[2주차_데이터분석] 개발일지 (숙제-워드클라우드, 머신러닝)

Coastby·2022년 7월 6일
0
post-custom-banner

[숙제]

  • 리뷰 데이터를 이용해 긍정/부정 워드 클라우드 만들기
  • 리뷰로 긍정/부정 분류하는 모델 만들기

워드 클라우드 만들기

1) 필요한 패키지, 모듈, 데이터 가져오기

import pandas as pd
import numpy as np

#판다스를 사용하여 네이버 쇼핑 리뷰 데이터가 존재하는 URL을 입력하고 다운로드합니다.
df = pd.read_table('https://raw.githubusercontent.com/bab2min/corpus/master/sentiment/naver_shopping.txt', names=['ratings', 'reviews'])
df
import matplotlib as mpl
import matplotlib.pyplot as plt
 
%config InlineBackend.figure_format = 'retina'
 
!apt -qq -y install fonts-nanum
 
import matplotlib.font_manager as fm
fontpath = '/usr/share/fonts/truetype/nanum/NanumBarunGothic.ttf'
font = fm.FontProperties(fname=fontpath, size=9)
plt.rc('font', family='NanumBarunGothic') 
mpl.font_manager._rebuild()

2) 데이터 정리하기*

# null 값 확인
print(df.isnull().sum())
#Result
ratings    0
reviews    0
dtype: int64

# 중복 값 확인
print(df.nunique())
df.drop_duplicates(subset=['reviews'], inplace=True)
#Result
ratings         4
reviews    199908
dtype: int64

# 별점이 몇개나 있나 확인
df['ratings'].value_counts()
#Reulst
5    81170
2    63948
1    36007
4    18783
Name: ratings, dtype: int64

3) 토큰화 및 리스트 컴프리헨션

# 워드클라우드를 위해 형태소 분석기 다운로드
!pip install konlpy
from konlpy.tag import Okt
tokenizer = Okt()

# 엄청 오래걸림
df['tokenized'] = df['reviews'].apply(tokenizer.nouns)

# 불용어는 두고, 1글자는 뺌
df['tokenized'] = df['tokenized'].apply(lambda x: [item for item in x if len(item)>1])

4) 워드 클라우드 만들기

# 긍정, 부정을 3점을 기준으로 나눠주기
df_positive = df[df['ratings']>3]
df_negative = df[df['ratings']<3]

# 긍정, 부정에 해당되는 단어들을 하나의 리스트로 묶어주기
positive_words = np.hstack(df_positive['tokenized'].values)
negative_words = np.hstack(df_negative['tokenized'].values)
print(positive_words, negative_words)
#Result
['배공' '아주' '바지' ... '제품' '본적' '배송'] ['택배' '엉망' '선물' ... '다음' '장마' '런가']

# 워드 클라우드 다운로드
from wordcloud import WordCloud

# 긍정 부정 단어 리스트를 각각 temp_data에 넣고 워드 클라우드 생성
plt.figure(figsize = (15,15))
temp_data = ' '.join(negative_words)
wc = WordCloud(max_words = 2000 , width = 1600 , height = 800, font_path = fontpath).generate(temp_data)
plt.imshow(wc, interpolation = 'bilinear')


긍정/부정 분류 모델 만들기

1) 평점기준 긍정/부정 라벨링하기

# 긍정리뷰 (평점 3이상)에는 1, 부정리뷰(평점 3이하)에는 0 라벨링
df['label'] = np.select([df.ratings>3], [1], default=0)

2) 훈련/테스트 데이터 나누기

# 훈련 데이터 / 테스트 데이터 나누기
# x_train : reviews 70% / x_test : reviews 30% / y_train : label 70% / y_test : label 30%
from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(df['reviews'], df['label'], test_size = 0.3)

3) 벡터화

# 사이킷런 다운로드
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer

vector = CountVectorizer() # DTM 벡터화를 위한 객체 생성
x_train_dtm = vector.fit_transform(x_train) # x_train 벡터화
x_test_dtm = vector.transform(x_test) # x_test 벡터화

tfidf_transformer = TfidfTransformer() # tfidf 벡터화를 위한 객체 생성
tfidfv = tfidf_transformer.fit_transform(x_train_dtm) # x_train_dtm에 대해서 벡터화 진행
tfidfv_test = tfidf_transformer.transform(x_test_dtm) # x_test_dtm에 대해서 벡터화 진행

print(tfidfv)

4) 로지스틱 회귀 모델 학습

from sklearn.linear_model import LogisticRegression # 로지스틱 회귀 함수 임포트
from sklearn.metrics import accuracy_score # 정확도 계산

# 사이킷런의 로지스틱 회귀 모델 학습
lr = LogisticRegression (C=10000, penalty='l2')
lr.fit(tfidfv, y_train)

# 정확도 예측
predicted = lr.predict(tfidfv_test)
print ("정확도 :", accuracy_score(y_test, predicted))
#Result
정확도 : 0.8565020926083404

5) 모델 실행해보기*

x_test_dtm = vector.transform(['사용', '배송']) # x_test 벡터화
tfidfv_test = tfidf_transformer.transform(x_test_dtm) # x_test_dtm에 대해서 벡터화 진행

predicted = lr.predict(tfidfv_test)
print (predicted)

#Result
[0 0]

리뷰

👉 중복된 데이터 확인하기

데이터 정리할 때 같은 입력값으로 다른 타깃(결과)가 나오면 안 되어서 중복된 데이터는 다 제외하였다. 그런데 리뷰와 평점이 동일한 값을 가진 데이터만 뽑아보는 방법이 궁금하여 확인해보았다.
방법1)

df_duplicated[df.duplicated() == True]


방법2)

df.loc[df.duplicated(), :]

👉 테스트할 때 들어가는 타입확인

모델 실행 시 transform()에 문자열은 안 됨.

profile
훈이야 화이팅
post-custom-banner

0개의 댓글