1. 程式人生 > >《Python資料分析與資料探勘實戰》第十五章學習——文字分析

《Python資料分析與資料探勘實戰》第十五章學習——文字分析

本章主要實戰目的是對京東平臺上的熱水器評論進行文字挖掘分析,包括分析其使用者情感傾向、從評論文字中挖掘出該品牌熱水器的優點與不足和提煉不同品牌熱水器的賣點。
本文主要包括以下幾個部分:

  1. 評論資料抽取
  2. 評論預處理
  3. 模型準備
  4. 模型構建
  5. 總結

評論資料抽取

評論資料抽取旨在選擇某一個具體品牌進行評論分析,按照書中步驟選擇抽取美的品牌的評論資料。
程式碼如下:

import pandas as pd
inputfile='D:/ProgramData/PythonDataAnalysiscode/chapter15/demo/data/huizong.csv'
outputfile='D:/ProgramData/PythonDataAnalysiscode/chapter15/demo/data2/meidi_jd.txt'
data=pd.read_csv(inputfile,encoding='utf-8') data=data[[u'評論']][data[u'品牌']==u'美的'] data.to_csv(outputfile,index=False,header=False,encoding='utf-8')

結果如下圖:
這裡寫圖片描述

評論文字去重

評論資料抽取完成後,需要對資料進行預處理,預處理包括文字去重、機械壓縮去詞以及短句刪除。
由於機械壓縮去詞還沒有摸索出來,因此這裡暫時只進行文字去重。
文字去重,即去掉評論資料中重複的部分,比如一些預設評論、同一個人購買多件商品所出現的重複評論、不同使用者為了省事複製貼上的評論等等。
書中沒有用到複雜的文字去重演算法,只用了簡單的unique()方法。
程式碼如下:

import pandas as pd
inputfile='D:/ProgramData/PythonDataAnalysiscode/chapter15/demo/data2/meidi_jd.txt'
outputfile='D:/ProgramData/PythonDataAnalysiscode/chapter15/demo/data2/meidi_jd_process1.txt'
data=pd.read_csv(inputfile,encoding='utf-8',header=None)
l1=len(data)
data=pd.DataFrame(data[0].unique())
l2=len(data)
data.to_csv(outputfile,encoding='utf-8'
,header=False,index=False) print u'刪除了%s條評論。'%(l1-l2)

利用這種方法,最後刪除了2725條評論。

模型準備

在構建模型之前,先利用武漢大學的內容分析工具ROSTCM6對文字進行了情感分析,得出了積極樣本和消極樣本,然後需要對兩者進行刪除字首評分處理和分詞處理。
之前寫論文的時候曾經對這個工具進行過使用,是比較便捷的內容分析工具,很容易上手,此處不另外說明了。

刪除字首評分

用工具得出來的最後結果前面是有情感得分的,需要刪除這個字首。
程式碼如下:

import pandas as pd

#引數初始化
inputfile1='D:/ProgramData/PythonDataAnalysiscode/chapter15/demo/data/meidi_jd_process_end_negtive.txt'
inputfile2='D:/ProgramData/PythonDataAnalysiscode/chapter15/demo/data/meidi_jd_process_end_positive.txt'
outputfile1='D:/ProgramData/PythonDataAnalysiscode/chapter15/demo/data2/meidi_jd_neg.txt'
outputfile2='D:/ProgramData/PythonDataAnalysiscode/chapter15/demo/data2/meidi_jd_pos.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(outputfile1,index=False,header=False,encoding='utf-8')
data2.to_csv(outputfile2,index=False,header=False,encoding='utf-8')

分詞

文字分詞是將連續的字序列按照一定的規範重新組合成詞序列的過程。書中採用python的中文分詞包——jieba對評論資料進行分詞。
程式碼如下:

import pandas as pd
import jieba
#引數初始化
inputfile1='D:/ProgramData/PythonDataAnalysiscode/chapter15/demo/data2/meidi_jd_neg.txt'
inputfile2='D:/ProgramData/PythonDataAnalysiscode/chapter15/demo/data2/meidi_jd_pos.txt'
outputfile1='D:/ProgramData/PythonDataAnalysiscode/chapter15/demo/data2/meidi_jd_neg_cut.txt'
outputfile2='D:/ProgramData/PythonDataAnalysiscode/chapter15/demo/data2/meidi_jd_pos_cut.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(outputfile1,encoding='utf-8',header=False,index=False)
data2.to_csv(outputfile2,encoding='utf-8',header=False,index=False)

