用python實(shí)現(xiàn)文本情感分析

注:本文轉(zhuǎn)載自知乎專欄

原文鏈接:https://zhuanlan.zhihu.com/p/23225934

情感分析就是分析一句話說(shuō)得是很主觀還是客觀描述赴邻,分析這句話表達(dá)的是積極的情緒還是消極的情緒。

原理

比如這么一句話:“這手機(jī)的畫面極好奸焙,操作也比較流暢彤敛。不過(guò)拍照真的太爛了!系統(tǒng)也不好玄糟“乐龋”

① 情感詞

要分析一句話是積極的還是消極的逢并,最簡(jiǎn)單最基礎(chǔ)的方法就是找出句子里面的情感詞砍聊,積極的情感詞比如:贊贰军,好,順手灶伊,華麗等寒跳,消極情感詞比如:差童太,爛胸完,壞,坑爹等爆惧。出現(xiàn)一個(gè)積極詞就+1锨能,出現(xiàn)一個(gè)消極詞就-1。
里面就有“好”熄阻,“流暢”兩個(gè)積極情感詞倔约,“爛”一個(gè)消極情感詞浸剩。那它的情感分值就是1+1-1+1=2. 很明顯這個(gè)分值是不合理的,下面一步步修改它吏恭。

② 程度詞

“好”袖扛,“流暢”和‘爛“前面都有一個(gè)程度修飾詞十籍〈浇福”極好“就比”較好“或者”好“的情感更強(qiáng)盏筐,”太爛“也比”有點(diǎn)爛“情感強(qiáng)得多。所以需要在找到情感詞后往前找一下有沒(méi)有程度修飾界牡,并給不同的程度一個(gè)權(quán)值漾抬。比如”極“纳令,”無(wú)比“,”太“就要把情感分值4圈匆,”較“捏雌,”還算“就情感分值2,”只算“纬傲,”僅僅“這些就0.5了窘奏。那么這句話的情感分值就是:41+12-14+1=3着裹。

③ 感嘆號(hào)

可以發(fā)現(xiàn)太爛了后面有感嘆號(hào),嘆號(hào)意味著情感強(qiáng)烈摔竿。因此發(fā)現(xiàn)嘆號(hào)可以為情感值+2. 那么這句話的情感分值就變成了:41+12-1*4-2+1 = 1

④ 否定詞

明眼人一眼就看出最后面那個(gè)”好“并不是表示”好“少孝,因?yàn)榍懊孢€有一個(gè)”不“字。所以在找到情感詞的時(shí)候袁翁,需要往前找否定詞。比如”不“柄驻,”不能“這些詞焙压。而且還要數(shù)這些否定詞出現(xiàn)的次數(shù)涯曲,如果是單數(shù),情感分值就-1拨黔,但如果是偶數(shù)傲武,那情感就沒(méi)有反轉(zhuǎn)揪利,還是1狠持。在這句話里面,可以看出”好“前面只有一個(gè)”不“甜刻,所以”好“的情感值應(yīng)該反轉(zhuǎn)正勒,-1章贞。
因此這句話的準(zhǔn)確情感分值是:4
1+12-14-2+1*-1 = -1

⑤ 積極和消極分開(kāi)來(lái)

再接下來(lái),很明顯就可以看出蜕径,這句話里面有褒有貶败京,不能用一個(gè)分值來(lái)表示它的情感傾向赡麦。而且這個(gè)權(quán)值的設(shè)置也會(huì)影響最終的情感分值帕识,敏感度太高了遂铡。因此對(duì)這句話的最終的正確的處理忧便,是得出這句話的一個(gè)積極分值,一個(gè)消極分值(這樣消極分值也是正數(shù)超歌,無(wú)需使用負(fù)數(shù)了)蒂教。它們同時(shí)代表了這句話的情感傾向凝垛。所以這句評(píng)論應(yīng)該是”積極分值:6,消極分值:7炭分。

⑥ 以分句的情感為基礎(chǔ)

