基于情感词典的python情感分析
近期老師給我們安排了一個大作業,要求根據情感詞典對微博語料進行情感分析。于是在網上狂找資料,看相關書籍,終于搞出了這個任務。現在做做筆記,總結一下本次的任務,同時也給遇到有同樣需求的人,提供一點幫助。
1、情感分析含義
情感分析指的是對新聞報道、商品評論、電影影評等文本信息進行觀點提取、主題分析、情感挖掘。情感分析常用于對某一篇新聞報道積極消極分析、淘寶商品評論情感打分、股評情感分析、電影評論情感挖掘。情感分析的內容包括:情感的持有者分析、態度持有者分析、態度類型分析(一系列類型如喜歡(like),討厭(hate),珍視(value),渴望(desire)等;或著簡單的加權極性如積極(positive),消極(negative)和中性(neutral)并可用具體的權重修飾)、態度的范圍分析(包含每句話,某一段、或者全文)。因此,情感分析的目的可以分為:初級:文章的整體感情是積極/消極的;進階:對文章的態度從1-5打分;高級:檢測態度的目標,持有者和類型。
總的來說,情感分析就是對文本信息進行情感傾向挖掘。
2、情感挖掘方法
情感挖掘目前主要使用的方法是使用情感詞典,對文本進行情感詞匹配,匯總情感詞進行評分,最后得到文本的情感傾向。本次我主要使用了兩種方法進行情感分析。第一種:基于BosonNLP情感詞典。該情感詞典是由波森自然語言處理公司推出的一款已經做好標注的情感詞典。詞典中對每個情感詞進行情感值評分,bosanNLP情感詞典如下圖所示:
?
第二種,采用的是知網推出的情感詞典,以及極性表進行情感分析。知網提供的情感詞典共用12個文件,分為英文和中文。其中中文情感詞典包括:評價、情感、主張、程度(正面、負面)的情感文本。本文將評價和情感詞整合作為情感詞典使用,程度詞表中含有的程度詞,按照等級區分,分為:most(最高)-very(很、非常)-more(更多、更)-ish(稍、一點點)-insufficiently(欠、不)-over(過多、多分、多)六個情感程度詞典。
?知網情感詞典下載地址:-?http://www.keenage.com/html/c_bulletin_2007.htm
?
?
?
?
?
?
?3、原理介紹
3.1 基于BosonNLP情感分析原理
基于BosonNLP情感詞典的情感分析較為簡單。首先,需要對文本進行分句、分詞,本文選擇的分詞工具為哈工大的pyltp。其次,將分詞好的列表數據對應BosonNLp詞典進行逐個匹配,并記錄匹配到的情感詞分值。最后,統計計算分值總和,如果分值大于0,表示情感傾向為積極的;如果小于0,則表示情感傾向為消極的。原理框圖如下:
?
?
?
3.2 基于BosonNLP情感分析代碼:
# -*- coding:utf-8 -*- import pandas as pd import jieba#基于波森情感詞典計算情感值
def getscore(text):
df = pd.read_table(r"BosonNLP_dict\BosonNLP_sentiment_score.txt", sep=" ", names=[‘key’, ‘score’])
key = df[‘key’].values.tolist()
score = df[‘score’].values.tolist()
# jieba分詞
segs = jieba.lcut(text,cut_all = False) #返回list
# 計算得分
score_list = [score[key.index(x)] for x in segs if(x in key)]
return sum(score_list)
#讀取文件
def read_txt(filename):
with open(filename,‘r’,encoding=‘utf-8’)as f:
txt = f.read()
return txt
#寫入文件
def write_data(filename,data):
with open(filename,‘a’,encoding=‘utf-8’)as f:
f.write(data)
if name==‘main’:
text = read_txt(‘test_data\微博.txt’)
lists = text.split(’\n’)
相關文件:
BosonNLp情感詞典下載地址:https://bosonnlp.com/dev/resource
微博語料:鏈接:https://pan.baidu.com/s/1Pskzw7bg9qTnXD_QKF-4sg? ?提取碼:15bu
輸出結果:
?
?3.3 基于知網情感詞典的情感挖掘原理
基于知網情感詞典的情感分析原理分為以下幾步:
1、首先,需要對文本分句,分句,得到分詞分句后的文本語料,并將結果與哈工大的停用詞表比對,去除停用詞;
2、其次,對每一句話進行情感分析,分析的方法主要為:判斷這段話中的情感詞數目,含有積極詞,則積極詞數目加1,含有消極詞,則消極詞數目加1。并且再統計的過程中還需要判斷該情感詞前面是否存在程度副詞,如果存在,則需要根據程度副詞的種類賦予不同的權重,乘以情感詞數。如果句尾存在?!等符號,則情感詞數目增加一定值,因為!與?這類的標點往往表示情感情緒的加強,因此需要進行一定處理。
3、接著統計計算整段話的情感值(積極詞值-消極詞值),得到該段文本的情感傾向。
4、最后,統計每一段的情感值,相加得到文章的情感值。
整體流程框圖如下:
?
3.4 基于知網情感詞典的情感分析代碼:
import pyltp from pyltp import Segmentor from pyltp import SentenceSplitter from pyltp import Postagger import numpy as np#讀取文件,文件讀取函數
def read_file(filename):
with open(filename, ‘r’,encoding=‘utf-8’)as f:
text = f.read()
#返回list類型數據
text = text.split(’\n’)
return text
#將數據寫入文件中
def write_data(filename,data):
with open(filename,‘a’,encoding=‘utf-8’)as f:
f.write(str(data))
#文本分句
def cut_sentence(text):
sentences = SentenceSplitter.split(text)
sentence_list = [ w for w in sentences]
return sentence_list
#文本分詞
def tokenize(sentence):
#加載模型
segmentor = Segmentor() # 初始化實例
# 加載模型
segmentor.load(r’E:\tool\python\Lib\site-packages\pyltp-0.2.1.dist-info\ltp_data\cws.model’)
# 產生分詞,segment分詞函數
words = segmentor.segment(sentence)
words = list(words)
# 釋放模型
segmentor.release()
return words
#詞性標注
def postagger(words):
# 初始化實例
postagger = Postagger()
# 加載模型
postagger.load(r’E:\tool\python\Lib\site-packages\pyltp-0.2.1.dist-info\ltp_data\pos.model’)
# 詞性標注
postags = postagger.postag(words)
# 釋放模型
postagger.release()
#返回list
postags = [i for i in postags]
return postags
# 分詞,詞性標注,詞和詞性構成一個元組
def intergrad_word(words,postags):
#拉鏈算法,兩兩匹配
pos_list = zip(words,postags)
pos_list = [ w for w in pos_list]
return pos_list
#去停用詞函數
def del_stopwords(words):
# 讀取停用詞表
stopwords = read_file(r"test_data\stopwords.txt")
# 去除停用詞后的句子
new_words = []
for word in words:
if word not in stopwords:
new_words.append(word)
return new_words
# 獲取六種權值的詞,根據要求返回list,這個函數是為了配合Django的views下的函數使用
def weighted_value(request):
result_dict = []
if request == “one”:
result_dict = read_file(r"E:\學習筆記\NLP學習\NLP code\情感分析3\degree_dict\most.txt")
elif request == “two”:
result_dict = read_file(r"E:\學習筆記\NLP學習\NLP code\情感分析3\degree_dict\very.txt")
elif request == “three”:
result_dict = read_file(r"E:\學習筆記\NLP學習\NLP code\情感分析3\degree_dict\more.txt")
elif request == “four”:
result_dict = read_file(r"E:\學習筆記\NLP學習\NLP code\情感分析3\degree_dict\ish.txt")
elif request == “five”:
result_dict = read_file(r"E:\學習筆記\NLP學習\NLP code\情感分析3\degree_dict\insufficiently.txt")
elif request == “six”:
result_dict = read_file(r"E:\學習筆記\NLP學習\NLP code\情感分析3\degree_dict\inverse.txt")
elif request == ‘posdict’:
result_dict = read_file(r"E:\學習筆記\NLP學習\NLP code\情感分析3\emotion_dict\pos_all_dict.txt")
elif request == ‘negdict’:
result_dict = read_file(r"E:\學習筆記\NLP學習\NLP code\情感分析3\emotion_dict\neg_all_dict.txt")
else:
pass
return result_dict
print(“reading sentiment dict …”)
#讀取情感詞典
posdict = weighted_value(‘posdict’)
negdict = weighted_value(‘negdict’)
# 讀取程度副詞詞典
# 權值為2
mostdict = weighted_value(‘one’)
# 權值為1.75
verydict = weighted_value(‘two’)
# 權值為1.50
moredict = weighted_value(‘three’)
# 權值為1.25
ishdict = weighted_value(‘four’)
# 權值為0.25
insufficientdict = weighted_value(‘five’)
# 權值為-1
inversedict = weighted_value(‘six’)
#程度副詞處理,對不同的程度副詞給予不同的權重
def match_adverb(word,sentiment_value):
#最高級權重為
if word in mostdict:
sentiment_value = 8
#比較級權重
elif word in verydict:
sentiment_value = 6
#比較級權重
elif word in moredict:
sentiment_value = 4
#輕微程度詞權重
elif word in ishdict:
sentiment_value = 2
#相對程度詞權重
elif word in insufficientdict:
sentiment_value = 0.5
#否定詞權重
elif word in inversedict:
sentiment_value = -1
else:
sentiment_value *= 1
return sentiment_value
#對每一條微博打分
def single_sentiment_score(text_sent):
sentiment_scores = []
#對單條微博分句
sentences = cut_sentence(text_sent)
for sent in sentences:
#查看分句結果
# print(‘分句:’,sent)
#分詞
words = tokenize(sent)
seg_words = del_stopwords(words)
#i,s 記錄情感詞和程度詞出現的位置
i = 0 #記錄掃描到的詞位子
s = 0 #記錄情感詞的位置
poscount = 0 #記錄積極情感詞數目
negcount = 0 #記錄消極情感詞數目
#逐個查找情感詞
for word in seg_words:
#如果為積極詞
if word in posdict:
poscount += 1 #情感詞數目加1
#在情感詞前面尋找程度副詞
for w in seg_words[s:i]:
poscount = match_adverb(w,poscount)
s = i+1 #記錄情感詞位置
# 如果是消極情感詞
elif word in negdict:
negcount +=1
for w in seg_words[s:i]:
negcount = match_adverb(w,negcount)
s = i+1
#如果結尾為感嘆號或者問號,表示句子結束,并且倒序查找感嘆號前的情感詞,權重+4
elif word ==’!’ or word ==’!’ or word ==’?’ or word == ‘?’:
for w2 in seg_words[::-1]:
#如果為積極詞,poscount+2
if w2 in posdict:
poscount += 4
break
#如果是消極詞,negcount+2
elif w2 in negdict:
negcount += 4
break
i += 1 #定位情感詞的位置
#計算情感值
sentiment_score = poscount - negcount
sentiment_scores.append(sentiment_score)
#查看每一句的情感值
# print(‘分句分值:’,sentiment_score)
sentiment_sum = 0
for s in sentiment_scores:
#計算出一條微博的總得分
sentiment_sum +=s
return sentiment_sum
# 分析test_data.txt 中的所有微博,返回一個列表,列表中元素為(分值,微博)元組
def run_score(contents):
# 待處理數據
scores_list = []
for content in contents:
if content !=’’:
score = single_sentiment_score(content) # 對每條微博調用函數求得打分
scores_list.append((score, content)) # 形成(分數,微博)元組
return scores_list
#主程序
if name == ‘main’:
print(‘Processing…’)
#測試
# sentence = ‘要怎么說呢! 我需要的戀愛不是現在的樣子, 希望是能互相鼓勵的勉勵, 你現在的樣子讓我覺得很困惑。 你到底能不能陪我一直走下去, 你是否有決心?是否你看不慣我?你是可以隨意的生活,但是我的未來我耽誤不起!’
# sentence = ‘轉有用嗎?這個事本來就是要全社會共同努力的,公交公司有沒有培訓到位?公交車上地鐵站內有沒有放足夠的宣傳標語?我現在轉一下微博,沒有多大的意義。’
sentences = read_file(r’test_data\微博.txt’)
scores = run_score(sentences)
#人工標注情感詞典
man_sentiment = read_file(r’test_data\人工情感標注.txt’)
al_sentiment = []
for score in scores:
print(‘情感分值:’,score[0])
if score[0] < 0:
print(‘情感傾向:消極’)
s = ‘消極’
elif score[0] == 0:
print(‘情感傾向:中性’)
s = ‘中性’
else:
print(‘情感傾向:積極’)
s = ‘積極’
al_sentiment.append(s)
print(‘情感分析文本:’,score[1])
i = 0
#寫入文件中
filename = r’result_data\result_data.txt’
for score in scores:
write_data(filename, ‘情感分析文本:{}’.format(str(score[1]))+’\n’) #寫入情感分析文本
write_data(filename,‘情感分值:{}’.format(str(score[0]))+’\n’) #寫入情感分值
write_data(filename,‘人工標注情感:{}’.format(str(man_sentiment[i]))+’\n’) #寫入人工標注情感
write_data(filename, ‘機器情感標注:{}’.format(str(al_sentiment[i]))+’\n’) #寫入機器情感標注
write_data(filename,’\n’)
i +=1
print(‘succeed…’)
?
?輸出結果:
?
4、小結
?本次的情感分析程序完成簡單的情感傾向判斷,準確率上基于BosonNLP的情感分析較低,其情感分析準確率為:56.67%;而基于知網情感詞典的情感分析準確率達到90%,效果上還是不錯的。但是,這兩個程序都還只是情感分析簡單使用,并未涉及到更深奧的算法,如果想要更加精確,或者再更大樣本中獲得更高精度,這兩個情感分析模型還是不夠的。但是用來練習學習還是不錯的選擇。要想更深入的理解和弄得情感分析,還需要繼續學習。
?
總結
以上是生活随笔為你收集整理的基于情感词典的python情感分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oatdata结构详解
- 下一篇: python对找到的匹配项作处理后再替换