酒店輿情分析


Python進行攜程酒店評論輿情分析

第一步:分析設計

  我們是對酒店進行輿情分析,所有我們的核心是酒店的評論數據;對住客的評論數據進行特征提取,通過住客對酒店的評分,對數據進行分類,並使用朴素貝葉斯算法建立數學模型

第二步:數據收集

  爬取酒店的相應類型的數據,如酒店的名稱,住客的評論,酒店的回復,住客的評分,酒店的綜合評分等等

酒店數據:

 

 

 

 

第三步:數據處理

數據清洗(在統計分析里面至少150條以上的數據

  依據評論ID去重數據(在SQL部分處理)

select * from  hotel_comment_datas group by `評論ID`

 

特征工程

 利用特征工程獲取相應評論的內容,需將文本信息轉為相應的數值

(1)獲取評論內容,做相應的索引(對所有的評論做處理)

import pandas as pd
sql = '''select * from  hotel_comment_datas   group by `評論ID`'''
data = pd.read_sql(sql, conn)
# 去除標簽列所對應的缺失值,可以使用花式索引的方式,對於數據進行相應的清洗和替換
data = data[['評論內容', '評分']].replace('none', np.NaN)
data = data.dropna()  # 刪除評論內容和用戶評分為空的數據

 

(2)開始分詞----cut

comment = data['評論內容']
# print(comment)
# (2)開始分詞----cut
list_word = []  # 創建空列表用來接收相應的結果

for i in comment:
    a = list(jieba.cut(i))  # 按照列表的方式進行相應的分詞
    list_word.append(' '.join(a))

 

 

(3)對於分詞后的文本進行相應的特征抽取,TF-TDF特征抽取。TF表示關鍵詞的頻率,TDF表示逆文檔的頻率,主要用來表示每個關鍵字在文檔的重要性

# TF-IDF 特征抽取
from sklearn.feature_extraction.text import TfidfVectorizer
tf = TfidfVectorizer()  # 調用TF-TDF分詞算法,將文本轉化為頻率

data1 = tf.fit_transform(list_word)  # 先擬合,再轉換,得出一個稀疏矩陣

 

 

第四步:數據分析

對因變量(住客評分)進行相應的分類

 

分類代碼

bq = []
for i in data['評分']:  # 初始的分類級別
     if float(i) <= 0:
         bq.append(0)
     elif 0 < float(i) <= 1:
         bq.append(1)
     elif 1 < float(i) <= 2:
         bq.append(2)
     elif 2 < float(i) <= 3:
         bq.append(3)
     elif 3 < float(i) <= 4:
         bq.append(4)
     else:
         bq.append(5)

 

划分數據集

(1)找到相對應的特征(自變量)x,標簽y(因變量)

x = data2
y = bq

 

(2)划分相應的訓練集和測試集,其中訓練集為80%,測試集為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=0)

 

(3)對數據進行標准化(將自變量的數據進行相應的標准化處理,可以使得某一個特征不會對總的結果產生較大影響)

# 對數據進行標准化處理
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()

# print(ss.fit_transform(x_train))  # 標准化后,有的值為正,有的值為負

x_train = ss.fit_transform(x_train)
x_test = ss.fit_transform(x_test)

 

數學建模-朴素貝葉斯分類算法

理解朴素貝葉斯算法

利用貝葉斯分類的目的:依據對應的評論內容給這個結果進行預測打分和客戶實際打分的區別

  • 預測打分可以將客戶評價分級,(分級的結果acc准確率要求比較高)
  • 進一步:分級后,將不同等級的用戶,單獨提取出來,按照預測的打分結果,產生新的一列
  • 按照預測評分結果,按照預測結果的不同等級,將整個數據划分為三個級別,需進一步考慮
  • 對於不同級別的顧客,可以考慮做相應的評價畫像
  • 同樣可以考慮做顧客畫像

代碼實現

from sklearn.naive_bayes import GaussianNB  # 用於處理有正有負的數據

nb = GaussianNB()  # 因為稀疏矩陣標准化后的值很可能是負值
nb.fit(x_train, y_train)  # 擬合相應的訓練集
x_predict = nb.predict(x_test)  # 放入相應的測試集進行分類
t_predict = nb.predict(x_train)  # 放入相應的訓練集進行分類
score_1 = nb.score(x_train, y_train)  # 使用對應的訓練集測試一下評估的ACC
score_2 = nb.score(x_test, y_test)
print(score_1, score_2)

 

模型的准確性

 

模型調優

增加相應的特征(如評論的推薦數)

 

這個特征,所有評論特征數,我們可以通過篩選所有評論特征數來提高我們的數據質量(數據的可靠性),進而提高我們的數學模型的ACC(准確率)

# 在sql部分重新篩選所有評論推薦數大於1的數據
sql = '''select * from  hotel_comment_datas  where `所有評論推薦數` >1  group by `評論ID`'''

 

 

 

  與未使用所有評論推薦數的特征的模型准確率,相比,訓練集的ACC提高了將近7個百分點,測試集的ACC降低了6個百分點 

 