再仔細(xì)一步剑肯,詳細(xì)一點(diǎn),一條評(píng)論的情感分值是由不同的分句加起來(lái)的呀忧,因此要得到一條評(píng)論的情感分值而账,就要先計(jì)算出評(píng)論中每個(gè)句子的情感分值因篇。這條例子評(píng)論有四個(gè)分句惜犀,因此其結(jié)構(gòu)如下([積極分值, 消極分值]):[[4, 0], [2, 0], [0, 6], [0, 1]] 。
以上就是使用情感詞典來(lái)進(jìn)行情感分析的主要流程了汽烦,算法的設(shè)計(jì)也會(huì)按照這個(gè)思路來(lái)實(shí)現(xiàn)莉御。

算法設(shè)計(jì)

第一步:讀取評(píng)論數(shù)據(jù)怨咪,對(duì)評(píng)論進(jìn)行分句。
第二步:查找對(duì)分句的情感詞煮岁,記錄積極還是消極,以及位置冶伞。
第三步:往情感詞前查找程度詞响禽,找到就停止搜尋荚醒。為程度詞設(shè)權(quán)值,乘以情感值侯繁。
第四步:往情感詞前查找否定詞巫击,找完全部否定詞精续,若數(shù)量為奇數(shù)粹懒,乘以-1凫乖,若為偶數(shù),乘以1删掀。
第五步:判斷分句結(jié)尾是否有感嘆號(hào)导街,有嘆號(hào)則往前尋找情感詞搬瑰,有則相應(yīng)的情感值+2控硼。
第六步:計(jì)算完一條評(píng)論所有分句的情感值卡乾,用數(shù)組(list)記錄起來(lái)缚够。
第七步:計(jì)算并記錄所有評(píng)論的情感值谍椅。
第八步:通過(guò)分句計(jì)算每條評(píng)論的積極情感均值,消極情感均值埂伦,積極情感方差思恐,消極情感方差胀莹。

實(shí)戰(zhàn)

這里是作者參考已有代碼,結(jié)合自己需要媳否,對(duì)代碼進(jìn)行了簡(jiǎn)單的修改篱竭。本腳本運(yùn)行環(huán)境是python3.5 步绸,使用2.x的盆友們見(jiàn)諒瓤介。

import jieba
import numpy as np

#打開(kāi)詞典文件,返回列表
def open_dict(Dict = 'hahah', path=r'/Users/apple888/PycharmProjects/Textming/Sent_Dict/Hownet/'):
    path = path + '%s.txt' % Dict
    dictionary = open(path, 'r', encoding='utf-8')
    dict = []
    for word in dictionary:
        word = word.strip('\n')
        dict.append(word)
    return dict

def judgeodd(num):
    if (num % 2) == 0:
        return 'even'
    else:
        return 'odd'


#注意氯质,這里你要修改path路徑闻察。
deny_word = open_dict(Dict = '否定詞', path= r'/Users/apple888/PycharmProjects/Textming/')
posdict = open_dict(Dict = 'positive', path= r'/Users/apple888/PycharmProjects/Textming/')
negdict = open_dict(Dict = 'negative', path= r'/Users/apple888/PycharmProjects/Textming/')

degree_word = open_dict(Dict = '程度級(jí)別詞語(yǔ)', path= r'/Users/apple888/PycharmProjects/Textming/')
mostdict = degree_word[degree_word.index('extreme')+1 : degree_word.index('very')]#權(quán)重4蜓陌,即在情感詞前乘以3
verydict = degree_word[degree_word.index('very')+1 : degree_word.index('more')]#權(quán)重3
moredict = degree_word[degree_word.index('more')+1 : degree_word.index('ish')]#權(quán)重2
ishdict = degree_word[degree_word.index('ish')+1 : degree_word.index('last')]#權(quán)重0.5



