網(wǎng)易云音樂評論抓取實驗(2)樸素貝葉斯入門:通過概率對評論情緒分類

上回網(wǎng)易云音樂評論抓取實驗(1)接口獲取說到我們已經(jīng)可以結(jié)合爬蟲拿到一首歌下面的所有評論了丧失,然而針對這些評論我們又能做些什么分析呢?由于我自己平時魔性洗腦迄委、抒情古風啥的都在聽谋梭,下面的評論也是哈哈哈表白編段子的都有互广,所以就在想能不能把評論的情緒做個分類踪栋?先看看實驗結(jié)果吧焙格。

實驗效果

輸入了三個評論,判斷其屬于兩首歌的概率從而確定歸屬夷都。(兩首歌分別是雙笙 達拉崩吧雙笙 我的一個道姑朋友

想法由來

把評論爬到之后首先想的就是先做個詞云看看這首歌的評論大致是什么畫風眷唉,比如《權(quán)御天下》

權(quán)御天下

(呃…這個大哭是emoji里面的笑哭的表情,大家不要誤會了)

就是這個表情

好幾個大大的 笑哭 拍到臉上囤官,就知道評論區(qū)應該比較歡樂啦~
也就是說冬阳,歡樂的歌曲里面出現(xiàn)體現(xiàn)歡樂情緒的評論會更多一些,悲傷的同理党饮。如果從里面隨機選評論出來肝陪,我們能知道這個評論屬于哪首歌嗎?

雙笙《達拉崩吧》
雙笙 《我的一個道姑朋友》

這篇文章的例子是以同一個歌手的兩首不同風格的歌作為樣本刑顺,如果樣本是兩個不同音樂情緒的專輯氯窍,那么是不是就可以根據(jù)評論分出一首歌是快樂還是憂傷呢?

樸素貝葉斯

當然先是到處查啦蹲堂,在這里我首先接觸到的是這篇文章Python做文本情感分析之情感極性分析 - 簡書狼讨,提到了兩種方法,第一種根據(jù)詞匯分類判斷柒竞,第二種基于機器學習暫時還看不懂- -這不是看不懂機器學習嘛政供,就去看了參考書機器學習實戰(zhàn) ,發(fā)現(xiàn)這個樸素貝葉斯很適合這個分析朽基,因為它舉的例子是垃圾郵件分類布隔!感覺和評論分類很像啊踩晶!
其核心為一個公式:

貝葉斯公式

Ci(Class)代表第i個分類执泰,向量w(words)代表一句話中的詞語,含義為:
出現(xiàn)向量w(w1,w2,w3,…)組成的一句話的前提下渡蜻,
它屬于類別*i*的概率=在類別*i*中出現(xiàn)這句話的概率*任一句子屬于類別*i*的概率/出現(xiàn)這句話的概率
而我們需要比較p(c0|w) p(c1|w)誰更大术吝,所以可以忽略這個相同的分母p(w),代碼中我設定兩類均使用2000條評論作為樣本茸苇,所以p(c)也相等可以忽略啦排苍。

“喂喂喂,你快別bb了学密,你說的啥啊淘衙,看不懂!D迥骸彤守!”

咳咳…我也一看到公式就發(fā)懵…那就直觀點說毯侦。來看看我們是如何區(qū)分的吧,如果看到“哈哈哈哈哈哈”什么的具垫,那就是第一首沒跑了侈离;“道姑”“道長”什么的,那就會是第二首啦筝蚕。也就是特定詞匯兩首歌中出現(xiàn)的概率不同卦碾。
后續(xù)就抄一抄書了。

“樸素”的含義

代碼實現(xiàn)

上面提到起宽,我們只需搞定p(w|c)就行了洲胖,也就是在各個分類下各個詞出現(xiàn)的概率,統(tǒng)計各個詞出現(xiàn)的次數(shù)坯沪,再除以一共有多少個詞就好啦绿映!……嗯,我真想給自己一巴掌屏箍,說的真輕松呢绘梦。

統(tǒng)計出現(xiàn)了哪些詞

把所有的評論的詞語都扔到集合里,就是所有用到的詞了赴魁!但是我們?yōu)榱吮阌诮y(tǒng)計出現(xiàn)的次數(shù),還是得用有序的列表啊钝诚。大概就是這樣一種表示方法:

使用向量表示句子

所以代碼的開頭是這樣的颖御,用來提取爬蟲數(shù)據(jù),轉(zhuǎn)換為詞語凝颇,并構(gòu)造出總的詞語列表出來:

