wordvec 자연어처리후 학습 한 것을 외부 데이터를 읽어내 확률 추출해 내는것이 궁금합니다.
조회수 583회
현재 id/date/text/smishing 행을 가진 데이터에서 text/smishing만 추출해 word2vec로 자연어처리후 랜덤포레스트와 KNN으로 학습했습니다. 이 학습한 것을 test.csv라는 id/date/text 행만 가진 데이터를 읽어내 스미싱 여부 및 그 확률을 추출해내고자 합니다.
다음 코드는 훈련했던 코드 들입니다.
데이터를 불러와 범위 설정
import numpy as np
import pandas as pd
import konlpy
ham_spam = pd.read_csv(r'C:\Users\chlwn\Desktop\JUNO\data\smishing data\train.csv')
data = list(zip(ham_spam['text'],ham_spam['smishing']))
text = [data[i][0] for i in range(30000)]
label = [data[i][1] for i in range(30000)]
데이터 텍스트 분리 및 train과 test 데이터 분리
import re
text1 = [re.sub('\d+',' ',tmp) for tmp in text]
text2 = [re.sub('\W+',' ',tmp) for tmp in text1]
text_split = [tmp.split(' ') for tmp in text2]
text_split
from sklearn.model_selection import train_test_split
text_train, text_test, label_train, label_test = train_test_split(text_split, label, random_state = 0)
#####text(메일 내용)의 train과 test 를 나눠줌
##### 정답인 label(ham인지 spam인지)도 train, test 따로 나눠줌
###### random_state : 난수 고정 / test_size(default) : 0.25
print(len(text_train), len(text_test))
print(len(label_train), len(label_test))
불용어 처리
stop_words = ['XXX','나','너','아이','오직','때','시각']
def rm_stop(token):
final = []
for words in token:
word_list = []
for word in words:
if word.split("/")[0] not in stop_words:
word_list.append(word)
final.append(word_list)
return final
text_train = rm_stop(text_train)
text_test = rm_stop(text_test)
from gensim.models import Word2Vec
##### Skip-gram (sg=1)
w2v_skip_gram = Word2Vec(text_train, size=100, window=10, min_count=10, workers=4, sg=1)
##### CBOW (sg=0)
w2v_CBOW = Word2Vec(text_train, size=100, window=10, min_count=10, workers=4, sg=0)
### Text embedding 하기
from sklearn.feature_extraction.text import TfidfVectorizer
from collections import defaultdict
import numpy as np
문서 embedding
class TfidfEmbeddingVectorizer(object):
def __init__(self, word2vec):
self.word2vec = word2vec
def transform(self, X):
tfidf = TfidfVectorizer(analyzer = lambda x : x)
tfidf.fit(X)
max_idf = max(tfidf.idf_)
word2weight = defaultdict(lambda : max_idf, [(w, tfidf.idf_[i]) for w, i in tfidf.vocabulary_.items()])
array_list =[]
for words in X:
array_list.append(np.array(np.mean([self.word2vec[w]*word2weight[w] for w in words if w in self.word2vec] or [np.zeros(100)], axis = 0)))
return(array_list)
vec_tf_skip_gram = TfidfEmbeddingVectorizer(w2v_skip_gram)
vec_tf_CBOW = TfidfEmbeddingVectorizer(w2v_CBOW)
Word2vec을 이용 단어들간의 관계 설정으로 smishing여부 훈련 (skip-gram, CBOW 사용)
#### skip-gram
train_tf_s = vec_tf_skip_gram.transform(text_train)
test_tf_s = vec_tf_skip_gram.transform(text_test)
#### CBOW
train_tf_c = vec_tf_CBOW.transform(text_train)
test_tf_c = vec_tf_CBOW.transform(text_test)
svm을 만들고 각 word2vec의 예측값과 정확도 확인
Support Vector Machine
from sklearn.svm import SVC
clf = SVC(decision_function_shape='ovo') # SVM 만들기
svc_clf_s = clf.fit(train_tf_s, label_train) # skip-gram
svc_clf_c = clf.fit(train_tf_c, label_train) # CBOW
예측값 뽑아내기
svc_pred_s = svc_clf_s.predict(test_tf_s) # skip-gram
svc_pred_c = svc_clf_c.predict(test_tf_c) # CBOW
정확도 확인
from sklearn import metrics
print(metrics.classification_report(label_test, svc_pred_s)) # skip-gram
print(metrics.classification_report(label_test, svc_pred_c)) # CBOW
KNN으로 머신러닝 후 정확도
K-Nearest Neighbor
from sklearn import neighbors, datasets
clf1 = neighbors.KNeighborsClassifier()
knn_clf = clf1.fit(train_tf_s, label_train)
knn_pred = knn_clf.predict(test_tf_s)
print(metrics.classification_report(label_test, knn_pred))
Random Forest로 머신러닝 후 정확도
랜덤 포레스트
from sklearn.ensemble import RandomForestClassifier
clf2 = RandomForestClassifier()
RF_clf = clf2.fit(train_tf_c, label_train)
RF_pred = RF_clf.predict(test_tf_c)
RF_pred
print(metrics.classification_report(label_test, RF_pred))
RF_clf.score(test_tf_s, label_test)
test 데이터를 public_test로 하여 text만 불러 냈습니다
public_test로 결과값 도출 및 csv저장 (KNN사용)
public_test = pd.read_csv(r'C:\Users\chlwn\Desktop\JUNO\data\smishing data\public_test.csv')
public_data = list(zip(public_test['text']))
public_text = [data[i][0] for i in range(len(data))]
import re
public_text1 = [re.sub('\d+',' ',tmp) for tmp in public_text]
public_text2 = [re.sub('\W+',' ',tmp) for tmp in public_text1]
public_text_split = [tmp.split(' ') for tmp in public_text2]
from sklearn.model_selection import train_test_split
public_text = rm_stop(public_text)
print(public_text_split)
# skip-gram
public_test_tf_s = vec_tf_skip_gram.transform(public_text_split)
# CBOW
public_test_tf_c = vec_tf_CBOW.transform(public_text_split)
print(RF_clf.predict_proba(public_test_tf_c))
S = list(zip(test_data[:], RF_clf.predict(public_test_tf_s)))
print(S)
df3 = pd.DataFrame(S)
df3.to_csv(r'C:\Users\chlwn\Desktop\JUNO\data\smishing data\public_test_RF_4.csv',encoding='UTF-8')
*이렇게 추출해서 csv 파일로 만들시 스미싱 여부가 모두 0으로 나오는데 이건 딱 봐도 잘못된 값인 것 같아서 질문을 드립니다. **
- 이 test.csv라는 id/date/text 행만 가진 데이터를 각 id별 스미싱 확률을 가진 데이터로 내보내려면 어떻게 해야하는지 궁금 합니다.
1 답변
-
colab notebook 을 참고하세요.
pc에서 수행하려면 word2vec 모델링 결과 파일과 Random forest 로 학습된 분류기 파일을 다운로드하고 colab notebook 코드를 수행시키면 되겠죠.
학습시킨 데이터
https://drive.google.com/open?id=1nCJG5jBbgn2TvrfvHcnKu8XcNGdm5neu
word2vec 모델링 결과 파일
https://drive.google.com/open?id=1FWNLMbXqegYPuG14RQOKBBsuAIF8Orb6
Random forest 로 학습된 분류기 파일
https://drive.google.com/open?id=1-1UwGjgB3ZbALgcv4tK-UpqG2mh8lgg9
colab notebook
https://colab.research.google.com/drive/1_eV4_y2WjrrEnlt-Aiv_vPLMMF37oZk3#scrollTo=dTc03PKYDQDo
- 귀찮으실수도 있으셨을텐데 직접 데이터 부터 모델링까지 너무 감사드립니다. colab notebook에 접근하기 위해서는 권한이 필요하다고 나오는데 액세스 요청 수락해주실수 있나요? 최준호 2020.1.7 13:12
- 엑세스 권한이 있어도 파일이 제 구글 드라이브에 있어서 파일 접근 못해요. 그래서 파일들을 다 올려드린거에요. colab 에서 해보고 싶으시다면 개인 구글 드라이브에 파일들 올리고 colab 계정 등록해서 해볼 수도 있겠지만...그럴 필요없이파일 2개만 다운받고 pc에서 해봐도 됩니다. 이미 학습 및 모델링은 다 된 것이라 학습처리할 필요도 없구요 코드 복사해서 붙여넣기하여 테스트 하면 됩니다. 정영훈 2020.1.7 13:55
댓글 입력