def sentiment_score_list(dataset):
    seg_sentence = dataset.split('。')

    count1 = []
    count2 = []
    for sen in seg_sentence: #循環(huán)遍歷每一個(gè)評(píng)論
        segtmp = jieba.lcut(sen, cut_all=False)  #把句子進(jìn)行分詞填抬,以列表的形式返回
        i = 0 #記錄掃描到的詞的位置
        a = 0 #記錄情感詞的位置
        poscount = 0 #積極詞的第一次分值
        poscount2 = 0 #積極詞反轉(zhuǎn)后的分值
        poscount3 = 0 #積極詞的最后分值(包括嘆號(hào)的分值)
        negcount = 0
        negcount2 = 0
        negcount3 = 0
        for word in segtmp:
            if word in posdict:  # 判斷詞語(yǔ)是否是情感詞
                poscount += 1
                c = 0
                for w in segtmp[a:i]:  # 掃描情感詞前的程度詞
                    if w in mostdict:
                        poscount *= 4.0
                    elif w in verydict:
                        poscount *= 3.0
                    elif w in moredict:
                        poscount *= 2.0
                    elif w in ishdict:
                        poscount *= 0.5
                    elif w in deny_word:
                        c += 1
                if judgeodd(c) == 'odd':  # 掃描情感詞前的否定詞數(shù)
                    poscount *= -1.0
                    poscount2 += poscount
                    poscount = 0
                    poscount3 = poscount + poscount2 + poscount3
                    poscount2 = 0
                else:
                    poscount3 = poscount + poscount2 + poscount3
                    poscount = 0
                a = i + 1  # 情感詞的位置變化

            elif word in negdict:  # 消極情感的分析,與上面一致
                negcount += 1
                d = 0
                for w in segtmp[a:i]:
                    if w in mostdict:
                        negcount *= 4.0
                    elif w in verydict:
                        negcount *= 3.0
                    elif w in moredict:
                        negcount *= 2.0
                    elif w in ishdict:
                        negcount *= 0.5
                    elif w in degree_word:
                        d += 1
                if judgeodd(d) == 'odd':
                    negcount *= -1.0
                    negcount2 += negcount
                    negcount = 0
                    negcount3 = negcount + negcount2 + negcount3
                    negcount2 = 0
                else:
                    negcount3 = negcount + negcount2 + negcount3
                    negcount = 0
                a = i + 1
            elif word == '宏蛉!' or word == '!':  ##判斷句子是否有感嘆號(hào)
                for w2 in segtmp[::-1]:  # 掃描感嘆號(hào)前的情感詞拾并,發(fā)現(xiàn)后權(quán)值+2鹏浅,然后退出循環(huán)
                    if w2 in posdict or negdict:
                        poscount3 += 2
                        negcount3 += 2
                        break
            i += 1 # 掃描詞位置前移


            # 以下是防止出現(xiàn)負(fù)數(shù)的情況
            pos_count = 0
            neg_count = 0
            if poscount3 < 0 and negcount3 > 0:
                neg_count += negcount3 - poscount3
                pos_count = 0
            elif negcount3 < 0 and poscount3 > 0:
                pos_count = poscount3 - negcount3
                neg_count = 0
            elif poscount3 < 0 and negcount3 < 0:
                neg_count = -poscount3
                pos_count = -negcount3
            else:
                pos_count = poscount3
                neg_count = negcount3

            count1.append([pos_count, neg_count])
        count2.append(count1)
        count1 = []

    return count2

def sentiment_score(senti_score_list):
    score = []
    for review in senti_score_list:
        score_array = np.array(review)
        Pos = np.sum(score_array[:, 0])
        Neg = np.sum(score_array[:, 1])
        AvgPos = np.mean(score_array[:, 0])
        AvgPos = float('%.1f'%AvgPos)
        AvgNeg = np.mean(score_array[:, 1])
        AvgNeg = float('%.1f'%AvgNeg)
        StdPos = np.std(score_array[:, 0])
        StdPos = float('%.1f'%StdPos)
        StdNeg = np.std(score_array[:, 1])
        StdNeg = float('%.1f'%StdNeg)
        score.append([Pos, Neg, AvgPos, AvgNeg, StdPos, StdNeg])
    return score



data = '你就是個(gè)王八蛋之碗,混賬玩意!你們的手機(jī)真不好用季希!非常生氣式塌,我非常郁悶!R背馈>澄觥劳淆!'
data2= '我好開(kāi)心啊默赂,非常非常非常高興!今天我得了一百分曲掰,我很興奮開(kāi)心栏妖,愉快,開(kāi)心'

print(sentiment_score(sentiment_score_list(data)))
print(sentiment_score(sentiment_score_list(data2)))