import jieba
from numpy import array
from numpy import log
import numpy
import copy
class nativebayes:
    def load(self,songtype):
        with open('%s_comment_train.txt'%str(songtype),encoding='utf-8') as f:
            comments=f.readlines()
        comments_list=[]
        for i in comments:
           comments_list .append(jieba.lcut(i))
        return comments_list

    #將所有出現(xiàn)過的詞語轉(zhuǎn)為列表

    def createwordslist(self,comments_list):
        wordsset=set([])
        for words in comments_list:
            wordsset=wordsset|set(words)
        #轉(zhuǎn)換為有序列表
        return list(wordsset)

統(tǒng)計出現(xiàn)的概率

一張圖說明如何操作

計算示意圖

把每個評論的向量加起來就是出現(xiàn)次數(shù)了潘拱,再除以總的字數(shù)就是每個詞語出現(xiàn)的概率了啦。
首先是轉(zhuǎn)換為向量表示

    def words2vec(self,wordslist,comment):
        returnVec=[0]*len(wordslist)
        #在之前已經(jīng)被切分好了
        for word in comment:
            if word in wordslist:
                #將評論中出現(xiàn)的詞在Vector中標記
                returnVec[wordslist.index(word)]=1
        return returnVec

這里是以是否出現(xiàn)作為特征拧略,為詞集模型(set-of-words)芦岂,如果再細一點,以出現(xiàn)次數(shù)作為特征的話垫蛆,則為詞袋模型(bag-of-words)禽最。我想評論里可能存在“啊啊啊啊二狗二狗二狗!8し埂川无!我愛你我!愛虑乖!你懦趋!”這種重復就沒什么意思,所以就用的詞集模型疹味。
然后是計算概率

    #計算p(c1),p(w|c1)
    def trainNB(self,trainMatrix):
        #因為均統(tǒng)計1000條評論仅叫,所以概率相等
        p_class=0.5
        #Class中詞語的總數(shù) 即一個wordslist的長度
        numwords=len(trainMatrix[0])
        words_statics=numpy.ones(numwords)
        words_totalnum=0.0
        for wordslist in trainMatrix:
            #將各個詞出現(xiàn)的次數(shù)累加
            words_statics+=wordslist
            #統(tǒng)計評論中總的詞數(shù)
            words_totalnum+=sum(wordslist)
            p_vect=log(words_statics/words_totalnum)
        return p_class,p_vect

注意帜篇!注意!這里為什么出現(xiàn)log呢诫咱?先看看如果不加log運行過程中p和總詞列表是怎樣的吧坠狡。

詞語與對應概率

各個詞出現(xiàn)的概率p很小,如果統(tǒng)計的文本(上面的圖片僅僅是抓了50條評論得出的結(jié)果)特別大的話遂跟,最終的乘積p用float64儲存也會約等于0逃沿,即乘積過小,約等于0幻锁。
所以書上的解決方式是把乘積轉(zhuǎn)為求和凯亮,即取個對數(shù),反正是比較大小嘛哄尔,取對數(shù)不會影響假消。
還有一個地方!為什么統(tǒng)計的變量初始化是words_statics=numpy.ones(numwords)岭接,都要從1開始呢富拗?
這是因為對種類0來說,種類1的詞不一定會出現(xiàn)(比如種類1中有個人發(fā)了個啥無關痛癢的“特朗普”)鸣戴,所以樣本采集之后啃沪,P(特朗普|c0)=0,然后我來測試一條新的評論窄锅,恰好出現(xiàn)了這個詞创千,就會導致種類0的最終乘積為0,從而僅僅因為一個詞導致其最后判定為種類1入偷,有失公允追驴。所以可以把所有詞出現(xiàn)次數(shù)初始化為1,也不會影響最終結(jié)果的裁定疏之。

測試

針對兩首歌各寫一個評論殿雪,再寫一個無法分類的評論,來看看測試效果吧:

if __name__=='__main__':
    bayestest=nativebayes()
    totalcomments=[]
    #這里用append 是因為totalcomment[0] [1]分別為兩種評論锋爪,均為列表
    totalcomments.append(bayestest.load(0))
    totalcomments.append(bayestest.load(1))
    totalcomments_a=copy.deepcopy(totalcomments[0])
    #這里用extend是因為totalcomments_a全為評論
    totalcomments_a.extend(totalcomments[1])
    wordslist=bayestest.createwordslist(totalcomments_a)
    p=[0,0]
    p_wv=[[],[]]
    for i in range(0,2):
        wordslist_matrix=[]
        for comment in totalcomments[i]:
            #將每個評論轉(zhuǎn)換為詞組出現(xiàn)的向量形式丙曙,并加入總的矩陣中用做統(tǒng)計
            wordslist_matrix.append(bayestest.words2vec(wordslist,comment))
        p[i],p_wv[i]=bayestest.trainNB(array(wordslist_matrix))
        # print(p_wv[i])
    test_commentV_0=bayestest.words2vec(wordslist,jieba.lcut('哈哈哈笑死我了'))
    test_commentV_1=bayestest.words2vec(wordslist,jieba.lcut('劍三的歌!很喜歡的故事几缭!'))
    test_commentV_2=bayestest.words2vec(wordslist,jieba.lcut('雙笙的歌真好聽河泳!'))
    bayestest.getP(test_commentV_0,p_wv[0],p_wv[1])
    bayestest.getP(test_commentV_1,p_wv[0],p_wv[1])
    bayestest.getP(test_commentV_2,p_wv[0],p_wv[1])