消極評論分詞結果如下:
這裡寫圖片描述

模型構建

本章所用模型為LDA主題模型。該模型是由Blei等人在2003年提出的生成式主題模型,模型認為每一篇文件的每一個詞都是通過“以一定概率選擇了某個主題,並從這個主題中以一定概率選擇某個詞語”。LDA具體原理可參考主題模型-LDA淺析
python中的自然語言處理包-gensim中有LDA演算法。
關於模型構建的程式碼如下:

#-*-coding:utf-8 -*-
import pandas as pd

#引數初始化
negfile='D:/ProgramData/PythonDataAnalysiscode/chapter15/demo/data/meidi_jd_neg_cut.txt'
posfile='D:/ProgramData/PythonDataAnalysiscode/chapter15/demo/data/meidi_jd_pos_cut.txt'
stoplist='D:/ProgramData/PythonDataAnalysiscode/chapter15/demo/data/stoplist.txt'

neg=pd.read_csv(negfile,encoding='utf-8',header=None)
pos=pd.read_csv(posfile,encoding='utf-8',header=None)
stop=pd.read_csv(stoplist,encoding='utf-8',header=None,sep='tipdm')
#sep設定分割詞,由於csv預設以半形逗號為分割詞,而該詞恰好在停用詞表中,因此會導致讀取出錯
#所以解決辦法是手動設定一個不存在的分割詞,如tipdm。
stop = [' ', ''] + list(stop[0]) #Pandas自動過濾了空格符,這裡手動新增

neg[1]=neg[0].apply(lambda s:s.split(' '))#定義一個分割函式,然後用apply廣播
neg[2]=neg[1].apply(lambda x:[i for i in x if i not in stop])#逐詞判斷是否停用詞
pos[1]=pos[0].apply(lambda s:s.split(' '))
pos[2]=pos[1].apply(lambda x:[i for i in x if i not in stop])

#從自然語言處理包中匯入程式包,其中corpora代表原始文字的集合(語料),models代表各個主題模型
from gensim import corpora,models


#負面主題分析
#訓練語料預處理
neg_dict=corpora.Dictionary(neg[2])#建立詞典
neg_corpus=[neg_dict.doc2bow(i) for i in neg[2]]#建立語料庫
#LDA模型訓練
neg_lda=models.LdaModel(neg_corpus,num_topics=3,id2word=neg_dict)
for i in range(3):
    neg_lda.print_topic(i)#輸出每個主題

#正面主題分析
#訓練語料預處理
pos_dict=corpora.Dictionary(pos[2])#建立詞典
pos_corpus=[pos_dict.doc2bow(i) for i in pos[2]]
#LDA模型訓練
pos_lda=models.LdaModel(pos_corpus,num_topics=3,id2word=pos_dict)
for i in range(3):
    pos_lda.print_topic(i)#輸出每個主題

經過LDA主題分析後,聚成三個主題,按理應該輸出每個主題下生成的10個最有可能出現的詞語及其概率,代表評論文字中的潛在主題。但不知道為什麼沒有輸出內容,因此本文又用show_topics()方法來展示正面評論和負面評論每個主題的情況。
程式碼如下:

pos_lda.show_topics()
neg_lda.show_topics()

正面評論的潛在主題如下所示:
這裡寫圖片描述
負面評論的潛在主題則如下所示:
這裡寫圖片描述
從正面評論的第一個主題中的詞可以看出,美的品牌較好,質量不錯,且京東平臺不錯;而從第二個主題可以看出美的品牌安裝不錯;第三個主題中除了安裝還體現了加熱快這個優點。
而分析負面評論的三個主題,則三個主題明顯都跟安裝有關係(主題顯示其實很像是優勢,這應該跟ROSTCM6的情感分析有關,但通過觀察負面評價的原資料發現是蠻正常的,所以不知道是什麼情況……)。
所以美的品牌的主要優勢在於品牌優勢、質量好、加熱速度快等,而劣勢則主要在於安裝。

總結

文字分析、自然語言處理是非常龐大而且重要的知識點,肯定不能單憑這樣一個實戰就搞清楚,但通過這個實踐,對LDA主題模型、文字分析的整體流程以及python中所涉及到的程式包都有了一定了解,也算是一個不錯的收穫。
————————————————————————————————————
自此,關於《Python資料分析與資料探勘實戰》這本書的整理就結束了。