3 분 소요

YELP 서비스의 리뷰 분석 (NLP)

PROBLEM STATEMENT

  • stars 컬럼은, 유저가 1점부터 5점까지 준 별점이 들어있다.
  • text 컬럼은, 별점을 준 유저의 리뷰가 들어있다.
  • cool, useful, funny 컬럼은, 다른사람들이 이 리뷰 글에 투표한 숫자다. 따라서 쿨이 3개이면, 이 리뷰에 대해서 3명이 쿨에 공감했다는 뜻이다.

STEP #0: LIBRARIES IMPORT

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
from google.colab import drive
drive.mount('/content/drive')
Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount("/content/drive", force_remount=True).
import os
os.chdir('/content/drive/MyDrive/python/day15')

STEP #1: IMPORT DATASET

yelp.csv 파일을 읽어서, yelp_df 변수에 저장하고, 기본적인 통계 분석을 하시오.

df = pd.read_csv('yelp.csv')
df.head(5)
business_id date review_id stars text type user_id cool useful funny
0 9yKzy9PApeiPPOUJEtnvkg 2011-01-26 fWKvX83p0-ka4JS3dc6E5A 5 My wife took me here on my birthday for breakf... review rLtl8ZkDX5vH5nAx9C3q5Q 2 5 0
1 ZRJwVLyzEJq1VAihDhYiow 2011-07-27 IjZ33sJrzXqU-0X6U8NwyA 5 I have no idea why some people give bad review... review 0a2KyEL0d3Yb1V6aivbIuQ 0 0 0
2 6oRAC4uyJCsJl1X0WZpVSA 2012-06-14 IESLBzqUCLdSzSqm0eCSxQ 4 love the gyro plate. Rice is so good and I als... review 0hT2KtfLiobPvh6cDC8JQg 0 1 0
3 _1QQZuf4zZOyFCvXc0o6Vg 2010-05-27 G-WvGaISbqqaMHlNnByodA 5 Rosie, Dakota, and I LOVE Chaparral Dog Park!!... review uZetl9T0NcROGOyFfughhg 1 2 0
4 6ozycU1RpktNG2-1BroVtw 2012-01-05 1uJFq2r5QfJG_6ExMRCaGw 5 General Manager Scott Petello is a good egg!!!... review vYmM4KTsC8ZfQBg-j5MWkw 0 0 0

STEP #2: VISUALIZE DATASET

리뷰 데이터의 길이를 구하여, 새로운 컬럼 length 컬럼을 만드시오

df['length']= df['text'].apply(len)

리뷰의 length를 히스토그램으로 나타내시오.

df['length'].hist()
plt.show()

png

리뷰가 가장 긴 글을 찾아서, 리뷰 내용을 보여주세요.

(df.loc[df['length'] == df['length'].max(),])['text'].values

리뷰가 가장 짧은 리뷰는 총 몇개이며, 리뷰 내용은 무엇입니까?

(df.loc[df['length'] == df['length'].min(),])['text'].values
array(['X'], dtype=object)

별점은 1점부터 5점까지 입니다. 각 별점별로 리뷰가 몇개씩 있는지를 시각화 하시오.

sns.countplot(data = df,x='stars')
plt.show()

png

별점별로 리뷰가 몇개씩 있는지 시각화 하되, 내림차순으로 정렬하여 시각화 하시오.

my_order = df['stars'].value_counts().index
sns.countplot(data = df,x='stars',order=my_order)
plt.show()

png

별점이 1점인 리뷰의 데이터프레임과, 별점아 5점인 데이터프레임을 각각 따로 아래의 변수에 저장하시오. 변수명은 yelp_df_1 , yelp_df_5 로 저장하시오.

yelp_df_1 = df.loc[df['stars'] == 1,]
yelp_df_5 = df.loc[df['stars'] == 5,]

yelp_df_1 , yelp_df_5 두개의 데이터프레임을 하나로 합치시오. 긍정과 부정의 리뷰 학습을 위해서 하나로 합치는 것이다.

