#패키지로드
import pandas as pd
import numpy as np
import plotly
import plotly.io as pio
import plotly.express as px
import plotly.graph_objects as go
import plotly.figure_factory as ff
from plotly.subplots import make_subplots
from plotly.validators.scatter.marker import SymbolValidator
df = pd.read_excel('df_all_1130_4.xlsx')
df.head()
site | hotel | score | review | date | star | length | review_spell_check | helpful | attitude | 담당자 | 위치 | 시설 | 인테리어 | 청결 | 친절 | 방음 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 아고다 | 나인트리 프리미어 명동2 | 10.0 | 뷰 좋고 위치 좋고 깨끗하고 최고 입니다 | NaN | NaN | 22 | 뷰 좋고 위치 좋고 깨끗하고 최고입니다 | 1 | 2 | 주현 | 1 | 0 | 0 | 0 | 0 | 0 |
1 | 아고다 | 신라스테이 광화문 | 10.0 | 위치 시설 모두 좋아요 | NaN | NaN | 12 | 위치 시설 모두 좋아요 | 0 | 2 | 주현 | 1 | 1 | 0 | 0 | 0 | 0 |
2 | 아고다 | 신라스테이 광화문 | 2.0 | 침대에 빨래 먼지로 보이는 먼지가 이불침대 시트 모두에 한가득이었습니다 청소 상태... | NaN | NaN | 69 | 침대에 빨래 먼지로 보이는 먼지가 이불 침대 시트 모두에 한가득이었습니다 청소 상... | 1 | 0 | 주현 | 0 | 0 | 0 | 1 | 0 | 0 |
3 | 아고다 | 신라스테이 광화문 | 8.8 | 위치 시설 서비스 모두 다 만족합니다 | NaN | NaN | 20 | 위치 시설 서비스 모두 다 만족합니다 | 0 | 2 | 주현 | 1 | 1 | 0 | 0 | 0 | 0 |
4 | 아고다 | 신라스테이 광화문 | 8.0 | 주변에 식사장소도 많고 볼 곳도 많아서 좋습니다다만 주말에는 집회가 근처에서 많아 ... | NaN | NaN | 57 | 주변에 식사 장소도 많고 볼 곳도 많아서 좋습니다 다만 주말에는 집회가 근처에서 많... | 1 | 1 | 주현 | 1 | 0 | 0 | 0 | 0 | 1 |
df['score_'] = df['score'].map(lambda x: round(x))
df['score_'].unique()
array([10, 2, 9, 8, 6, 4, 7, 3, 5], dtype=int64)
df['helpful'].value_counts()
0 1441 1 968 Name: helpful, dtype: int64
g = df.groupby(['score_','attitude']).count().site.reset_index()
g.columns = ['score', 'attitude', 'res']
all = g.groupby(['score']).sum().res
all = all.reset_index()
all.columns = ['score','all']
g = g.merge(all)
g['rate'] = g['res']/g['all']
add = [(3,1,0,0,0),(3,2,0,0,0),(5,2,0,0,0)]
add = pd.DataFrame(add, columns = g.columns)
g = g.append(add, ignore_index = True)
g = g.sort_values(["score","attitude"])
g.head()
score | attitude | res | all | rate | |
---|---|---|---|---|---|
0 | 2 | 0 | 21 | 27 | 0.777778 |
1 | 2 | 1 | 3 | 27 | 0.111111 |
2 | 2 | 2 | 3 | 27 | 0.111111 |
3 | 3 | 0 | 1 | 1 | 1.000000 |
24 | 3 | 1 | 0 | 0 | 0.000000 |
g['score'].unique()
array([ 2, 3, 4, 5, 6, 7, 8, 9, 10], dtype=int64)
x = g['score'].unique()
y0 = g[g['attitude']==0]
y1 = g[g['attitude'] ==1]
y2 = g[g['attitude'] ==2]
fig = go.Figure()
fig.add_trace(go.Bar(x=x, y = y0.rate, name = "부정"))
fig.add_trace(go.Bar(x=x, y = y1.rate, name = "중립"))
fig.add_trace(go.Bar(x=x, y = y2.rate, name = "긍정"))
fig.update_traces(hovertemplate = '평점: %{x}점 <br>비율: %{y}')
#fig.update_layout(xaxis_type = 'category')
#fig.update_yaxes(tickvals = [0, 20, 40, 60, 80, 100])
fig.update_yaxes(nticks = 5)
fig.update_xaxes(title = "평점")
fig.update_layout(yaxis_tickformat = '%',
barmode = 'relative',
hoverlabel = dict(font_size = 15),
template = 'seaborn') #stack으로 만들어짐
fig.write_html("평점 별 긍부정 비율.html")
fig.show()
x = g['score'].unique()
y0 = g[g['attitude']==0]
y1 = g[g['attitude'] ==1]
y2 = g[g['attitude'] ==2]
fig = go.Figure()
fig.add_trace(go.Bar(x=x, y = y0.res, name = "부정"))
fig.add_trace(go.Bar(x=x, y = y1.res, name = "중립"))
fig.add_trace(go.Bar(x=x, y = y2.res, name = "긍정"))
fig.update_traces(hovertemplate = '평점: %{x} <br>개수 : %{y}')
#fig.update_layout(xaxis_type = 'category')
fig.update_yaxes(nticks = 5)
fig.update_layout(
barmode = 'relative',
hoverlabel = dict(font_size = 15),
template = 'plotly_white') #stack으로 만들어짐
fig.write_html("평점 별 긍부정.html")
fig.show()
부정적인 리뷰를 써도, 별점은 높게 줌. 별점만으로 긍/부정을 파악할 수 없음. 리뷰 내용을 봐야 호텔의 진짜 상태를 파악할 수 있는 것
g = df.groupby(['attitude','helpful']).count().site.reset_index()
g.columns = ['attitude', 'helpful', 'res']
all = g.groupby(['attitude']).sum().res
all = all.reset_index()
all.columns = ['attitude','all']
g = g.merge(all)
g['rate'] = g['res']/g['all']
g = g.sort_values(["attitude","helpful"])
g
attitude | helpful | res | all | rate | |
---|---|---|---|---|---|
0 | 0 | 0 | 37 | 166 | 0.222892 |
1 | 0 | 1 | 129 | 166 | 0.777108 |
2 | 1 | 0 | 147 | 501 | 0.293413 |
3 | 1 | 1 | 354 | 501 | 0.706587 |
4 | 2 | 0 | 1257 | 1742 | 0.721584 |
5 | 2 | 1 | 485 | 1742 | 0.278416 |
#x = g['attitude'].unique()
layout_font = {'font':dict(size=18,color='#60606e',family='Franklin Gothic' )}
x = ['부정','중립','긍정']
y0 = g[g['helpful']==0]
y1 = g[g['helpful'] ==1]
fig = go.Figure()
fig.add_trace(go.Bar(x=x, y = y0.rate, name = "불성실", marker_color = 'royalblue'))
fig.add_trace(go.Bar(x=x, y = y1.rate, name = "성실",marker_color = 'skyblue'))
fig.update_traces(hovertemplate = 'attitude: %{x} <br>비율 : %{y}')
#fig.update_layout(xaxis_type = 'category')
fig.update_yaxes(nticks = 5)
fig.update_layout(yaxis_tickformat = '%',
barmode = 'relative',
hoverlabel = dict(font_size = 18),
template = 'presentation') #stack으로 만들어짐
fig.update_xaxes(title_font = dict(size = 18, family = 'Gothic',color='#60606e' ))
fig.update_layout(xaxis_type = 'category')
#fig.update_xaxes(tickvals = '부정','중립','긍정'})
fig.write_html("atttitude별 성실 불성실 비율.html")
fig.show()
g = df.groupby(['score_','helpful']).count().site.reset_index()
add = [(3,0,0)]
add = pd.DataFrame(add, columns = g.columns)
g = g.append(add, ignore_index = True)
g = g.sort_values(["score_","helpful"])
helpful_dict = {0: '불성실',
1:'성실'}
g['helpful'] = g['helpful'].map(helpful_dict)
g.head()
score_ | helpful | site | |
---|---|---|---|
0 | 2 | 불성실 | 10 |
1 | 2 | 성실 | 17 |
17 | 3 | 불성실 | 0 |
2 | 3 | 성실 | 1 |
3 | 4 | 불성실 | 8 |
fig = px.bar(g, x = 'score_', y = 'site',
color = 'helpful', barmode = 'group',
height = 400)
fig.update_layout(xaxis_type = 'category')
fig.show()
df = pd.read_excel("df_all_1130_4.xlsx")
df.head(3)
site | hotel | score | review | date | star | length | review_spell_check | helpful | attitude | 담당자 | 위치 | 시설 | 인테리어 | 청결 | 친절 | 방음 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 아고다 | 나인트리 프리미어 명동2 | 10.0 | 뷰 좋고 위치 좋고 깨끗하고 최고 입니다 | NaN | NaN | 22 | 뷰 좋고 위치 좋고 깨끗하고 최고입니다 | 1 | 2 | 주현 | 1 | 0 | 0 | 0 | 0 | 0 |
1 | 아고다 | 신라스테이 광화문 | 10.0 | 위치 시설 모두 좋아요 | NaN | NaN | 12 | 위치 시설 모두 좋아요 | 0 | 2 | 주현 | 1 | 1 | 0 | 0 | 0 | 0 |
2 | 아고다 | 신라스테이 광화문 | 2.0 | 침대에 빨래 먼지로 보이는 먼지가 이불침대 시트 모두에 한가득이었습니다 청소 상태... | NaN | NaN | 69 | 침대에 빨래 먼지로 보이는 먼지가 이불 침대 시트 모두에 한가득이었습니다 청소 상... | 1 | 0 | 주현 | 0 | 0 | 0 | 1 | 0 | 0 |
len(df.columns)
df.columns[-6:]
Index(['위치', '시설', '인테리어', '청결', '친절', '방음'], dtype='object')
data = pd.DataFrame([])
for k in list(df.columns[-6:]):
df_ = df.groupby([k]).count().hotel
df_ = df_.reset_index()
df_ = pd.melt(df_, id_vars = ['hotel'])
df_ = df_[df_.value == 1]
data = data.append(df_)
fig = px.bar(data, x = 'variable', y = 'hotel',
barmode = 'group',
height = 400)
fig.update_layout(xaxis_type = 'category', title = "Category별 리뷰수",
xaxis = { 'categoryorder': 'total descending'})
fig.update_traces(hovertemplate = 'Category: %{x} <br>리뷰수: %{y}')
fig.update_xaxes(title_text = '리뷰수')
fig.update_yaxes(title_text = 'Category')
fig.show()
data = pd.DataFrame([])
for k in list(df.columns[-7:]):
df_ = df[df[k] == 1]
df_ = df_.groupby(["attitude"]).count().hotel
df_ = df_.reset_index()
df_.columns = ["attitude",k]
df_ = pd.melt(df_, id_vars = ['attitude'])
data = data.append(df_)
value_dict = {0: '부정',
1:'중립',
2: '긍정'}
data['attitude'] = data['attitude'].map(value_dict)
data.head()
attitude | variable | value | |
---|---|---|---|
0 | 부정 | 위치 | 13 |
1 | 중립 | 위치 | 158 |
2 | 긍정 | 위치 | 399 |
0 | 부정 | 시설 | 31 |
1 | 중립 | 시설 | 122 |
data2 = data.groupby(["variable"]).sum().value
data2 = data2.reset_index()
data2.columns = ["variable","all"]
data = data.merge(data2, how = "left")
data["rate"] = data["value"]/data["all"]
data.head()
attitude | variable | value | all | rate | |
---|---|---|---|---|---|
0 | 부정 | 위치 | 13 | 570 | 0.022807 |
1 | 중립 | 위치 | 158 | 570 | 0.277193 |
2 | 긍정 | 위치 | 399 | 570 | 0.700000 |
3 | 부정 | 시설 | 31 | 376 | 0.082447 |
4 | 중립 | 시설 | 122 | 376 | 0.324468 |
fig = px.bar(data, x = 'variable', y = 'value',
color = 'attitude', barmode = 'group',
height = 400)
fig.update_traces(hovertemplate = 'Category: %{x} <br>리뷰수: %{y}')
fig.update_xaxes(title_text = '리뷰수')
fig.update_yaxes(title_text = 'Category')
fig.update_layout(xaxis_type = 'category', template = 'ggplot2')
fig.show()
x = data['variable'].unique()
y0 = data[data['attitude']=="부정"]
y1 = data[data['attitude'] =="중립"]
y2 = data[data['attitude'] =="긍정"]
fig = go.Figure()
fig.add_trace(go.Bar(x=x, y = y0.rate, name = "부정"))
fig.add_trace(go.Bar(x=x, y = y1.rate, name = "중립"))
fig.add_trace(go.Bar(x=x, y = y2.rate, name = "긍정"))
fig.update_traces(hovertemplate = '카테고리: %{x} <br>비율: %{y}')
#fig.update_layout(xaxis_type = 'category')
#fig.update_yaxes(tickvals = [0, 20, 40, 60, 80, 100])
fig.update_yaxes(nticks = 5)
fig.update_xaxes(title = "Category")
fig.update_layout(yaxis_tickformat = '%',
barmode = 'relative',
hoverlabel = dict(font_size = 15),
template = 'seaborn') #stack으로 만들어짐
fig.write_html("카테고리 별 긍부정 비율.html")
fig.show()
data = pd.DataFrame([])
for k in list(df.columns[-6:]):
df_ = df[df[k] == 1]
df_ = df_.groupby(["helpful"]).count().hotel
df_ = df_.reset_index()
df_.columns = ["helpful",k]
df_ = pd.melt(df_, id_vars = ['helpful'])
data = data.append(df_)
helpful_dict = {0: '불성실',
1:'성실'}
data['helpful'] = data['helpful'].map(helpful_dict)
colors = ['cyon','indigo']
fig = px.bar(data, x = 'variable', y = 'value',
color = 'helpful', barmode = 'group',
height = 400)
fig.update_traces(hovertemplate = 'Category: %{x} <br>리뷰수: %{y}')
fig.update_xaxes(title_text = 'Category')
fig.update_yaxes(title_text = '리뷰수')
fig.update_layout(xaxis_type = 'category', template = 'ggplot2', title = "Category별 성실·불성실 리뷰수")
fig.show()
scat = pd.read_excel('scatterplot.xlsx')
scat.head(1)
예측 | 실제 | site | hotel | score | review | date | star | length | review_spell_check | helpful | attitude | 위치 | 시설 | 인테리어 | 청결 | 친절 | 방음 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0.77 | 1 | 야놀자 | 신라스테이 광화문 | 10.0 | 위치적으로 접근하기 좋았고 청결도와 직원 서비스가 깔끔해서 다시 가도 좋겠다 생각했습니다 | 2020. 04. 01 | 5.0 | 49 | 위치적으로 접근하기 좋았고 청결 도와 직원 서비스가 깔끔해서 다시 가도 좋겠다 생각... | 1 | 2 | 1 | 0 | 0 | 1 | 1 | 0 |
score_dict = {0:'도움X', 1:'도움O'}
scat["실제"] = scat["실제"].map(score_dict)
attitude_dict = {0:'부정', 1:'중립', 2:'긍정'}
scat["attitude"] = scat["attitude"].map(attitude_dict)
scat.head()
예측 | 실제 | site | hotel | score | review | date | star | length | review_spell_check | helpful | attitude | 위치 | 시설 | 인테리어 | 청결 | 친절 | 방음 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0.77 | 도움O | 야놀자 | 신라스테이 광화문 | 10.0 | 위치적으로 접근하기 좋았고 청결도와 직원 서비스가 깔끔해서 다시 가도 좋겠다 생각했습니다 | 2020. 04. 01 | 5.0 | 49 | 위치적으로 접근하기 좋았고 청결 도와 직원 서비스가 깔끔해서 다시 가도 좋겠다 생각... | 1 | 긍정 | 1 | 0 | 0 | 1 | 1 | 0 |
1 | 0.09 | 도움X | 야놀자 | 신라스테이 광화문 | 10.0 | 좋습니다 역시 호텔임 | 2020. 10. 05 | 5.0 | 11 | 좋습니다 역시 호텔임 | 0 | 긍정 | 0 | 0 | 0 | 0 | 0 | 0 |
2 | 0.48 | 도움O | 야놀자 | 롯데 호텔 서울 | 8.0 | 정말 좋았습니다 다만 지금 공사기간입니다 나머지는 더할나위 없었네요 | 2018. 08. 04 | 4.0 | 37 | 정말 좋았습니다 다만 지금 공사기간입니다 나머지는 더할 나위 없었네요 | 1 | 중립 | 0 | 0 | 0 | 0 | 0 | 0 |
3 | 0.56 | 도움X | 야놀자 | 신라스테이 광화문 | 8.0 | 깨끗하고 편의시설도 주변에 많고 친절하고 좋았어요 다음이 또 이용하겠습니다 | 2018-08-24 00:00:00 | 4.0 | 41 | 깨끗하고 편의시설도 주변에 많고 친절하고 좋았어요 다음이 또 이용하겠습니다 | 0 | 긍정 | 0 | 1 | 0 | 1 | 1 | 0 |
4 | 0.99 | 도움O | 야놀자 | 그랜드 워커힐 서울 | 8.0 | 말로만 듣던 5성급 모든시설과 서비스 등 최고 청결도나 방음 좋다 뷰는 리버뷰이긴 ... | 2019. 09. 23 | 4.0 | 226 | 말로만 듣던 5성급 모든 시설과 서비스 등 최고 청결도 나 방음 좋다 뷰는 리버뷰이... | 1 | 부정 | 0 | 1 | 0 | 1 | 0 | 1 |
scat["score_up"] = scat["score"].map(lambda x : x*100)
#실제값으로 색 구분
fig = px.scatter(scat, x = '예측', y = 'length',color = '실제', size = "length")
fig.show()
#길이로 색 구분
fig = px.scatter(scat, x = '예측', y = 'length',color = 'score', size = 'length')
fig.show()
fig = px.scatter(scat, x = '예측', y = 'length',color = '실제')
fig.update_traces(hovertemplate = '예측: %{x}% <br>리뷰길이: %{y}')
fig.update_xaxes(title = "확률")
#fig.update_layout(title = "")
fig.update_layout(
xaxis = dict(
tickangle = 60,
title_text = '예측',
title_font = {'size':20},
title_standoff = 20),
yaxis = dict(
title_text = 'Length',
title_font = {'size':20},
title_standoff = 20)
)
fig.write_html("예측실제길이.html")
fig.show()
fig = px.scatter(scat, x= '예측', y = 'length', color = 'score',
facet_row = 'helpful')
fig.show()
#facet_row 는 속성값에 따라 분리해서 scatter plot을 그림
#길이에 따라 색 구분
fig = px.scatter(scat, x= '예측', y = 'length',
facet_row = 'helpful', color = "실제")
fig.show()
#실제값으로 색 구분
fig = px.scatter(scat, x = '예측', y = 'length',color = 'attitude')
fig.show()
fig = px.scatter(scat, x= '예측', y = 'length', color = "실제",
facet_row = 'attitude')
fig.update_traces(hovertemplate = '예측: %{x}% <br>리뷰길이: %{y} <br>%{color}')
fig.show()
#facet_row 는 속성값에 따라 분리해서 scatter plot을 그림
fig = px.scatter(scat, x= '예측', y = 'length', color = "attitude",
facet_row = 'attitude', hover_data = ["실제"])
#fig.update_traces(hovertemplate = '예측: %{x}% <br>리뷰길이: %{y}')
fig.show()
#facet_row 는 속성값에 따라 분리해서 scatter plot을 그림
df['total'] = df[['위치', '시설', '인테리어',
'청결', '친절', '방음']].sum(axis=1)
pie = df.groupby(['attitude','total']).count().review
pie = pie.reset_index()
pie.columns = ['attitude','Category_count','review']
add = [(0,5,0), (0,6,0),(1,6,0), (2, 6, 0)]
add = pd.DataFrame(add, columns = pie.columns)
pie = pie.append(add, ignore_index = True)
pie = pie.sort_values(["attitude", "Category_count"])
pie = pie[pie["Category_count"]!=0]
pie['Category_count'] = pie['Category_count'].map(lambda x : str(x))
pie
attitude | Category_count | review | |
---|---|---|---|
1 | 0 | 1 | 87 |
2 | 0 | 2 | 31 |
3 | 0 | 3 | 5 |
4 | 0 | 4 | 1 |
17 | 0 | 5 | 0 |
18 | 0 | 6 | 0 |
6 | 1 | 1 | 151 |
7 | 1 | 2 | 122 |
8 | 1 | 3 | 64 |
9 | 1 | 4 | 20 |
10 | 1 | 5 | 4 |
19 | 1 | 6 | 0 |
12 | 2 | 1 | 483 |
13 | 2 | 2 | 332 |
14 | 2 | 3 | 101 |
15 | 2 | 4 | 26 |
16 | 2 | 5 | 3 |
20 | 2 | 6 | 0 |
neg = pie[pie.attitude == 0]
fig = px.pie(neg, values = 'review', hover_data = ['Category_count'],
color_discrete_sequence = px.colors.sequential.dense, names = 'Category_count',labels = {'Category_count' : '포함된 카테고리 수'})
fig.update_traces(textposition = 'inside', textinfo = 'percent + label', textfont_size = 14) #위에 거슬리는 숫자들을 안으로!
fig.update_traces(textposition = 'inside', textinfo = 'percent + label', textfont_size = 14,
marker = dict(line = dict(color = 'black', width = 1)))
fig.update_layout(title = "부정")
fig.show()
pos = pie[pie.attitude == 0]
fig = px.pie(neg, values = 'review', hover_data = ['Category_count'],
color_discrete_sequence = px.colors.sequential.dense, names = 'Category_count',labels = {'Category_count' : '포함된 카테고리 수'})
fig.update_traces(textposition = 'inside', textinfo = 'percent + label', textfont_size = 14) #위에 거슬리는 숫자들을 안으로!
fig.update_traces(textposition = 'inside', textinfo = 'percent + label', textfont_size = 14,
marker = dict(line = dict(color = 'black', width = 1)))
fig.update_layout(title = "긍정")
fig.show()
neu = pie[pie.attitude == 0]
fig = px.pie(neg, values = 'review', hover_data = ['Category_count'],
color_discrete_sequence = px.colors.sequential.dense, names = 'Category_count',labels = {'Category_count' : '포함된 카테고리 수'})
fig.update_traces(textposition = 'inside', textinfo = 'percent + label', textfont_size = 14) #위에 거슬리는 숫자들을 안으로!
fig.update_traces(textposition = 'inside', textinfo = 'percent + label', textfont_size = 14,
marker = dict(line = dict(color = 'black', width = 1)))
fig.update_layout(title = "중립")
fig.show()