우선 아래와 같이 필요한 라이브러리와 모듈등을 한번에 설치해준다.
import pandas as pd
import numpy as np
import pickle
from gensim.models import Word2Vec
from gensim import models
import konlpy
from konlpy.tag import Mecab
import re
import nltk
from nltk.corpus import stopwords
nltk.download('stopwords')
stop_words = stopwords.words('english')
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, precision_score, recall_score, confusion_matrix,f1_score,classification_report
from sklearn.ensemble import RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import LinearSVC
다음으로는 데이터가 fake, true로 나누어져있기 때문에 데이터를 합쳐야한다. fake와 true data set을 구분해줘야 하기 때문에 bool이라는 column을 만든뒤에 fake에는 0, true에는 1이라는 라벨을 붙여준다.
#fake_news_data && real_news_data load
fdata=pd.read_csv("../input/fake-and-real-news-dataset/Fake.csv")
tdata=pd.read_csv("../input/fake-and-real-news-dataset/True.csv")
# fill bool on data(fake==0 / true==1)
fdata['bool']=0
tdata['bool']=1
# data=fdata+tdata
data = pd.concat([fdata,tdata],ignore_index=True)
data['clean_text']=np.nan
다음으로 데이터에 결측치등을 확인해본다. 아래와 같이 데이터가 결측치 없이 잘 구성되어있음을 확인한다.
data.info()
다음으로 데이터의 구성을 살펴보면 아래와 같이 title과 text가 존재하고, clean_text column은 아직 비어있다.
data.head()
나는 분석을 우선 데이터(뉴스)의 본문 부분인 text column만 이용하였다. 여기서 자연어처리(nlp)를 하게되는데, mecab이라는 분석기를 통해서 형태소 분류를 하였다. 참고로 mecab은 window에서 사용하려면 복잡하기 때문에 colab같은 웹형도구를 이용하기를 권장한다. 텍스트를 전처리 한뒤에 아까 만들어둔 clean_text column에 채워준다.
tokenizer = Mecab()
def text_preprocessing(text,tokenizer):
txt = re.sub('[^a-zA-Z]', ' ', text)
token = tokenizer.morphs(txt)
token = [t for t in token if t not in stop_words]
return token
for i in range(len(data['text'])):
tmp=text_preprocessing(data['text'][i].lower(),tokenizer)
data['clean_text'][i]=tmp
이제 본격적으로 분류를 하기위해서 train data과 test data을 나눠 줄 것이다. 나눈뒤에 train,test_sentence에 각 set의 전ㅊ처리된 본문을 넣어주고, 이를 Word2Vec을 이용해서 임베딩해준다.
text_train, text_test, label_train, label_test = train_test_split(data[['clean_text']], data['bool'],test_size = 0.4)
train_data = pd.concat([text_train, label_train], axis = 1)
test_data = pd.concat([text_test, label_test], axis = 1)
train_sentence = list([i for i in train_data['clean_text']])
test_sentence=list([i for i in test_data['clean_text']])
train_model = Word2Vec(train_sentence, vector_size=100, window=5, min_count=0, workers=1)
test_model = Word2Vec(test_sentence, vector_size=100, window=5, min_count=0, workers=1)
이렇게 임베딩한 결과값은 단어 하나하나에 대한 벡터값을 나오는데 우리는 뉴스와 뉴스를 분류할 것이기 때문에 각 문장안에 있는 단어들의 벡터의 평균값을 이용해서 문장벡터를 만들고 그 문장벡터의 유사도를 통해서 분류할 것이다.
embedding_dim = 100
zero_vector = np.zeros(embedding_dim)
def calc_sentence_vector(sentence,model):
if len(sentence) != 0:
return sum([model.wv[word] for word in sentence if word!=None])/len(sentence)
else:
return zero_vector
all_train_vect=[]
for i in train_data['clean_text']:
sentence_vect=calc_sentence_vector(i,train_model)
all_train_vect.append(sentence_vect)
train_data = train_data.assign(vect = all_train_vect)
#-------------------------------------------------------
all_test_vect=[]
for i in test_data['clean_text']:
sentence_vect=calc_sentence_vector(i,test_model)
all_test_vect.append(sentence_vect)
test_data = test_data.assign(vect = all_test_vect)
이제 분류모델에 넣을 인자값인 x,y_train과 x,y_test를 생성해준다. 아래에 리스트 형태로 만들어줘야 모델에 돌아간다.
x_train=train_data['vect']
y_train=train_data['bool']
x_test=test_data['vect']
y_test=test_data['bool']
x_train=[i for i in x_train]
y_train=[i for i in y_train]
x_test=[i for i in x_test]
y_test=[i for i in y_test]
이제 차례대로 랜덤포레스트, knn, 가우시안나이브베이즈,linear svc에 돌려봤다.
# Create the RandomForestClassifier model
rfc = RandomForestClassifier(random_state=1)
# Fit the model
rfc.fit(x_train, y_train)
# Use the trained model to predict
y_pred = rfc.predict(x_test)
# model accuracy
print(f'Model train accuracy: {rfc.score(x_train, y_train)*100:.3f}%')
print(f'Model test accuracy: {rfc.score(x_test, y_test)*100:.3f}%')
print(f'Model test precision: {precision_score(y_pred,y_test):.3f}')
print(f'Model test recall: {recall_score(y_pred,y_test):.3f}')
print(f'Model test f1_score: {f1_score(y_pred,y_test):.3f}')
# Create the KNeighborsClassifier model
knn = KNeighborsClassifier(n_neighbors=5)
# Fit the model
knn.fit(x_train, y_train)
# Use the trained model to predict
y_pred = knn.predict(x_test)
# model accuracy
print(f'Model train accuracy: {knn.score(x_train, y_train)*100:.3f}%')
print(f'Model test accuracy: {knn.score(x_test, y_test)*100:.3f}%')
print(f'Model test precision: {precision_score(y_pred,y_test):.3f}')
print(f'Model test recall: {recall_score(y_pred,y_test):.3f}')
print(f'Model test f1_score: {f1_score(y_pred,y_test):.3f}')
# Create the GaussianNB model
nb = GaussianNB()
# Fit the model
nb.fit(x_train, y_train)
# Use the trained model to predict
y_pred=nb.predict(x_test)
# model accuracy
print(f'Model train accuracy: {nb.score(x_train, y_train)*100:.3f}%')
print(f'Model test accuracy: {nb.score(x_test, y_test)*100:.3f}%')
print(f'Model test precision: {precision_score(y_pred,y_test):.3f}')
print(f'Model test recall: {recall_score(y_pred,y_test):.3f}')
print(f'Model test f1_score: {f1_score(y_pred,y_test):.3f}')
# Create the LinearSVC model
clf = LinearSVC(max_iter=10000, C=1.0)
# Fit the model
clf.fit(x_train, y_train)
# Use the trained model to predict
y_pred = clf.predict(x_test)
# model accuracy
print(f'Model train accuracy: {clf.score(x_train, y_train)*100:.3f}%')
print(f'Model test accuracy: {clf.score(x_test, y_test)*100:.3f}%')
print(f'Model test precision: {precision_score(y_pred,y_test):.3f}')
print(f'Model test recall: {recall_score(y_pred,y_test):.3f}')
print(f'Model test f1_score: {f1_score(y_pred,y_test):.3f}')
저번글에서 올린 것처럼 colab에서 돌렸을 때는 모든 분류모델들이 정확도가 매우 높게 나왔는데, 왜 kaggle에서 돌리면 정확도가 저렇게 낮게 나오는지 아직도 모르겠다.... 그리고 저번시간에 걱정한 각 단어의 임베딩벡터값들을 평균화 한 벡터를 문장벡터로 사용하는것이 맞는지 걱정했는데, 다른 작성자도 그렇게 문장벡터를만들어서 한것으로 보아 다행히 맞는 방법인 것 같다.
나중에 왜 이렇게 정확도가 낮게나왔는지 분석해보고, 다른 글들을 보니 딥러닝중 LSTM을 이용한 분류가 가장 많았던 것 같아서 그 방법으로 해보려고 한다. 아래는 임베딩된 단어벡터들을 이용해서 문장벡터를 만드는것과 내가 올린 kaggle사이트 주소이다.
'프로젝트 > 가짜 뉴스 분류' 카테고리의 다른 글
[가짜뉴스구별]-Day 3(모델적용) (0) | 2022.05.03 |
---|---|
[가짜뉴스구별]-Day 2(임베딩구현) (0) | 2022.04.02 |
[가짜뉴스구별]-Day 1(임베딩 설명) (0) | 2022.04.02 |
[가짜뉴스구별]-Day 0 (0) | 2022.03.28 |