yelp_df_1_5 = pd.concat([yelp_df_1,yelp_df_5])
yelp_df_1_5
business_id date review_id stars text type user_id cool useful funny length
23 IJ0o6b8bJFAbG6MjGfBebQ 2010-09-05 Dx9sfFU6Zn0GYOckijom-g 1 U can go there n check the car out. If u wanna... review zRlQEDYd_HKp0VS3hnAffA 0 1 1 594
31 vvA3fbps4F9nGlAEYKk_sA 2012-05-04 S9OVpXat8k5YwWCn6FAgXg 1 Disgusting! Had a Groupon so my daughter and ... review 8AMn6644NmBf96xGO3w6OA 0 1 0 361
35 o1GIYYZJjM6nM03fQs_uEQ 2011-11-30 ApKbwpYJdnhhgP4NbjQw2Q 1 I've eaten here many times, but none as bad as... review iwUN95LIaEr75TZE_JC6bg 0 4 3 1198
61 l4vBbCL9QbGiwLuLKwD_bA 2011-11-22 DJVxOfj2Rw9zklC9tU3i1w 1 I have always been a fan of Burlington's deals... review EPROVap0M19Y6_4uf3eCmQ 0 0 0 569
64 CEswyP-9SsXRNLR9fFGKKw 2012-05-19 GXj4PNAi095-q9ynPYH3kg 1 Another night meeting friends here. I have to... review MjLAe48XNfYlTeFYca5gMw 0 1 2 498
... ... ... ... ... ... ... ... ... ... ... ...
9990 R8VwdLyvsp9iybNqRvm94g 2011-10-03 pcEeHdAJPoFNF23es0kKWg 5 Yes I do rock the hipster joints. I dig this ... review b92Y3tyWTQQZ5FLifex62Q 1 1 1 263
9991 WJ5mq4EiWYAA4Vif0xDfdg 2011-12-05 EuHX-39FR7tyyG1ElvN1Jw 5 Only 4 stars? \n\n(A few notes: The folks that... review hTau-iNZFwoNsPCaiIUTEA 1 1 0 908
9992 f96lWMIAUhYIYy9gOktivQ 2009-03-10 YF17z7HWlMj6aezZc-pVEw 5 I'm not normally one to jump at reviewing a ch... review W_QXYA7A0IhMrvbckz7eVg 2 3 2 1326
9994 L3BSpFvxcNf3T_teitgt6A 2012-03-19 0nxb1gIGFgk3WbC5zwhKZg 5 Let's see...what is there NOT to like about Su... review OzOZv-Knlw3oz9K5Kh5S6A 1 2 1 1968
9999 pF7uRzygyZsltbmVpjIyvw 2010-10-16 vWSmOhg2ID1MNZHaWapGbA 5 4-5 locations.. all 4.5 star average.. I think... review KSBFytcdjPKZgXKQnYQdkA 0 0 0 461

4086 rows × 11 columns

별점 1과 별점 5의 리뷰는 몇개씩인지, 시각화 하시오.

sns.countplot(data=yelp_df_1_5,x='stars')
plt.show()

png

별점 1점과 별점 5점의 리뷰의 비율이 나오도록, 파이차트로 시각화 하시오.

yelp_df_1_5['stars'].value_counts()
5    3337
1     749
Name: stars, dtype: int64
plt.pie(yelp_df_1_5['stars'].value_counts(),labels=yelp_df_1_5['stars'].value_counts().index,autopct='%.1f')
plt.show()

png

STEP #3: CREATE TESTING AND TRAINING DATASET/DATA CLEANING

정리 : 위의 과정을 하나의 함수로 만든다.

import string
import nltk
nltk.download('stopwords')
from nltk.corpus import stopwords
my_stopwords = stopwords.words('english')

def message_cleaning(sentence) :
  Test_punc_removed = [ char for char in sentence if char not in string.punctuation]
  Test_punc_removed_join = ''.join(Test_punc_removed)
  Test_punc_removed_join_clean = [word for word in Test_punc_removed_join.split() if word.lower() not in my_stopwords ]
  return Test_punc_removed_join_clean
[nltk_data] Downloading package stopwords to /root/nltk_data...
[nltk_data]   Unzipping corpora/stopwords.zip.

COUNT VECTORIZER 에 클리닝 함수를 애널라이저로 적용하여, 단어를 숫자로 바꾼다.

from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer(analyzer=message_cleaning)
X = vectorizer.fit_transform(yelp_df_1_5['text'])

X = X.toarray()
y = yelp_df_1_5['stars']

STEP#4: 학습용과 테스트용으로 데이터프레임을 나눈다. 테스트용은 20%로 설정한다. 그리고 나이브베이즈 모델링 한다.

from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2 , random_state=15)
from sklearn.naive_bayes import MultinomialNB, GaussianNB
classirier1 = MultinomialNB()
classirier1.fit(X_train,y_train)
MultinomialNB()
y_pred = classirier1.predict(X_test)
classirier2 = GaussianNB()
classirier2.fit(X_train,y_train)
GaussianNB()
y_pred_G = classirier2.predict(X_test)

STEP#5: 테스트셋으로 모델 평가. 컨퓨전 매트릭스 사용한다.

from sklearn.metrics import confusion_matrix, accuracy_score
confusion_matrix(y_test,y_pred)
array([[111,  52],
       [ 17, 638]])
accuracy_score(y_test,y_pred)
0.9156479217603912
confusion_matrix(y_test,y_pred_G)
array([[ 54, 109],
       [ 82, 573]])
accuracy_score(y_test,y_pred_G)
0.7665036674816625

STEP#6 다음 문장이 긍정인지 부정인지 예측하시오.

  1. ‘amazing food! highly recommmended’
  2. ‘shit food, made me sick’
test = vectorizer.transform([ 'amazing food! highly recommmended','shit food, made me sick'])
test = test.toarray()
classirier1.predict(test)
array([5, 1])

댓글남기기