【python資料探勘課程】二十六.基於SnowNLP的豆瓣評論情感分析
這是《Python資料探勘課程》系列文章,前面很多文章都講解了分類、聚類演算法,而這篇文章主要講解如何呼叫SnowNLP庫實現情感分析,處理的物件是豆瓣《肖申克救贖》的評論文字。文章比較基礎,希望對你有所幫助,提供些思路,也是自己教學的內容。如果文章中存在錯誤或不足之處,還請海涵。同時,推薦大家閱讀我以前的文章瞭解其他知識。
目錄:
一.豆瓣評論資料抓取
1.審查網頁元素,獲取目標網站DOM樹結構
2.Selenium抓取《肖申克救贖》評論資訊
3.抓取前10頁評論並儲存至CSV檔案
二.情感分析預處理及詞雲顯示
三.SnowNLP情感分析
1.SnowNLP
2.中文分詞
3.常見功能
4.情感分析
四.SnowNLP情感分析例項
PSS:最近參加CSDN2018年部落格評選,希望您能投出寶貴的一票。我是59號,Eastmount,楊秀璋。投票地址:https://bss.csdn.net/m/topic/blog_star2018/index
前文參考:
【Python資料探勘課程】一.安裝Python及爬蟲入門介紹
【Python資料探勘課程】二.Kmeans聚類資料分析及Anaconda介紹
【Python資料探勘課程】三.Kmeans聚類程式碼實現、作業及優化
【Python資料探勘課程】四.決策樹DTC資料分析及鳶尾資料集分析
【Python資料探勘課程】五.線性迴歸知識及預測糖尿病例項
【Python資料探勘課程】六.Numpy、Pandas和Matplotlib包基礎知識
【Python資料探勘課程】七.PCA降維操作及subplot子圖繪製
【Python資料探勘課程】八.關聯規則挖掘及Apriori實現購物推薦
【Python資料探勘課程】九.迴歸模型LinearRegression簡單分析氧化物資料
【python資料探勘課程】十.Pandas、Matplotlib、PCA繪圖實用程式碼補充
【python資料探勘課程】十一.Pandas、Matplotlib結合SQL語句視覺化分析
【python資料探勘課程】十二.Pandas、Matplotlib結合SQL語句對比圖分析
【python資料探勘課程】十三.WordCloud詞雲配置過程及詞頻分析
【python資料探勘課程】十四.Scipy呼叫curve_fit實現曲線擬合
【python資料探勘課程】十五.Matplotlib呼叫imshow()函式繪製熱圖
【python資料探勘課程】十六.邏輯迴歸LogisticRegression分析鳶尾花資料
【python資料探勘課程】十七.社交網路Networkx庫分析人物關係(初識篇)
【python資料探勘課程】十八.線性迴歸及多項式迴歸分析四個案例分享
【python資料探勘課程】十九.鳶尾花資料集視覺化、線性迴歸、決策樹花樣分析
【python資料探勘課程】二十.KNN最近鄰分類演算法分析詳解及平衡秤TXT資料集讀取
【python資料探勘課程】二十一.樸素貝葉斯分類器詳解及中文文字輿情分析
【python資料探勘課程】二十二.Basemap地圖包安裝入門及基礎知識講解
【python資料探勘課程】二十三.時間序列金融資料預測及Pandas庫詳解
【python資料探勘課程】二十四.KMeans文字聚類分析互動百科語料
【python資料探勘課程】二十五.Matplotlib繪製帶主題及聚類類標的散點圖
一.豆瓣評論資料抓取
本文首先需要抓取豆瓣《肖申克救贖》電影的評論資訊,採用Selenium爬蟲實現。這裡不再詳細講解爬蟲的知識,僅簡單介紹。
1.審查網頁元素,獲取目標網站DOM樹結構
目標網址為:https://movie.douban.com/subject/1292052/comments?start=0&limit=0&sort=new_score&status=P
如下圖所示:
接著通過瀏覽器定位節點找到需要抓取內容的位置。
每一個評論都位於 < div class=“comment-item” > 中,定位內容包括:
(1) 使用者名稱及其超連結定位class為“avatar”節點下的超連結;
(2) 評論人數位於span標籤class為“comment-vote”中的第一個span;
(3) 使用者評分位於span標籤class為“comment-info”中第二個span;
(4) 短評論位於span標籤class為“short”。
<div class="comment-item" data-cid="477351">
<div class="avatar">
<a title="犀牛" href="https://www.douban.com/people/whiterhinoceros/">
...
</a>
</div>
<div class="comment">
<span class="comment-vote">
<span class="votes">10667</span>
...
</span>
<span class="comment-info">
...
<span class="allstar50 rating" title="力薦"></span>
<span class="comment-time " title="2005-10-28 00:28:07">
2005-10-28
</span>
</span>
</h3>
<p class="">
<span class="short">當年的奧斯卡頒獎禮上...</span>
</p>
</div>
</div>
2.Selenium抓取《肖申克救贖》評論資訊
Python程式碼如下所示,抓取了第一頁的評論資訊,這段程式碼重點是Selenium的定位方法,而下一部分程式碼重點是將前10頁評論抓取並儲存至CSV檔案中。
# coding=utf-8
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import selenium.webdriver.support.ui as ui
from selenium.webdriver.common.action_chains import ActionChains
import time
import re
import os
import csv
#開啟Firefox瀏覽器
driver = webdriver.Firefox()
i = 0
while i<1:
num = i*20
url = "https://movie.douban.com/subject/1292052/comments?start=" + str(num) +"&limit=20&sort=new_score&status=P"
print url
driver.get(url)
#使用者姓名 超連結
elem1 = driver.find_elements_by_xpath("//div[@class='avatar']/a")
for n in elem1:
print n.get_attribute("title"),
print n.get_attribute("href")
#使用者評分
elem2 = driver.find_elements_by_xpath("//span[@class='comment-info']/span[2]")
for n in elem2:
print n.get_attribute("class"),
print n.get_attribute("title")
#有用數
elem3 = driver.find_elements_by_xpath("//span[@class='comment-vote']/span[1]")
for n in elem3:
print n.text
#日期
elem4 = driver.find_elements_by_xpath("//span[@class='comment-time ']")
for n in elem4:
print n.text
#評論
elem5 = driver.find_elements_by_xpath("//span[@class='short']")
for n in elem5:
print n.text
i = i + 1
輸出結果如下所示:
>>>
犀牛 https://www.douban.com/people/whiterhinoceros/
kingfish https://www.douban.com/people/kingfish/
Eve|Classified https://www.douban.com/people/eve42/
...
allstar50 rating 力薦
allstar40 rating 推薦
allstar30 rating 還行
...
10667
19919
4842
...
2005-10-28
2006-03-22
2008-05-09
...
當年的奧斯卡頒獎禮上,被如日中天的《阿甘正傳》...
不需要女主角的好電影
有種鳥是關不住的.
...
>>>
3.抓取前10頁評論並儲存至CSV檔案
完整程式碼如下所示:
# coding=utf-8
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import selenium.webdriver.support.ui as ui
from selenium.webdriver.common.action_chains import ActionChains
import time
import re
import os
import csv
import codecs
#寫入檔案
c = open("test-douban.csv", "wb") #寫檔案
c.write(codecs.BOM_UTF8) #防止亂碼
writer = csv.writer(c) #寫入物件
writer.writerow(['序號','使用者名稱','連結','評分','評分標題','有用數','日期','評論'])
#開啟Firefox瀏覽器 設定等待載入時間 訪問URL
driver = webdriver.Firefox()
i = 0
while i<1:
num = i*20
url = "https://movie.douban.com/subject/1292052/comments?start=" + str(num) +"&limit=20&sort=new_score&status=P"
print url
driver.get(url)
#使用者姓名 超連結
elem1 = driver.find_elements_by_xpath("//div[@class='avatar']/a")
#使用者評分
elem2 = driver.find_elements_by_xpath("//span[@class='comment-info']/span[2]")
#有用數
elem3 = driver.find_elements_by_xpath("//span[@class='comment-vote']/span[1]")
#日期
elem4 = driver.find_elements_by_xpath("//span[@class='comment-time ']")
#評論
elem5 = driver.find_elements_by_xpath("//span[@class='short']")
#迴圈寫入20行評價
tlist = []
k = 0
while k<20:
#序號
num = i*20+k+1
print num
#使用者姓名
name = elem1[k].get_attribute("title").encode('utf-8')
print name
#超連結
href = elem1[k].get_attribute("href").encode('utf-8')
print href
#使用者評分及內容
score = elem2[k].get_attribute("class").encode('utf-8')
print score
content = elem2[k].get_attribute("title").encode('utf-8')
print content
#有用數
useful = elem3[k].text.encode('utf-8')
print useful
#日期
date = elem4[k].text.encode('utf-8')
#評論
shortcon = elem5[k].text.encode('utf-8')
print shortcon
#寫入檔案
templist = []
templist.append(num)
templist.append(name)
templist.append(href)
templist.append(score)
templist.append(content)
templist.append(useful)
templist.append(date)
templist.append(shortcon)
writer.writerow(templist)
k = k + 1
i = i + 1
c.close()
執行結果如下圖所示:
二.情感分析預處理及詞雲顯示
情感分析的基本流程如下圖所示,通常包括:
1.自定義爬蟲抓取文字資訊;
2.使用Jieba工具進行中文分詞、詞性標註;
3.定義情感詞典提取每行文字的情感詞;
4.通過情感詞構建情感矩陣,並計算情感分數;
5.結果評估,包括將情感分數置於0.5到-0.5之間,並視覺化顯示。
本文將抓取的200條《肖申克救贖》評論資訊複製至TXT檔案中 ,每一行為一條評論,再對其進行中文分詞處理。注意,這裡僅僅獲取序號1-200的情感分數,而其他情感分析可以進行時間對比、主題對比等,這裡作者也爬取了完整資訊,而不僅僅是評論,就為了方便讀者實驗。其方法和此篇文章類似,希望讀者學會舉一反三。
data.txt
下面這段程式碼主要講解Python呼叫Jieba工具進行分詞,然後通過WordCloud庫實現詞雲顯示,關鍵詞出現越多顯示越大,比如“希望”、“自由”、“電影”等。
# -*- coding: utf-8 -*-
import jieba
import sys
import matplotlib.pyplot as plt
from wordcloud import WordCloud
#開啟本體TXT檔案
text = open('data.txt').read()
print type(text)
#結巴分詞 cut_all=True 設定為精準模式
wordlist = jieba.cut(text, cut_all = False)
#使用空格連線 進行中文分詞
wl_space_split = " ".join(wordlist)
print wl_space_split
#對分詞後的文字生成詞雲
my_wordcloud = WordCloud().generate(wl_space_split)
#顯示詞雲圖
plt.imshow(my_wordcloud)
#是否顯示x軸、y軸下標
plt.axis("off")
plt.show()
分詞過程如下圖所示,通過空格連線。
三.SnowNLP情感分析
1.SnowNLP
SnowNLP是一個常用的Python文字分析庫,是受到TextBlob啟發而發明的。由於當前自然語言處理庫基本都是針對英文的,而中文沒有空格分割特徵詞,Python做中文文字挖掘較難,後續開發了一些針對中文處理的庫,例如SnowNLP、Jieba、BosonNLP等。注意SnowNLP處理的是unicode編碼,所以使用時請自行decode成unicode。
Snownlp主要功能包括:
- 中文分詞(演算法是Character-Based Generative Model)
- 詞性標註(原理是TnT、3-gram 隱馬)
- 情感分析
- 文字分類(原理是樸素貝葉斯)
- 轉換拼音、繁體轉簡體
- 提取文字關鍵詞(原理是TextRank)
- 提取摘要(原理是TextRank)、分割句子
- 文字相似(原理是BM25)
推薦官網給大家學習。
安裝和其他庫一樣,使用pip安裝即可。
pip install snownlp
2.中文分詞
下面是最簡單的例項,使用SnowNLP進行中文分詞,同時比較了SnowNLP和Jieba庫的分詞效果。
# -*- coding: utf-8 -*-
from snownlp import SnowNLP
s1 = SnowNLP(u"這本書質量真不太好!")
print("SnowNLP:")
print(" ".join(s1.words))
import jieba
s2 = jieba.cut(u"這本書質量真不太好!", cut_all=False)
print("jieba:")
print(" ".join(s2))
輸出結果如下所示:
總體感覺是SnowNLP分詞速度比較慢,準確度較低,比如“不太好”這個片語,但也不影響我們後續的情感分析。
3.常見功能
程式碼如下:
# -*- coding: utf-8 -*-
from snownlp import SnowNLP
s = SnowNLP(u"這本書質量真不太好!")
print(u"\n中文分詞:")
print( " ".join(s.words))
print(u"\n詞性標註:")
print(s.tags)
for k in s.tags:
print(k)
print(u"\n情感分數:")
print(s.sentiments)
print(u"\n轉換拼音:")
print(s.pinyin)
print(u"\n輸出前4個關鍵詞:")
print(s.keywords(4))
for k in s.keywords(4):
print(k)
print(u"\n輸出關鍵句子:")
print(s.summary(1))
for k in s.summary(1):
print(k)
print(u"\n輸出tf和idf:")
print(s.tf)
print(s.idf)
n = SnowNLP(u'「繁體字」「繁體中文」的叫法在臺灣亦很常見。')
print(u"\n繁簡體轉換:")
print(n.han)
s.words 輸出分詞後的結果,詞性標註主要通過 s.tags,s.sentiments 計算情感分數,s.pinyin 轉換為拼音,s.keywords(4) 提取4個關鍵詞,s.summary(1) 輸出一個關鍵句子,s.tf 計算TF值(頻率),s.idf 計算IDF值(倒文件)。
輸出結果如下所示:
>>>
中文分詞:
這 本書 質量 真 不 太 好 !
詞性標註:
[(u'\u8fd9', u'r'), (u'\u672c\u4e66', u'r'), (u'\u8d28\u91cf', u'n'),
(u'\u771f', u'd'), (u'\u4e0d', u'd'), (u'\u592a', u'd'),
(u'\u597d', u'a'), (u'\uff01', u'w')]
(u'\u8fd9', u'r')
(u'\u672c\u4e66', u'r')
(u'\u8d28\u91cf', u'n')
(u'\u771f', u'd')
(u'\u4e0d', u'd')
(u'\u592a', u'd')
(u'\u597d', u'a')
(u'\uff01', u'w')
情感分數:
0.420002029202
轉換拼音:
[u'zhe', u'ben', u'shu', u'zhi', u'liang', u'zhen', u'bu', u'tai', u'hao', u'\uff01']
輸出前4個關鍵詞:
[u'\u592a', u'\u4e0d', u'\u8d28\u91cf', u'\u771f']
太
不
質量
真
輸出關鍵句子:
[u'\u8fd9\u672c\u4e66\u8d28\u91cf\u771f\u4e0d\u592a\u597d']
這本書質量真不太好
輸出tf和idf:
[{u'\u8fd9': 1}, {u'\u672c': 1}, {u'\u4e66': 1},
{u'\u8d28': 1}, {u'\u91cf': 1}, {u'\u771f': 1},
{u'\u4e0d': 1}, {u'\u592a': 1}, {u'\u597d': 1}, {u'\uff01': 1}]
{u'\uff01': 1.845826690498331, u'\u4e66': 1.845826690498331, u'\u8d28': 1.845826690498331,
u'\u592a': 1.845826690498331, u'\u4e0d': 1.845826690498331, u'\u672c': 1.845826690498331,
u'\u91cf': 1.845826690498331, u'\u8fd9': 1.845826690498331, u'\u597d': 1.845826690498331, u'\u771f': 1.845826690498331}
繁簡體轉換:
「繁體字」「繁體中文」的叫法在臺灣亦很常見。
>>>
同樣可以進行文字相似度計算,程式碼參考下圖所示:
4.情感分析
SnowNLP情感分析也是基於情感詞典實現的,其簡單的將文字分為兩類,積極和消極,返回值為情緒的概率,越接近1為積極,接近0為消極。其原理參考zhiyong_will大神和鄧旭東老師的文章,也強烈推薦大家學習。地址:
情感分析——深入snownlp原理和實踐
自然語言處理庫之snowNLP
下面簡單給出一個情感分析的例子:
# -*- coding: utf-8 -*-
from snownlp import SnowNLP
s1 = SnowNLP(u"我今天很開心")
print(u"s1情感分數:")
print(s1.sentiments)
s2 = SnowNLP(u"我今天很沮喪")
print(u"s2情感分數:")
print(s2.sentiments)
s3 = SnowNLP(u"大傻瓜,你脾氣真差,動不動就打人")
print(u"s3情感分數:")
print(s3.sentiments)
輸出結果如下所示,當負面情感特徵詞越多,比如“傻瓜”、“差”、“打人”等,分數就會很低,同樣當正免情感詞多分數就高。
s1情感分數:
0.84204018979
s2情感分數:
0.648537121839
s3情感分數:
0.0533215596706
而在真實專案中,通常需要根據實際的資料重新訓練情感分析的模型,匯入正面樣本和負面樣本,再訓練新模型。
sentiment.train(’./neg.txt’, ‘./pos.txt’)
sentiment.save(‘sentiment.marshal’)
四.SnowNLP情感分析例項
下面的程式碼就是對爬取的豆瓣電影《肖申克的救贖》評論進行情感分析。
1.情感各分數段出現頻率
首先統計各情感分數段出現的評率並繪製對應的柱狀圖,程式碼如下:
# -*- coding: utf-8 -*-
from snownlp import SnowNLP
import codecs
import os
source = open("data.txt","r")
line = source.readlines()
sentimentslist = []
for i in line:
s = SnowNLP(i.decode("utf-8"))
print(s.sentiments)
sentimentslist.append(s.sentiments)
import matplotlib.pyplot as plt
import numpy as np
plt.hist(sentimentslist, bins = np.arange(0, 1, 0.01), facecolor = 'g')
plt.xlabel('Sentiments Probability')
plt.ylabel('Quantity')
plt.title('Analysis of Sentiments')
plt.show()
輸出結果如下圖所示:
對應的分數如下:
>>>
1.0
0.945862922561
1.0
0.979234476526
0.750839957904
0.491062087241
0.936143577844
0.641496807331
...
2.情感波動分析
接下來分析200條評論,每條評論的波動情況,程式碼如下所示:
# -*- coding: utf-8 -*-
from snownlp import SnowNLP
import codecs
import os
source = open("data.txt","r")
line = source.readlines()
sentimentslist = []
for i in line:
s = SnowNLP(i.decode("utf-8"))
print(s.sentiments)
sentimentslist.append(s.sentiments)
import matplotlib.pyplot as plt
import numpy as np
plt.plot(np.arange(0, 200, 1), sentimentslist, 'k-')
plt.xlabel('Number')
plt.ylabel('Sentiment')
plt.title('Analysis of Sentiments')
plt.show()
輸出結果如下所示,呈現一條曲線,因為抓取的評論基本都是好評,所以分數基本接近於1.0,而真實分析過程中存在好評、中評和差評,曲線更加規律。
同時,在做情感分析的時候,我看到很多論文都是將情感區間從[0, 1.0]轉換為[-0.5, 0.5],這樣的曲線更加好看,位於0以上的是積極評論,反之消極評論。修改程式碼如下:
# -*- coding: utf-8 -*-
from snownlp import SnowNLP
import codecs
import os
#獲取情感分數
source = open("data.txt","r")
line = source.readlines()
sentimentslist = []
for i in line:
s = SnowNLP(i.decode("utf-8"))
print(s.sentiments)
sentimentslist.append(s.sentiments)
#區間轉換為[-0.5, 0.5]
result = []
i = 0
while i<len(sentimentslist):
result.append(sentimentslist[i]-0.5)
i = i + 1
#視覺化畫圖
import matplotlib.pyplot as plt
import numpy as np
plt.plot(np.arange(0, 200, 1), result, 'k-')
plt.xlabel('Number')
plt.ylabel('Sentiment')
plt.title('Analysis of Sentiments')
plt.show()
繪製圖形如下所示:
3.建議
這裡簡單補充五個建議,具體如下:
(1)情感分析通常需要和評論時間結合起來,並進行輿情預測等,建議讀者嘗試將時間結合。比如王樹義老師的文章《基於情感分類的競爭企業新聞文字主題挖掘》。
(2)情感分析也是可以進行評價的,我們前面抓取的分為5星評分,假設0-0.2位一星,0.2-0.4位二星,0.4-0.6為三星,0.6-0.8為四星,0.8-1.0為五星,這樣我們可以計算它的準確率,召回率,F值,從而評論我的演算法好壞。
(3)作者還有很多情感分析結合冪率分佈的知識,因為需要寫文章,這裡暫時不進行分享,但是這篇基礎文章對初學者仍然有一定的幫助。
(4)BosonNLP也是一個比較不錯的情感分析包,建議感興趣的讀者學習,它提供了相關的詞典,如下:https://bosonnlp.com/dev/resource。
(5)讀者如果不太擅長寫程式碼,可以嘗試使用情感分析系統。http://ictclas.nlpir.org/nlpir/
比如分析評論:
當年的奧斯卡頒獎禮上,被如日中天的《阿甘正傳》掩蓋了它的光彩,而隨著時間的推移,這部電影在越來越多的人們心中的地位已超越了《阿甘》。每當現實令我疲憊得產生無力感,翻出這張碟,就重獲力量。毫無疑問,本片位列男人必看的電影前三名!回顧那一段經典臺詞:“有的人的羽翼是如此光輝,即使世界上最黑暗的牢獄,也無法長久地將他圍困!”
基礎性文章,希望對大家有所幫助,不喜勿噴,2018年馬上結束,祝大家新年快樂,學到更多知識,認識這個大千世界。也推薦下我的年終總結文章。
2018年總結:向死而生,為愛而活——憶程式設計青椒的戎馬歲月
(By:Eastmount 2018-12-21 中午12點 http://blog.csdn.net/eastmount/ )
相關文章
- 【python資料探勘課程】二十七.基於SVM分類器的紅酒資料分析Python
- [譯] 基於評論的機器學習線上課程排名機器學習
- 【python資料探勘課程】二十四.KMeans文字聚類分析互動百科語料Python聚類
- 《資料探勘導論》實驗課——實驗四、資料探勘之KNN,Naive BayesKNNAI
- 《資料分析與資料探勘》--天津大學公開課
- 基於知識引入的情感分析
- snownlp類庫(中文情感分析)原始碼註釋及使用原始碼
- Python爬取豆瓣電影的短評資料並進行詞雲分析處理Python
- 萌新向Python資料分析及資料探勘 前言Python
- 【python資料探勘課程】二十三.時間序列金融資料預測及Pandas庫詳解Python
- 資料探勘的過程有哪些
- Python——各種方法的使用(儘量每天更新)——from(資料探勘課)Python
- 20行程式碼實現電影評論情感分析行程
- [譯] 基於 Python 的圖論和網路分析Python圖論
- 《資料探勘導論》讀後感
- 【python資料探勘課程】二十五.Matplotlib繪製帶主題及聚類類標的散點圖Python聚類
- 基於Python豆瓣自動化測試【2】Python
- 基於python的大資料分析-資料處理(程式碼實戰)Python大資料
- 基於python的大資料分析實戰學習筆記-pandas(資料分析包)Python大資料筆記
- 淺談大資料、資料分析、資料探勘的區別!大資料
- 基於python的大資料分析-pandas資料儲存(程式碼實戰)Python大資料
- 基於python的大資料分析-pandas資料讀取(程式碼實戰)Python大資料
- 【python爬蟲案例】利用python爬取豆瓣電影TOP250評分排行資料!Python爬蟲
- 【資料視覺化】周杰倫新歌《Mojito》豆瓣短評資料視覺化
- 基於GitHub Issues的評論系統--gitmentGithub
- Python基礎課程筆記5Python筆記
- 基於Python的效能分析Python
- 實驗課程名稱:資料庫系統概論資料庫
- 如何用Python做情感分析?Python
- 資料探勘與資料分析的主要區別是什麼
- 基於 Amazon SageMaker 構建細粒度情感分析應用
- 基於 Spark 的資料分析實踐Spark
- logminer進行資料探勘分析測試
- 資料分析與資料探勘 - 04科學計算
- Yahoo前任資料官:資料探勘與分析技巧(下)IF
- 中科院“大資料探勘和分析技術實戰”公開課實訓大資料
- 基於python的大資料分析實戰學習筆記-AnacondaPython大資料筆記
- 關於資料探勘你想了解的都在這