運(yùn)行結(jié)果:

[[78.0, 169.0, 3.1, 6.8, 3.1, 6.5]]
[[327.0, 30.0, 14.9, 1.4, 22.5, 0.9]]

從得分我們看到第一段話是消極的宛裕,第二段是積極的论泛。(主要看Pos與Neg大衅ㄗ唷)

運(yùn)行代碼及詞典下載
鏈接:http://link.zhihu.com/?target=https%3A//pan.baidu.com/s/1jIRoOxK
密碼:6wq4
下載完代碼坟瓢,一定要注意代碼中的path,修改成泥電腦中的文件路徑粥诫,否則沒(méi)法用崭庸。有什么問(wèn)題可以給作者留言。

歡迎關(guān)注作者公眾號(hào):大鄧帶你玩轉(zhuǎn)python

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末怕享,一起剝皮案震驚了整個(gè)濱河市执赡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌函筋,老刑警劉巖沙合,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異跌帐,居然都是意外死亡首懈,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門谨敛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)究履,“玉大人脸狸,你說(shuō)我怎么就攤上這事最仑∶臧常” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵泥彤,是天一觀的道長(zhǎng)欲芹。 經(jīng)常有香客問(wèn)我,道長(zhǎng)吟吝,這世上最難降的妖魔是什么菱父? 我笑而不...
    開(kāi)封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮爸黄,結(jié)果婚禮上滞伟,老公的妹妹穿的比我還像新娘。我一直安慰自己炕贵,他們只是感情好梆奈,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著称开,像睡著了一般亩钟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鳖轰,一...
    開(kāi)封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天清酥,我揣著相機(jī)與錄音,去河邊找鬼蕴侣。 笑死焰轻,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的昆雀。 我是一名探鬼主播辱志,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼狞膘!你這毒婦竟也來(lái)了揩懒?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤挽封,失蹤者是張志新(化名)和其女友劉穎已球,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體辅愿,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡智亮,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了点待。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鸽素。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖亦鳞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤燕差,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布遭笋,位于F島的核電站,受9級(jí)特大地震影響徒探,放射性物質(zhì)發(fā)生泄漏瓦呼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一测暗、第九天 我趴在偏房一處隱蔽的房頂上張望央串。 院中可真熱鬧,春花似錦碗啄、人聲如沸质和。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)饲宿。三九已至,卻和暖如春胆描,著一層夾襖步出監(jiān)牢的瞬間瘫想,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工昌讲, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留国夜,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓短绸,卻偏偏與公主長(zhǎng)得像车吹,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鸠按,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

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

  • 有部電影叫 《黑天鵝》 :) “有什么東西容易導(dǎo)致心理扭曲礼搁?” “壓力∧考猓” …… 文丨一先生 2018年03月14...
    一克松閱讀 356評(píng)論 0 0
  • 地震是大家熟知的不可抗力因素之一,尤其身處地震活躍帶上洞拨。當(dāng)?shù)卣饋?lái)臨扯罐,動(dòng)物方面、植物方面以及地震局都有一定程度的反...
    我愛(ài)刨根問(wèn)底閱讀 822評(píng)論 2 2
  • 上大學(xué)的時(shí)候烦衣,我利用業(yè)余時(shí)間看完了這部電視劇歹河,整體來(lái)說(shuō)還不錯(cuò)基本上按照小說(shuō)的劇情在拍電視掩浙。當(dāng)然在看電視之前我看過(guò)這...
    夏目心葉閱讀 853評(píng)論 0 5
  • 小李來(lái)到單位辦公室一年了,工作踏實(shí)謹(jǐn)慎秸歧、一絲不茍厨姚、任勞任怨。眼看著下周就要召開(kāi)下半年的黨政領(lǐng)導(dǎo)班子民主生活會(huì)了...
    wiwy閱讀 1,138評(píng)論 0 1
  • 被朋友挖了坑键菱,已填完谬墙。 英劇《誰(shuí)是兇手》,看完感慨经备,再加上朱莉皮特的離婚消息拭抬,忍不住也從婚姻的角度談?wù)勥@部劇。 這...
    8bbb569d8b19閱讀 5,656評(píng)論 0 0