본문 바로가기
투닥투닥

DACON 금융문자 분석 경진대회 도전

by Lauren X Ming 2019. 12. 22.

DACON

DACON 메인화면

금융문자 분석 경진대회를 한다고 한다. 총 상금 2000만원😎

 

[대회] 14회 금융문자 분석 경진대회 - A. 대회 설명 & 데이터 다운로드

1. 배경 올해 1월부터 7월까지 스미싱 범죄 건수는 17만6220건으로 지난해 같은 기간(14만5093건)에 비해 21.5% 증가했습니다. 특히 최근 교묘하고 지능적인 스미싱 문자 패턴으로 인해 고객들의 피해가 증가하고 있습니다. 이를 방지하기 위해 kb 금융그룹과 KISA는 데이코너들에게 도움을 요청합니다. 총 글자수 50,000,000개의 데이터를 활용해 스미싱 탐지 모델을 개발하고 명예와 상금을 동시에 누리세요! ...

dacon.io

Ranking에서 위를 올려보니...

높은 사람들....

아래를 내려다보니...

꼴찌가 173?!

제출만 해도 200위권이 가능하다!! 바로 ㄲㄲ!!

Train/Test 데이터와 제출양식

갯수가 아니라 개수다 쯔아식아

초급자용 코드를 참고하여 제출을 해야겠다.

 

[대회] 14회 금융문자 분석 경진대회 - [Dacon Baseline] 초급자용 코드

/*! * * Twitter Bootstrap * */ /*! * Bootstrap v3.3.7 (http://getbootstrap.com) * Copyright 2011-2016 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */ /*! normalize.css v3.0.3 | MIT License | github.com/necolas/

dacon.io

 

초급자용 코드 구성

심플하군

colab으로 초보자용 코드 분석 ㄲㄲ!

 

코드 흐름 분석

1. 텍스트 다운사이징

random.seed(1217) #반복 수행시에도 동일한 결과 나올 수 있도록 시드 번호 지정
train_nsm_list=list(train[train['smishing']!=1].index)
train_nsmishing=random.sample(train_nsm_list, 11750 )

random.seed(1217)
train_sm_list=list(train[train['smishing']==1].index)
train_smishing=random.sample(train_sm_list, 800 ) #0.066과 제일 비슷하게 나올 수 있도록  train data under sampling
train_xx=train.iloc[train_smishing+train_nsmishing,:].reset_index(drop=True) #under sampling으로 나온 index들로 train data 선별

train_yy=DataFrame(train['smishing'],columns=['smishing']) 
train_yyy=train_yy.iloc[train_smishing+train_nsmishing,:].reset_index(drop=True)
test['smishing']=2 #train data와 동일한 형태 생성을 위해 임의의 숫자를 추가 #이후 스미싱 여부 확률 값으로 덮어 씌워짐
test_xx=DataFrame(test['text'])
test_yyy=DataFrame(test['smishing'])
train_xx.shape,train_yyy.shape,test_xx.shape,test_yyy.shape

데이터를 일정 비율로 줄인 후 train_X, train_Y, test_X, test_Y를 만든다.
당연히 X는 조건이고 Y는 레이블, 즉, 스미싱일 확률
test_Y는 정답을 모르니 2로 일단 값을 매겼다.

 

2. Mecab을 통한 텍스트 토큰화

import konlpy
from konlpy.tag import Mecab

tokenizer = Mecab() # setting tokenizer using Mecab()
train_doc = [ ( tokenizer.pos(x), y ) for x, y in tqdm( zip( train_xx['text'], train_yyy['smishing'] ) )  ] # Mecab를 활용하여 text를 토큰화 시킴
test_doc = [ ( tokenizer.pos(x), y ) for x, y in tqdm( zip( test_xx['text'], test_yyy['smishing'] ) )  ]

zip: 동일한 개수의 자료형을 묶어주는 함수
tqdm: 진행 상황 표시
tokenizer.pos(x) : 한글 텍스트의 품사를 파악해 토큰화

2-1. zip 예제

list(zip([1, 2, 3], [4, 5, 6]))
[(1, 4), (2, 5), (3, 6)]

2-2. KoNLPy의 품사 토큰화

2-2. 품사 토큰화 예제: 아버지가방에들어가신다.

2-2. train_doc 토큰화 결과

 

3. stopwords를 통한 필요없는 불용어 제거

stopwords = ['XXX', '.', '을', '를', '이', '가', '-', '(', ')', ':', '!', '?', ')-', '.-', 'ㅡ', 'XXXXXX', '..', '.(', '은', '는'] #필요없는 단어 리스트

def get_couple(_words): #필요없는 단어들 없애는 함수
    global stopwords
    _words = [x for x in _words if x[0] not in stopwords]
    l = len(_words)
    for i in range(l-1):
        yield _words[i][0], _words[i+1][0]

3-1. train_doc, test_doc의 불용어 제거 후 적절한 train, test 데이터 형태로 변환

X_train, Y_train = [], []
for lwords in train_doc:
    Y_train.append(lwords[1])

    temp = []
    for x, y in get_couple(lwords[0]):
        temp.append("{}.{}".format(x, y))

    X_train.append(" ".join(temp))

X_test = []
for lwords in test_doc:

    temp = []
    for x, y in get_couple(lwords[0]):
        temp.append("{}.{}".format(x, y))

    X_test.append(" ".join(temp))

 

4. CountVectorizer를 통한 word2vector

v=CountVectorizer()

v.fit(X_train)

vec_x_train= v.transform(X_train).toarray()
vec_x_test= v.transform(X_test).toarray()

 

word2vec은 단어간의 거리를 수치화해 비슷한 거리는 같은 의미라 파악하는데 쓰임

word2vec 예시로 각 단어들의 거리로 의미들의 연관성을 파악

 

5. MultinominalNB() 학습모델 생성 및 학습 후 테스트 데이터에 적용

m1= MultinomialNB()
m1.fit(vec_x_train,Y_train)

y_train_pred1=m1.predict_proba(vec_x_train)
y_train_pred1_one= [ i[1]  for i in y_train_pred1]

y_test_pred1=m1.predict_proba(vec_x_test)
y_test_pred1_one= [ i[1]  for i in y_test_pred1]

naive bayes중 MultinomialNB를 이용하였다.
Navie Bayes는 전통적인 텍스트 분류 방법이고 MultinomialNB는 다항분포 방법인데 아주 전통적인 방법을 쓰셨다.

6. 제출 데이터 생성 및 제출

!ls "/content/drive/My Drive/14th data" 
cd /content/drive/My Drive/14th data
submission['smishing'] = y_test_pred1_one

submission.to_csv("14th_baseline_version_5.csv",index=False) #현재 결과물인 output2를 구글 드라이브에 submission_test라는 이름으로 저장

뾰로롱

 

6. 제출 데이터 생김새

표시형식을 숫자로해서 0, 1로 나타나지 실제 값은 소수다.

 

7. 제출 ㄲㄲ

 

7. 등수 확인

 

초급자 코드를 제출했을 뿐인데 꼴지가 아니다 낄낄낄

다운 샘플링, 토큰화, 학습모델을 조정하면 더 높일 수 있을 것 같다.