相比于模棱兩可的第三條雙笙的歌真好聽來說,第一條評論哈哈哈笑死我了明顯P0>P1年栓,屬于第一首歌的情緒風格拆挥;第二條針對歌曲來源的評論劍三的歌!很喜歡的故事!P1>P0纸兔,屬于第二首歌的情緒風格惰瓜。
咩哈哈哈!表現(xiàn)還挺好的呢汉矿!

總結(jié)

之前看機器實戰(zhàn)的書也看過一會兒崎坊,不過這是我第一次實際接觸機器學習,果然有實際需求的時候才最有動力學下去洲拇。這篇文章也是馬馬虎虎完成的奈揍,可以從中看出我有很多地方都對實際進行了簡化,包括P1=P2=0.5等等赋续,有何不當?shù)牡胤侥泻玻埓蠹叶喽嘀附蘜_^,另外感覺NLP這一塊挺有趣的纽乱,如果我有一個人足夠多的評論數(shù)據(jù)蛾绎,我是不是能模仿他說話呢?后續(xù)準備學習一下這篇文章問答機器人的Python分類器鸦列。

代碼地址(包括評論爬取租冠、已經(jīng)爬好的數(shù)據(jù)、詞云薯嗤、樸素貝葉斯)
Github 163music

最后感謝大家的閱讀顽爹,如果對你有幫助,不妨點個喜歡吧应民。
往期批量下載電影排行榜的系列文章:
(番外篇)Python操縱網(wǎng)盤客戶端批量離線下載小電影
Python實現(xiàn)電影排行榜自動網(wǎng)盤下載(4)Cookies免登錄+抓包下載
Python實現(xiàn)電影排行榜自動網(wǎng)盤下載(3)Selenium離線下載
Python實現(xiàn)電影排行榜自動網(wǎng)盤下載(2)Scrapy深入 “打包員”“快遞員”
Python實現(xiàn)電影排行榜自動網(wǎng)盤下載(1)Scrapy爬蟲框架
Python實現(xiàn)電影排行榜自動網(wǎng)盤下載(0)簡介

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末话原,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子诲锹,更是在濱河造成了極大的恐慌,老刑警劉巖涉馅,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件归园,死亡現(xiàn)場離奇詭異,居然都是意外死亡稚矿,警方通過查閱死者的電腦和手機庸诱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來晤揣,“玉大人桥爽,你說我怎么就攤上這事∶潦叮” “怎么了钠四?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我缀去,道長侣灶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任缕碎,我火速辦了婚禮褥影,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘咏雌。我一直安慰自己凡怎,他們只是感情好,可當我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布赊抖。 她就那樣靜靜地躺著统倒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪熏迹。 梳的紋絲不亂的頭發(fā)上檐薯,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天,我揣著相機與錄音注暗,去河邊找鬼坛缕。 笑死,一個胖子當著我的面吹牛捆昏,可吹牛的內(nèi)容都是我干的赚楚。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼骗卜,長吁一口氣:“原來是場噩夢啊……” “哼宠页!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起寇仓,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤举户,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后遍烦,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體俭嘁,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年服猪,在試婚紗的時候發(fā)現(xiàn)自己被綠了供填。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡罢猪,死狀恐怖近她,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情膳帕,我是刑警寧澤粘捎,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響晌端,放射性物質(zhì)發(fā)生泄漏捅暴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一咧纠、第九天 我趴在偏房一處隱蔽的房頂上張望蓬痒。 院中可真熱鬧,春花似錦漆羔、人聲如沸梧奢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽亲轨。三九已至,卻和暖如春鸟顺,著一層夾襖步出監(jiān)牢的瞬間惦蚊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工讯嫂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蹦锋,地道東北人。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓欧芽,卻偏偏與公主長得像莉掂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子千扔,可洞房花燭夜當晚...
    茶點故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容