可以考慮分類級別過多

  我們是對酒店進行分類,一般我們對酒店的評價是差、一般、好;但是我們之前是划分了5個等級,我們考慮一下是否分類過度,導致模型ACC過低?嘗試降低分類數

縮小分類級別
for i in data['評分']:
    if float(i) <= 2:
        bq.append(0)

    elif 2 < float(i) <= 4:
        bq.append(1)
    else:
        bq.append(2)

 

 

  相比與上圖的數學模型ACC而言,本次的訓練集數學模型ACC提高了近1個百分點 ,測試集數學模型ACC基本一致

 

修改訓練集(70%)與測試集(30%)的占比

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=0)

 

 

  相比上圖的數學模型ACC而言,本次訓練集的數學模型ACC提高近2個百分點,測試集的數學模型ACC提高近0.8個百分點

我們發現我們建立的數學模型的ACC依舊不是很理想,所有我們得進一步考慮提高模型的ACC。那么問題來了,我們如何再提高模型的ACC?

 

當然是再次把目光回歸到數據本身,提高提取新的特征來篩選高質量的數據

 

 增加特征,重新篩選數據

select * from  hotel_comment_datas  where `所有評論推薦數` >1 and `城市足跡數` >1 group by `評論ID`

 

  此時我們發現,我們的數學模型的ACC非常好

酒店數學建模代碼

#  --encoding:utf-8--
#  Yun

import numpy as np
import pandas as pd
import sklearn

from pprint import pprint

# TF-IDF 特征抽取
from sklearn.feature_extraction.text import TfidfVectorizer
# 對數據進行標准化處理
from sklearn.preprocessing import StandardScaler
# 引入朴素貝葉斯算法
from sklearn.naive_bayes import GaussianNB  # 用於處理有正有負的數據
from sklearn.naive_bayes import MultinomialNB  # 用於處理有正數的數據
# 划分數據集
from sklearn.model_selection import train_test_split
# 對所有的評論內容分開
import jieba

import pymysql

config = {
    'host': '127.0.0.1',
    'port': 3306,
    'user': 'root',
    'password': '123456',
    'db': 'xiecheng_cruise',
    'charset': 'utf8'
}
# 步驟一:連接數據庫並進行數據清洗
# 連接數據庫
conn = pymysql.connect(**config)
# 獲取MSC地中海郵輪·地中海輝煌號5天4晚福岡游輪旅游的評論
# sql = '''select  *  from  cruise_comment where cruise_name="MSC地中海郵輪·地中海輝煌號5天4晚福岡"  group by comment_id'''
sql = '''select * from  hotel_comment_datas  where `所有評論推薦數` >1 and `城市足跡數` >1 group by `評論ID`'''
data = pd.read_sql(sql, conn)

# 去除標簽列所對應的缺失值,可以使用花式索引的方式,對於數據進行相應的清洗和替換
data = data[['評論內容', '評分']].replace('none', np.NaN)
data = data.dropna()  # 刪除評論內容和用戶評分為空的數據
# 步驟二:對因變量進行相應的分類
# 需要對標簽進行相應的分類
bq = []
# for i in data['評分']:  # 初始的分類級別
#     if float(i) <= 0:
#         bq.append(0)
#     elif 0 < float(i) <= 1:
#         bq.append(1)
#     elif 1 < float(i) <= 2:
#         bq.append(2)
#     elif 2 < float(i) <= 3:
#         bq.append(3)
#     elif 3 < float(i) <= 4:
#         bq.append(4)
#
#     else:
#         bq.append(5)

# 降低分類級別
for i in data['評分']:
    if float(i) <= 2:
        bq.append(0)

    elif 2 < float(i) <= 4:
        bq.append(1)
    else:
        bq.append(2)
# print(bq)


# 步驟三:利用特征工程獲取相應評論的內容,需將文本信息轉為相應的數值
# (1)獲取評論內容,做相應的索引(對所有的評論做處理)
comment = data['評論內容']
# print(comment)
# (2)開始分詞----cut
list_word = []  # 創建空列表用來接收相應的結果

for i in comment:
    a = list(jieba.cut(i))  # 按照列表的方式進行相應的分詞
    list_word.append(' '.join(a))
# print(list_word)

# (3)對於分詞后的文本進行相應的特征抽取,TF-TDF特征抽取。TF表示關鍵詞的頻率,
# TDF表示逆文檔的頻率,主要用來表示每個關鍵字在文檔的重要性
tf = TfidfVectorizer()  # 調用TF-TDF分詞算法,將文本轉化為頻率

data1 = tf.fit_transform(list_word)  # 先擬合,再轉換,得出一個稀疏矩陣
# print(data1)
print('關鍵詞的數量:', len(tf.get_feature_names()))  # 查看一下分詞之后關鍵詞的數量

data2 = data1.toarray()  # 將產生的稀疏矩陣轉化為相應的數組

# pprint(data2)
# 步驟四:划分數據集
# 需將數據集進行相應的划分,train  test
# (1)找到相對應的特征(自變量)x,標簽y(因變量)

x = data2
y = bq

# (2)划分相應的訓練集和測試集,其中訓練集為80%,測試集為20%
# 為了演示結果一致,可以考慮使用隨機種子設置0
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0)

