반응형
네이버 영화 리뷰 데이터를 전처리하고, TF-IDF 토큰나이져를 활용하여 토큰화하고 머신러닝으로 모델링 만들고 감성분류 수행합니다.
참고 사이트
- 네이버 영화 리뷰 감성 분류하기 : https://wikidocs.net/106446
- BERT를 활용한 네이버 영화 리뷰 감정 분류 : https://velog.io/@fragrance_0/NLP-BERT-%EC%8B%A4%EC%8A%B5-%EC%98%88%EC%A0%9C-%EB%84%A4%EC%9D%B4%EB%B2%84-%EC%98%81%ED%99%94-%EB%A6%AC%EB%B7%B0-%EA%B0%90%EC%A0%95-%EB%B6%84%EB%A5%98
- 딥 러닝을 이용한 자연어 처리 입문 : https://wikidocs.net/book/2155
- 딥 러닝을 이용한 자연어 처리 입문(github) :https://github.com/ukairia777/tensorflow-nlp-tutorial
- 한국어 영화리뷰 텍스트 감정분류 예제 : https://github.com/eugene-dev-space/ai-study/
A. 머신러닝 이용하여 자연어 Classification하기
- 네이버 영화 리뷰 데이터를 가지고
- RandomForest/SGD 모델 학습하여 감정 Classification 모델링해 보겠습니다.
1. 라이브러리 임포트
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import urllib.request
plt.rc('font', family='NanumBarunGothic')
2. 파일 읽어오기
# 네이버 영화 리뷰 데이터 읽어오기
# urllib.request.urlretrieve("https://raw.githubusercontent.com/e9t/nsmc/master/ratings_train.txt", filename="ratings_train.txt")
# urllib.request.urlretrieve("https://raw.githubusercontent.com/e9t/nsmc/master/ratings_test.txt", filename="ratings_test.txt")
!git clone https://github.com/e9t/nsmc.git
Cloning into 'nsmc'...
remote: Enumerating objects: 14763, done.
remote: Counting objects: 100% (14762/14762), done.
remote: Compressing objects: 100% (13012/13012), done.
remote: Total 14763 (delta 1748), reused 14762 (delta 1748), pack-reused 1 (from 1)
Receiving objects: 100% (14763/14763), 56.19 MiB | 21.75 MiB/s, done.
Resolving deltas: 100% (1748/1748), done.
Updating files: 100% (14737/14737), done.
# 데이터 확인하기
final_data = pd.read_csv("./nsmc/ratings.txt", delimiter='\t', quoting=3)
final_data.head(3)
iddocumentlabel012
8112052 | 어릴때보고 지금다시봐도 재밌어요ㅋㅋ | 1 |
8132799 | 디자인을 배우는 학생으로, 외국디자이너와 그들이 일군 전통을 통해 발전해가는 문화산... | 1 |
4655635 | 폴리스스토리 시리즈는 1부터 뉴까지 버릴께 하나도 없음.. 최고. | 1 |
# 총 200000 건
final_data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 200000 entries, 0 to 199999
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 id 200000 non-null int64
1 document 199992 non-null object
2 label 200000 non-null int64
dtypes: int64(2), object(1)
memory usage: 4.6+ MB
3. 전처리 : Null, 중복 제거
# final_data 어떤 컬럼과 내용으로 되어 있는지 다시 확인
final_data.tail()
# '문장' 컬럼의 내용을 양끝의 빈공간 삭제
final_data['document'] = final_data['document'].str.strip()
# Null 있는지 확인 : 없음
final_data.isnull().sum()
0iddocumentlabel
0 |
8 |
0 |
dtype: int64
# null 데이터 삭제
final_data.dropna(inplace=True)
# 중복 데이터 있는지 확인 : 중복 존재 확인
final_data['document'].duplicated().sum()
5449
# 중복 데이터 제거
final_data.drop_duplicates(subset=['document'], inplace=True)
# info 정보 확인
final_data.info()
<class 'pandas.core.frame.DataFrame'>
Index: 194543 entries, 0 to 199999
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 id 194543 non-null int64
1 document 194543 non-null object
2 label 194543 non-null int64
dtypes: int64(2), object(1)
memory usage: 5.9+ MB
4. 영문, 숫자, 특수문자 제거
# '문장' 컬럼의 내용중에 영문, 특수문자 있는지 확인 : 영문과 특수문자 존재 확인
final_data[ final_data['document'].str.contains('[^가-힣 ]') ].head(3)
iddocumentlabel012
8112052 | 어릴때보고 지금다시봐도 재밌어요ㅋㅋ | 1 |
8132799 | 디자인을 배우는 학생으로, 외국디자이너와 그들이 일군 전통을 통해 발전해가는 문화산... | 1 |
4655635 | 폴리스스토리 시리즈는 1부터 뉴까지 버릴께 하나도 없음.. 최고. | 1 |
# '문장' 컬럼의 내용에서 숫자, 영문자, 특수문자등의 글자는 삭제처리
# final_data['문장'].replace('[^가-힣 ]','', regex=True) : 이렇게도 가능
final_data['document'] = final_data['document'].str.replace('[^가-힣 ]','', regex=True)
# '문장' 컬럼의 내용에서 영문, 특수문자 없음 확인
final_data['document'][final_data['document'].str.contains('[^가-힣 ]')].sum()
0
# 숫자, 영문자, 특수문자 등 제거후 데이터 확인하기.
final_data.head(3)
iddocumentlabel012
8112052 | 어릴때보고 지금다시봐도 재밌어요 | 1 |
8132799 | 디자인을 배우는 학생으로 외국디자이너와 그들이 일군 전통을 통해 발전해가는 문화산업... | 1 |
4655635 | 폴리스스토리 시리즈는 부터 뉴까지 버릴께 하나도 없음 최고 | 1 |
5. Label 분포 확인
# label '감정' 분포 확인 : 총 6개이며, 고루게 분포 확인. 단 기쁨이 약간 부족해 보임
final_data['label'].value_counts()
countlabel01
97277 |
97266 |
dtype: int64
6. X, Y 분리
# X, Y 분리
features = final_data['document']
labels = final_data['label']
features.shape, labels.shape
((194543,), (194543,))
# features 내용 3개 출력
features.head(3), labels.head(3)
(0 어릴때보고 지금다시봐도 재밌어요
1 디자인을 배우는 학생으로 외국디자이너와 그들이 일군 전통을 통해 발전해가는 문화산업...
2 폴리스스토리 시리즈는 부터 뉴까지 버릴께 하나도 없음 최고
Name: document, dtype: object,
0 1
1 1
2 1
Name: label, dtype: int64)
print('이벤트 문자열 최대 길이 :{}'.format(max(len(l) for l in features)))
print('이벤트 문자열 평균 길이 :{}'.format(sum(map(len, features))/len(features)))
이벤트 문자열 최대 길이 :140
이벤트 문자열 평균 길이 :32.56406038767779
# 히스토그램을 보면 30~40 부근에 많이 몰려 있음 알수 있다.
plt.hist([len(s) for s in features], bins=50)
plt.xlabel('length of samples')
plt.ylabel('number of samples')
plt.show()
7. train set와 test set 분리
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(features, labels , test_size=0.2, random_state=41)
x_train.shape, x_test.shape, y_train.shape, y_test.shape
((155634,), (38909,), (155634,), (38909,))
7. TF-IDF 변환하기
# 말뭉치를 TF-IDF로 변환하기
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf = TfidfVectorizer()
x_train_v = tfidf.fit_transform( x_train )
x_test_v = tfidf.transform( x_test )
y_train_v = y_train.copy()
y_test_v = y_test.copy()
# 각 라인의 각 단어에 대한 TF-IDF 값 표현
print(x_train_v[:3])
# 학습데이터셋의 TF-IDF 매트릭스 확인하기 : 41259 라인, 47366 단어
x_train_v.shape
(155634, 306861)
print(x_test_v[:1])
8. 머신러닝 모델링
# 전체 데이터로 학습하는 1분 내외 소요 : 성능 76% 나옴, 성능 잘 나옴.
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import SGDClassifier
import time
start = time.time()
# rfc = RandomForestClassifier()
# rfc.fit(x_train_v, y_train_v)
# print(f'RandomForestClassifier 성능 : { rfc.score(x_test_v, y_test_v) }')
sgdc = SGDClassifier()
sgdc.fit(x_train_v, y_train_v)
print(f'SGDClassifier 성능 : { sgdc.score(x_test_v, y_test_v) }')
end = time.time()
print(f'총학습시간: { end - start }')
SGDClassifier 성능 : 0.76529851705261
총학습시간: 0.2772693634033203
10. 예측해 보기
# 출력 결과 해석 : (0, 44327) 0.241660101642553
# 0 : 첫라인, 44327 : 단어에 맵핑된 번호, 0.241660101642553 : tf-idf 계산 값
print(f'검증데이터셋의 첫번째 TF-IDF : {x_test_v[:1]}')
검증데이터셋의 첫번째 TF-IDF : (0, 37669) 0.32179648415569073
(0, 64486) 0.46224340396439156
(0, 79316) 0.3773767865467077
(0, 113329) 0.4469586451306701
(0, 122155) 0.3577255327170683
(0, 155269) 0.2472916313660645
(0, 188060) 0.18777104866665684
(0, 296883) 0.3409019131309016
print(f'검증데이터셋의 첫번째 TF-IDF 역변환 : {tfidf.inverse_transform(x_test_v[:1])}')
검증데이터셋의 첫번째 TF-IDF 역변환 : [array(['나에겐', '돌이키고', '마지막에는', '보기전으로', '불쌍', '싶다', '영화를', '허나'],
dtype='<U139')]
# RandomForest 모델로 예측하기
predict = sgdc.predict(x_test_v[:1])
print(predict)
[1]
반응형
'정보' 카테고리의 다른 글
2023 일본벚꽃 개화시기 만개시기 벚꽃 명소 일본여행 (0) | 2023.03.04 |
---|---|
3월3일(3/3) 삼겹살데이 온오프라인 할인정보 삼삼데이 마트 최저가 (0) | 2023.03.01 |
2023년 벚꽃 개화시기 및 전국 벚꽃축제 일정 (0) | 2023.02.12 |