일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- pytorch
- Classification Task
- 대학원
- naver movie review
- 자연어처리
- word embedding
- CUDA
- 수기
- 전처리
- 우울증
- 석사
- sentiment analysis
- Word2Vec
- NLP
- 인공지능
- 품사태깅
- Today
- Total
슬기로운 연구생활
3-1. BoW + NB 본문
[1] Data Set
( Train Data )
- 긍정 리뷰 : 93,042 / 부정 리뷰 : 275,270
( Test Data )
- 긍정 리뷰 : 10,338 / 부정 리뷰 : 30,586
평점이 1점 ~ 3점인 영화리뷰를 부정 리뷰로 분류했고 10점인 리뷰를 긍정 리뷰로 라벨링했다.
[2] Text To Vector
텍스트 데이터를 NB에 그대로 넣을 수 없으니 Vector로 변환하는 과정을 거쳤다.
BoW을 사용해 Text를 Vector로 변형하였다.
Vector의 차원수 : 602,884
( 형태소 분석기를 사용해 전처리를 하면 차원수가 감소할까? 조사와 같은 불필요한 품사들을 제외하고 명사, 형용사, 동사 등 중요한 품사만 사용하면 차원수를 줄일 수 있을 것 같다. 실험해봐야겠다. )
Sklearn의 CountVector를 사용하면 ( 그림1 )과 같이 표현이 된다.
[3] Naive Bayes
Sklearn에 MultinomialNB를 적용하여 분류기를 만들었다.
Sklearn에서는 다양한 NB 모델을 지원한다.
MultinomialNB : feature가 이산형일 때 유용.
Bernoulli : feature가 이진형일 때 유용.
Gaussian : feature가 정규분포를 따를 때 유용.
[3-1] 코드
from sklearn import preprocessing, naive_bayes, metrics
from sklearn.feature_extraction.text import CountVectorizer
import pandas
import csv
from sklearn.metrics import classification_report
def Load_Data(train_file_dir, validation_file_dir):
train_file = open(train_file_dir, 'r', encoding='utf-8') # 학습 데이터 파일 읽기
csv_reader_train = csv.reader(train_file)
valid_file = open(validation_file_dir, 'r', encoding='utf-8') # 검증 데이터 파일 읽기
csv_reader_valid = csv.reader(valid_file)
all_texts = []
train_texts, train_labels = [], []
valid_texts, valid_labels = [], []
for row in csv_reader_train:
all_texts.append(row[0])
train_texts.append(row[0])
train_labels.append(row[1])
train_file.close()
for row in csv_reader_valid:
all_texts.append(row[0])
valid_texts.append(row[0])
valid_labels.append(row[1])
valid_file.close()
# 전체, 학습, 검증 데이터 프레임 미리 만들어둔다.
dfAll, dfTrain, dfValid = pandas.DataFrame(), pandas.DataFrame(), pandas.DataFrame()
dfAll['text'] = all_texts
dfTrain['text'], dfTrain['label'] = train_texts, train_labels
dfValid['text'], dfValid['label'] = valid_texts, valid_labels
# 라벨링을 해준다.
encoder = preprocessing.LabelEncoder()
train_y, valid_y = encoder.fit_transform(dfTrain['label']), encoder.fit_transform(dfValid['label'])
DataSet = {'train_text': dfTrain['text'], 'valid_text': dfValid['text'], 'train_label': train_y, 'valid_label': valid_y, 'all_text_data': dfAll['text']}
return DataSet
def Convert_Text_To_Vector(DataSet):
AllTextData = DataSet['all_text_data']
train_text = DataSet['train_text']
valid_text = DataSet['valid_text']
word_index, embedding_matrix = None, None # Word Embedding 일 사용 할 경우에만 사용한다.
# 문장을 단어로 잘라준다.
count_vect = CountVectorizer(analyzer='word', token_pattern=r'\w{1,}')
count_vect.fit(AllTextData)
train_count = count_vect.transform(train_text)
print(train_count.shape)
valid_count = count_vect.transform(valid_text)
print(valid_count.shape)
TextToVec_DataSet = {'train_count': train_count, 'valid_count': valid_count, 'word_index': word_index, 'embedding_matrix': embedding_matrix }
return TextToVec_DataSet
def Train_Model(classifier, data_set, text_to_vector_data_set, target_names=['0', '1']):
train_count, train_label = text_to_vector_data_set['train_count'], data_set['train_label']
valid_count, valid_label = text_to_vector_data_set['valid_count'], data_set['valid_label']
# train_count와 train_label로 학습해서 모델 생성.
classifier.fit(train_count, train_label)
# 학습된 모델에 valid_count를 넣어 정답 예측하기.
predictions = classifier.predict(valid_count)
print("-" * 33)
print(classification_report(valid_label, predictions, target_names=target_names))
return metrics.accuracy_score(predictions, valid_label)
if __name__ == "__main__":
DataSet = Load_Data("../data/train.csv", "../data/validation.csv") # 1. 학습데이터와 검증데이터를 불러온다.
TextToVec_DataSet = Convert_Text_To_Vector(DataSet) # 2. 불러온 Text 데이터를 Vector로 변환해준다.
classifier = naive_bayes.MultinomialNB() # 3. 사용할 알고리즘 정의
# classifier = naive_bayes.BaseNB()
# classifier = naive_bayes.GaussianNB()
# classifier = naive_bayes.BernoulliNB()
accuracy = Train_Model(classifier, DataSet, TextToVec_DataSet) # 4. model을 만들고 정확도를 측정한다.
print("모델 정확도: ", accuracy)
print("-" * 33)
https://github.com/vhrehfdl/Blog/blob/master/movie_review_classification/model/BoW%2BNB.py
[3-2] 결과
대체 왜 이렇게 결과가 높게 나오는지 모르겠다.
어떠한 전처리도 하지 않았고 그냥 BoW로 Vector 만들고 NB 사용했을 뿐인데 지나치게 높게 나왔다.
그 이유를 추측해본다면, 애초에 DataSet을 구성할 때 1~3점은 부정리뷰, 10점은 긍정리뷰로 한게 문제일수도 있다고 생각했다.
왜냐하면 너무 극단적이기 때문이다.
텍스트에도 그러한 특성들이 반영되어 있을 수 있기 때문에 결과가 너무 좋게 나온 것 같기도 하다.
만약, 애매모호한 문장을 Test Set으로 구성해 해당 Model에 테스트 해보면 정확률이 낮게 나올 수도 있을 것 같다. ( 추가적으로 실험해봐야겠다. )
[4] 추후 계획
- 일단은 Konlpy를 사용해 전처리 했을 때 성능이 올라가는지 확인해봐야 한다. ( 불필요 품사 제외, Stemming )
- Test Set을 바꿔서 accuracy를 측정해봐야 할 것 같다.
- NB 다양한 모델 사용 ( 가우시안, 베르누이 )
'프로젝트 : 영화리뷰 분류' 카테고리의 다른 글
3-4. BoW + Random Forest Classifier (0) | 2019.07.25 |
---|---|
3-3. BoW + SVM (0) | 2019.07.25 |
3-2. BoW + NB + Komoran (0) | 2019.07.25 |
2. 데이터 가공 (0) | 2019.07.24 |
1. 소개 (0) | 2019.07.24 |