# print(x_train, y_train)
# (3)對數據進行標准化
ss = StandardScaler()

# print(ss.fit_transform(x_train))  # 標准化后,有的值為正,有的值為負

x_train = ss.fit_transform(x_train)
x_test = ss.fit_transform(x_test)

# 步驟五:正式引入貝葉斯算法,進行相應的分類-------朴素貝葉斯算法原理
# 利用貝葉斯分類的目的:依據對應的評論內容給這個結果進行預測打分和客戶實際打分的區別。
# 預測打分可以將客戶評價分級,(分級的結果acc准確率要求比較高)
# 進一步:分級后,將不同等級的用戶,單獨提取出來,按照預測的打分結果,產生新的一列
# 預測評分結果,按照預測結果的不同等級,將整個數據划分為三個級別,進一步考慮:對於不同級別的顧客
# 做相應的評價畫像(同樣可以考慮做顧客畫像)
nb = GaussianNB()  # 因為稀疏矩陣標准化后的值很可能是負值
nb.fit(x_train, y_train)  # 擬合相應的訓練集
x_predict = nb.predict(x_test)  # 放入相應的測試集進行分類
t_predict = nb.predict(x_train)  # 放入相應的訓練集進行分類
# print(x_predict)
print('================================================================')
# print(t_predict)
score_1 = nb.score(x_train, y_train)  # 使用對應的訓練集測試一下評估的ACC
score_2 = nb.score(x_test, y_test)
print(score_1, score_2)

# 步驟六:模型優化,增加相應的特征---我們在抽取數據的時候考慮進一步篩選數據
# 在數據篩選的時候考慮多個字段,在sql部分直接處理
# 可以考慮分類的級別過多,減少分類的個數,在對應的標簽處處理,發現對於總的評論而言
# 模型的准確率提升,並且,發現評論的推薦數,這個字段非常有用,可以提高整個模型的准確率(ACC)
View Code

 

第五步:數據可視化

酒店所有評論的詞雲圖

 

 

酒店差評詞雲圖

 

 詞雲繪制代碼

#  --encoding:utf-8--
#  Yun
import numpy as np
import pandas as pd
import pymysql
from jieba import analyse  # 運用此模塊做相對應的分詞處理----提取關鍵詞
from PIL import Image  # 處理圖片
from matplotlib import pyplot as plt
from wordcloud import WordCloud, ImageColorGenerator

config = {
    'host': '127.0.0.1',
    'port': 3306,
    'user': 'root',
    'password': '123456',
    'db': 'xiecheng_cruise',
    'charset': 'utf8'
}
# 步驟一:連接數據庫並進行數據清洗
# 連接數據庫
conn = pymysql.connect(**config)
# 依據貝葉斯分類方法提取的數據方式是一樣的
sql = '''select * from hotel_bad_comment_datas where 所有評論推薦數>1 and 酒店ID='662464' GROUP BY 評論ID'''
# sql = '''select * from  hotel_comment_datas  where `所有評論推薦數` >1 and `城市足跡數` >1 group by `評論ID`'''
data = pd.read_sql(sql, conn)
print(data)
# 清理none值,否則會成為高頻詞匯
data1 = data['評論內容'].replace('none', np.NaN).dropna()  # 刪除評論內容為空的數據

# 處理數據,生成關鍵詞的占比權重,此時的data1是Series數據
# 分詞是對於整個數據而言

data2 = data1.to_list()  # 將Series數據轉化為列表,為了做下一步的拼接
data3 = ''.join(data2)
# print(data3)

# 提取對應的關鍵詞,並查看這些關鍵詞對應的權重
result = analyse.textrank(data3, topK=50, withWeight=True)
print(result)
dict_1 = {}
for i in result:
    dict_1[i[0]] = i[1]
# print(dict_1)

# 生成對應的詞雲

# 利用PIL的Image打開背景圖片,並且進行相應的參數化
img = Image.open('timg2.jpg')

graph = np.array(img)  # 把img的參數給到graph生成相應的詞雲

# WordCloud默認不支持中文,加載對應的中文黑色字體庫,一般在電腦的C盤  fonts

# mask以傳遞過來的數據繪制詞雲
wc = WordCloud(font_path='‪C:\Windows\Fonts\simhei.ttf', background_color='white', max_words=300, mask=graph)

# 將字典的文本生成相對應的詞雲
wc.generate_from_frequencies(dict_1)

# 進一步,基於背景顏色,設置字體的顏色
image_color = ImageColorGenerator(graph)

# 顯示對應的圖片
plt.imshow(wc)  # 顯示對應的詞雲圖
plt.axis('off')  # 關閉圖像對應的坐標

plt.show()  # 顯示對應的窗口

# 將生成的圖片保存
wc.to_file('H:\大數據分析\攜程輿情分析\酒店差評詞雲.jpg')

# 考慮到這是多個酒店的差評的詞雲,考慮將單一酒店的詞雲圖提取出來,
# 在sql數據篩選階段修改篩選條件
# 例如通過酒店ID篩選每個酒店的差論詞雲
View Code

 

 

 

 

第六步:報告撰寫

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM