《Python資料分析與挖掘實戰》第15章——文字挖掘
阿新 • • 發佈:2019-01-10
本文是基於《Python資料分析與挖掘實戰》的實戰部分的第15章的資料——《電商產品評論資料情感分析》做的分析。
旨在回顧對評論文字資料的處理和建模方法。
1 挖掘背景與目標
對京東平臺上的熱水器評論進行文字挖掘分析,挖掘建模如下:
1)分析某一個品牌熱水器的使用者情感傾向
2)從評論文字中挖掘出該品牌熱水器的優點和不足
3)提煉不同品牌熱水器的賣點
2 資料探索與預處理
2.1 資料篩選
# -*- coding:utf-8 -*- import pandas as pd inputfile = 'huizong.csv' # 評論彙總檔案 data = pd.read_csv(inputfile, encoding = 'utf-8') result = data[[u'評論']][data[u'品牌'] == u'美的'] result.info()
輸出結果
2.2 to_txt
# 必須匯入下面這個包,要不然會報錯'ascii' codec can't encode characters in position
# Python在安裝時,預設的編碼是ascii,當程式中出現非ascii編碼時,python的處理常常會報這樣的錯
import sys
reload(sys)
sys.setdefaultencoding( "utf-8" )
result.to_csv('1_1my_meidi_jd.txt', index = False, header = False) # 將評論提取後儲存到txt中,不要索引,不要列名(***)
2.3 原始資料去重
import pandas as pd inputfile = '1_1my_meidi_jd.txt' # 評論彙總檔案 data = pd.read_csv(inputfile, encoding = 'utf-8', header = None) #(***) l1 = len(data) print u'原始資料有%d條' % l1 # 原始資料有55774條 data = pd.DataFrame(data[0].unique())# (*****) l2 = len(data) print u'去重後資料有%d條' % l2 # 去重後資料有53049條 data.to_csv('2_1my_meidi_jd_delduplis.txt', header = False, index = False, encoding='utf-8') # (***)
2.4 刪除字首
inputfile1 = u'meidi_jd_process_end_負面情感結果.txt' # 評論彙總檔案
inputfile2 = u'meidi_jd_process_end_正面情感結果.txt' # 評論彙總檔案
data1 = pd.read_csv(inputfile1, encoding = 'utf-8', header = None) #(***)
data2 = pd.read_csv(inputfile2, encoding = 'utf-8', header = None) #(***)
data1 = pd.DataFrame(data1[0].str.replace('.*?\d+?\\t', '')) # 使用正則表示式替換掉字首
data2 = pd.DataFrame(data2[0].str.replace('.*?\d+?\\t', '')) # 使用正則表示式替換掉字首
data1.to_csv(u'3_1my_meidi_jd_process_end_負面情感結果.txt', header = False, index = False, encoding='utf-8') # (***)
data2.to_csv(u'3_2my_meidi_jd_process_end_正面情感結果.txt', header = False, index = False, encoding='utf-8') # (***)
2.5 分詞
import pandas as pd
import jieba # 匯入結巴分詞包
inputfile1 = u'3_1my_meidi_jd_process_end_負面情感結果.txt'
inputfile2 = u'3_2my_meidi_jd_process_end_正面情感結果.txt'
data1 = pd.read_csv(inputfile1, encoding = 'utf-8', header = None) #(***)
data2 = pd.read_csv(inputfile2, encoding = 'utf-8', header = None) #(***)
mycut = lambda s: " ".join(jieba.cut(s)) # 自定義簡單分詞函式
data1 = data1[0].apply(mycut) # 通過廣播形式分詞,加快速度
data2 = data2[0].apply(mycut) # 通過廣播形式分詞,加快速度
data1.to_csv(u'4_1my_meidi_jd_process_end_負面情感結果_cut.txt', header = False, index = False, encoding='utf-8') # (***)
data2.to_csv(u'4_2my_meidi_jd_process_end_正面情感結果_cut.txt', header = False, index = False, encoding='utf-8') # (***)
3 基於LED 模型的主題分析
# 方法:在分好詞的正面評價、負面評價以及過濾用的停用詞表上進行,使用Gensim庫完成LDA分析程式碼
import pandas as pd
# 引數初始化
inputfile1 = u'4_1my_meidi_jd_process_end_負面情感結果_cut.txt'
inputfile2 = u'4_2my_meidi_jd_process_end_正面情感結果_cut.txt'
inputfile3 = 'stoplist.txt' # 停用詞表
data1 = pd.read_csv(inputfile1, encoding = 'utf-8', header = None) #(***)
data2 = pd.read_csv(inputfile2, encoding = 'utf-8', header = None) #(***)
stop = pd.read_csv(inputfile3, encoding = 'utf-8', sep = 'tipdm', header = None) #(***)
# sep 設定分割詞, 由於csv預設以半形逗號為分割詞,而該詞恰好在停用詞表中,因此會導致讀取出錯
# 所以,解決方法是手動設定一個不存在的分割詞,如tipdm
stop = [' ', ''] +list(stop[0]) # pandas自動過濾了空格符,所以手動將其加入
data1 [1] = data1[0].apply(lambda s: s.split(' ')) # 定義一個分隔函式,用apply廣播
data1 [2] = data1[1].apply(lambda x: [i for i in x if i not in stop]) # 逐詞判斷是否是停用詞
data2 [1] = data2[0].apply(lambda s: s.split(' ')) # 定義一個分隔函式,用apply廣播
data2 [2] = data2[1].apply(lambda x: [i for i in x if i not in stop]) # 逐詞判斷是否是停用詞
from gensim import corpora, models
# 負面主題分析
data1_dict = corpora.Dictionary(data1[2]) # 建立詞典
data1_corpus = [data1_dict.doc2bow(i) for i in data1[2]] # 建立語料庫
data1_LDA = models.LdaModel(data1_corpus, num_topics =3, id2word = data1_dict) # LDA訓練模型
for i in range(3):
data1_LDA.print_topic(i)# 輸出每個主題
# 正面主題分析
data2_dict = corpora.Dictionary(data2[2]) # 建立詞典
data2_corpus = [data2_dict.doc2bow(i) for i in data2[2]] # 建立語料庫
data2_LDA = models.LdaModel(data2_corpus, num_topics =3, id2word = data2_dict) # LDA訓練模型
for i in range(3):
data2_LDA.print_topic(i)# 輸出每個主題
PS:不知道為什麼輸出時有編碼問題data1_LDA.print_topic(0)
輸出:
u'0.044*"\u7684" + 0.036*"\u8fd8" + 0.027*"\u5b89\u88c5" + 0.024*"\u4e86" + 0.021*"\u5f88" + 0.019*"\u4e0d\u9519" + 0.015*"\u4e0d" + 0.013*"\u7528" + 0.011*"\u597d" + 0.011*"\u5c31\u662f"'
備註:本章完整程式碼請見:點選開啟連結