如何利用情感词典做中文文本的情感分析?

article/2025/3/14 20:31:38

如何利用情感词典做中文文本的情感分析?

这是本学期在大数据哲学与社会科学实验室做的第四次分享了。

第一次分享的是:如何利用“wordcloud+jieba”制作中文词云?

第二次分享的是:如何爬取知乎中问题的回答以及评论的数据?

第三次分享的是:如何做中文文本的情感分析?

本次给大家分享的是利用情感词典进行中文文本分类的方法,这种方法是对人的记忆和判断思维的最简单的模拟,如图所示。

我们首先通过学习来记忆一些基本词汇,如否定词语有“不”,积极词语有“喜欢”、“爱”,消极词语有“讨厌”、“恨”等,从而在大脑中形成一个基本的语料库。

然后,我们再对输入的句子进行最直接的拆分,看看我们所记忆的词汇表中是否存在相应的词语。

接着,根据这个词语的类别来判断情感,比如“我喜欢数学”,“喜欢”这个词在我们所记忆的积极词汇表中,所以我们判断它具有积极的情感。

基于上述思路,我们可以通过以下几个步骤实现基于情感词典的中文文本情感分类:

  • Step01:准备各类词典(积极情感词典、消极情感词典、否定词词典、程度副词词典)
  • Step02:对句子进行分词
  • Step03:进行情感判断

整个过程如下图所示。

1. 准备各类词典

一般来说,词典是文本感情分类最核心的地方。情感词典通常分为四个部分:积极情感词典、消极情感词典、否定词典以及程度副词词典。

目前最常用的词典如下:

  • 清华大学李军中文褒贬义词典
  • Hownet知网情感词典
  • 台湾大学NTUSD
  • 大连理工大学中文情感词汇本体库

本文用到的词典如下:

2. 句子分词

Python中比较常用的分词库是“jieba”,俗称“结巴分词”。

安装“jieba”的过程也比较简单,支持Python的pip安装,命令如下:

pip install jieba

“jieba”常用的函数非常少,通常只有一个cut()函数。

cut(sentence, cut_all=False, HMM=True):将包含中文的整个句子分割成单独的词。

  • sentence:要进行分词的句子。
  • cut_all:模型类型,True表示完整模式,False表示准确模式。
  • HMM:是否使用隐马尔可夫模型。

下面通过简单的例子来讲述如何使用结巴分词。

【例子】利用准确模式分词。

import jiebatext = "中华民族创造了悠久灿烂的中华文明,为人类作出了卓越贡献。"
words = list(jieba.cut(text, cut_all=False))
print(words)
# ['中华民族', '创造', '了', '悠久', '灿烂', '的', '中华文明', ',', '为', '人类', '作出', '了', '卓越贡献', '。']

【例子】利用完整模式分词。

import jiebatext = "中华民族创造了悠久灿烂的中华文明,为人类作出了卓越贡献。"
words = list(jieba.cut(text, cut_all=True))
print(words)
# ['中华', '中华民族', '民族', '创造', '了', '悠久', '灿烂', '的', '中华', '中华文明', '华文', '文明', '', '', '为', '人类', '作出', '了', '卓越', '卓越贡献', '贡献', '', '']

3. 情感判断

基于情感词典的文本情感分类规则比较机械化。

简单起见,我们将每个积极情感词语赋予权重“1”,将每个消极情感词语赋予权重“-1”,并且假设情感值满足线性叠加原理。如果句子分词后的词语向量包含相应的词语,就加上向前的权值,其中,否定词和程度副词会有特殊的判别规则,否定词会导致权值反号,而程度副词则根据修饰的程度加上相应的数值,在本文档中将权重分为1~6,6个档次(感叹号为第2档)。最后,根据总权值的正负性来判断句子的情感。

以下代码用于加载词典:

def loadDict(fileName, score):wordDict = {}with open(fileName) as fin:for line in fin:word = line.strip()wordDict[word] = scorereturn wordDictdef appendDict(wordDict, fileName, score):with open(fileName) as fin:for line in fin:word = line.strip()wordDict[word] = scoredef loadExtentDict(fileName, level):extentDict = {}for i in range(level):with open(fileName + str(i + 1) + ".txt") as fin:for line in fin:word = line.strip()extentDict[word] = i + 1return extentDict

以下代码用于给词汇赋权值:

postDict = loadDict(u"sentimentDict/积极情感词语.txt", 1)  # 积极情感词典
negDict = loadDict(u"sentimentDict/消极情感词语.txt", -1)  # 消极情感词典
inverseDict = loadDict(u"sentimentDict/否定词语.txt", -1)  # 否定词词典
extentDict = loadExtentDict(u"sentimentDict/程度级别词语", 6)
punc = loadDict(u"sentimentDict/标点符号.txt", 1)
exclamation = {"!": 2, "!": 2}

以下代码是具体的规则:

totalScore = 0  # 记录最终情感得分
lastWordPos = 0  # 记录情感词的位置
lastPuncPos = 0  # 记录标点符号的位置
i = 0  # 记录扫描到的词的位置for word in wordList:if word in punc:lastPuncPos = iif word in postDict: # 积极情感词语处理的规则if lastWordPos > lastPuncPos:start = lastWordPoselse:start = lastPuncPosscore = 1for word_before in wordList[start:i]: # 前面是否有否定词和副词if word_before in extentDict:score = score * extentDict[word_before]if word_before in inverseDict:score = score * -1for word_after in wordList[i + 1:]: # 后面是否带感叹号if word_after in punc:if word_after in exclamation:score = score + 2else:breaklastWordPos = itotalScore += scoreelif word in negDict: # 消极情感词语处理的规则if lastWordPos > lastPuncPos:start = lastWordPoselse:start = lastPuncPosscore = -1for word_before in wordList[start:i]: # 前面是否有否定词和副词if word_before in extentDict:score = score * extentDict[word_before]if word_before in inverseDict:score = score * -1for word_after in wordList[i + 1:]:  # 后面是否带感叹号if word_after in punc:if word_after in exclamation:score = score - 2else:breaklastWordPos = itotalScore += scorei = i + 1

4. 补充说明

在如今的网络信息时代,新词的出现如雨后春笋,其中包括“新构造网络词语”以及“将已有词语赋予新的含义”;另一方面,我们整理的情感词典中,也不可能完全包含已有的情感词语。因此,自动扩充情感词典是保证情感分类模型时效性的必要条件。

目前,通过网络爬虫等手段,我们可以从微博、社区中收集到大量的评论数据,为了从这大批量的数据中找到新的具有情感倾向的词语,可以用无监督学习式的词频统计。

我们的目标是“自动扩充”,因此我们要达到的目的是基于现有的初步模型来进行无监督学习,完成词典扩充,从而增强模型自身的性能,然后再以同样的方式进行迭代,这是一个正反馈的调节过程。虽然我们可以从网络中大量抓取评论数据,但是这些数据是无标注的,我们要通过已有的模型对评论数据进行情感分类,然后在同一类情感(积极或消极)的评论集合中统计各个词语的出现频率,最后将积极、消极评论集的各个词语的词频进行对比。某个词语在积极评论集中的词频相当低,在消极评论集中的词频相当高,那么我们就有把握将该词语添加到消极情感词典中,或者说,赋予该词语负的权值。

举例来说,假设我们的消极情感词典中并没有“黑心”这个词语,但是“可恶”、“讨厌”、“反感”、“喜欢”等基本的情感词语在情感词典中已经存在,那么我们就会能够将下述句子正确地进行情感分类:

句子权值
这个黑心老板太可恶了-2
我很反感这黑心企业的做法-2
很讨厌这家黑心店铺-2
这家店铺真黑心!0

其中,由于消极情感词典中没有“黑心”这个词语,所以“这家店铺真黑心!”就只会被判断为中性(即权值为0)。分类完成后,对所有词频为正和为负的分别统计各个词频,我们发现,新词语“黑心”在负面评论中出现很多次,但是在正面评论中几乎没有出现,那么我们就将黑心这个词语添加到我们的消极情感词典中,然后更新我们的分类结果:

句子权值
这个黑心老板太可恶了-3
我很反感这黑心企业的做法-3
很讨厌这家黑心店铺-3
这家店铺真黑心!-2

于是我们就通过无监督式的学习扩充了词典,同时提高了准确率,增强了模型的性能。这是一个反复迭代的过程,前一步的结果可以帮助后一步的进行。

5. 总结

基于情感词典的文本情感分类是容易实现的,其核心之处在于对情感词典的积累。

最后,把完整的代码和测试放在这里,方便大家使用。

import jiebadef loadDict(fileName, score):wordDict = {}with open(fileName) as fin:for line in fin:word = line.strip()wordDict[word] = scorereturn wordDictdef appendDict(wordDict, fileName, score):with open(fileName) as fin:for line in fin:word = line.strip()wordDict[word] = scoredef loadExtentDict(fileName, level):extentDict = {}for i in range(level):with open(fileName + str(i + 1) + ".txt") as fin:for line in fin:word = line.strip()extentDict[word] = i + 1return extentDictdef getScore(content):postDict = loadDict(u"sentimentDict/积极情感词语.txt", 1)  # 积极情感词典negDict = loadDict(u"sentimentDict/消极情感词语.txt", -1)  # 消极情感词典inverseDict = loadDict(u"sentimentDict/否定词语.txt", -1)  # 否定词词典extentDict = loadExtentDict(u"sentimentDict/程度级别词语", 6)punc = loadDict(u"sentimentDict/标点符号.txt", 1)exclamation = {"!": 2, "!": 2}words = jieba.cut(content)wordList = list(words)print(wordList)totalScore = 0  # 记录最终情感得分lastWordPos = 0  # 记录情感词的位置lastPuncPos = 0  # 记录标点符号的位置i = 0  # 记录扫描到的词的位置for word in wordList:if word in punc:lastPuncPos = iif word in postDict:if lastWordPos > lastPuncPos:start = lastWordPoselse:start = lastPuncPosscore = 1for word_before in wordList[start:i]:if word_before in extentDict:score = score * extentDict[word_before]if word_before in inverseDict:score = score * -1for word_after in wordList[i + 1:]:if word_after in punc:if word_after in exclamation:score = score + 2else:breaklastWordPos = itotalScore += scoreelif word in negDict:if lastWordPos > lastPuncPos:start = lastWordPoselse:start = lastPuncPosscore = -1for word_before in wordList[start:i]:if word_before in extentDict:score = score * extentDict[word_before]if word_before in inverseDict:score = score * -1for word_after in wordList[i + 1:]:if word_after in punc:if word_after in exclamation:score = score - 2else:breaklastWordPos = itotalScore += scorei = i + 1return totalScore

测试情感分类的代码如下:

content = u"你真的是一个非常好的人!"
print(getScore(content))  # 11
content = u"这种行为非常的丑陋,无耻!"
print(getScore(content))  # -6

参考文献:

  • https://kexue.fm/archives/3360
  • https://blog.csdn.net/maxMikexu/article/details/106050067

http://chatgpt.dhexx.cn/article/xx3gmxvS.shtml

相关文章

基于情感词典的文本情感分析(一个最简单的举例能直接运行)

1. 使用情感词典进行情感分析的思路为 1) 将Web文本进行分句,使其以句子为单位进行处理;2) 从分句中抽取连词和否定词,并标记相应连词与否定词位置;3) 访问情感词汇本体,确定词汇极性…

Python利用情感词典做情感分析

情感分析是大数据时代常见的一种分析方法,多用于对产品评论的情感挖掘,以探究顾客的满意度程度。在做情感分析时,有两种途径:一种是基于情感词典的分析方法,一种是基于机器学习的方法,两者各有利弊。 在此&…

共现分析

一、共现分析概念 “共现”指文献的特征项描述的信息共同出现的现象,这里的特征项包括文献的外部和内部特征,如题名、作者、关键词、机构等。 而“共现分析”是对共现现象的定量研究, 以揭示信息的内容关联和特征项所隐含的知识。 二、共…

python基于情感词典的情感分析

今天给大家分享的是通过情感词典来对文本进行情感分析最后计算出情感得分 通过情感得分来判断正负调性 主要步骤: 数据准备 本次情感词典采用的是BosonNLP的情感词典,来源于社交媒体文本,所以词典适用于处理社交媒体的情感分析 本次分析准备的…

python 热词分析_Python笔记:热词分析2020-01-01

热词分析在公众趋势分析、舆情分析有很宽广的应用,我们来看看怎么从一个TXT文件中分析出文章的热词出来,我们采用流行的第三方“结巴”包来实现。 首先安装第三方包(matplotlib,jieba,wordcloud,numpy)mmatplotlib主要…

【共词聚类分析】基于CNKI和WOS的小样本稳健性检验

很久之前的一篇文章,最近终于收到了Reviewers的回复(一把心酸…其中有一个Comments如下,意思是我们原先的文章没法证明共词聚类方法的结论是合理的…于是打算新增加一个稳健型检验(robust analysis),由于上…

python共词矩阵分析结果一步到位

import os import re import pandas as pd from PyPDF2 import PdfFileReader import string import yakeif __name__ __main__:# 运行第一部分代码pdf_files_path C:/Users/win10/Documents/美国智库/pdf_files# 定义一个函数,用于读取PDF文件并将其转化成文本de…

共词分析

一、共现分析概念及主要类型 “共现”指文献的特征项描述的信息共同出现的现象,这里的特征项包括文献的外部和内部特征,如题名、作者、关键词、机构等。而“共现分析”是对共现现象的定量研究,以揭示信息的内容关联和特征项所隐含的知识。常…

AD09由英文改中文菜单步骤

1:打开AD09,点击DXP,选择Preferences 2:在对话框的左边一竖列选择General 3:选择左边竖列后,在右边找到Localization选项 4:点击应用,再点击OK。 5:然后关闭AD09&#xf…

AD软件的常用基本设置

AD软件的基本设置 前言 工欲善其事,必先利其器;最近学弟一直在忙着画板子,但是效率非常低,在看过他的软件基本设置,以及对软件快捷键掌握程度后(新手小白),我决定将常AD的常用基本…

STM32定时器做时钟源输出基于CubeMx

目录 前言 CubeMX配置 开始函数 改变频率 改占空比 结论 前言 调试使用的评估板:https://item.taobao.com/item.htm?spma230r.1.14.17.432b1562F8z658&id612002664117&ns1&abbucket14#detail 作者再调试AD5933过程中,需要输出100Hz…

Evaluation Board User Guide UG-364 文档 BUG

最近作者使用这个芯片;在进行硬件性能对比测试中发现ADI文档中的一个小问题; 相位角计算的过程中,就是下图 结合下面的代码,验证了上面文档应该是手误导致的。

2019年全国大学生电子设计竞赛D题简易电路特性测试仪试题

题目要求部分 我负责的部分就是测量阻抗的部分,这一次我使用的是AD5933 AD5933介绍 我这一篇主要是讲使用5933计算那个待测电路的阻抗值,首先就是在概括处已经说明是我们读取的数据其实是一个实部和一个虚部。 然后我们要记住的是向寄存器0x94&#xf…

电赛专题 |国一作品_线路负载及故障检测装置

有幸邀请到了在2019大学生电子设计大赛的获奖优秀队员为本公众号投稿,将分几次推文为大家介绍几只优秀队伍的作品。 本次推文为大家分享西安电子科技大学微电子学院的团队的作品,团队成员为:蒋昊宇 冯郑 张岳琦(排名不分先后&…

智能电导率系统电路设计详解

电导率是一个衡量水溶液导电能力的电学物理量, 电阻率的倒数为电导率,用希腊字母κ表示,κ1/ρ。一般意义上,电导率的测量温度是标准温度(25℃)。在液体中,水的电导率是衡量水质的一个重要指标。…

AD5934阻抗变换模块实验电路板

■ 前言 本文讨论了基于AD5934构建阻抗变换模块。并对于它测试相应的阻抗进行实验。 01电路设计 1.原理图设计1 ▲ 实验电路板 原理图 2.PCB版图 ▲ 实验电路板PCB 电路板输出接口从右到左,前四个的功能定义如下表。后面四个是用于调试使用。 管脚(从右到左)符号功…

使用AD5933测量元器件的谐振特性

■ 前言 元器件的谐振特性 使用 使用AD5933测量电子器件复阻抗 测量元器件的谐振特性。这里记录了一些相应的的电子实验的数据。以备之后进行复习和参考。 01测量电路 在 使用AD5933测量电子器件复阻抗 中给出了直接测量一些元器件(电阻、电容)的结果。…

AD5933测量容性负载时的神秘振荡信号

■ 问题简介 在博文 使用AD5933测量电子器件复阻抗 中,对于电容负载进行测量的时候,发现测量的结果与理论值严重不符。 除了出现了增大的测量输出值(与前面电阻相对比),还有一些非常不规则的输出结果。 计时在小信号…

使用AD5933分析复阻抗的时钟频率设置

作者:卓晴博士,清华大学自动化系 更新时间:2020-07-29 Wednesday ■ 前言 使用 AD5933分析复数阻抗 时,由于受到内部离散傅里叶变换(DFT)所带来的以下限制: 由于采集信号可能带来的频率 频率混叠 现象由…

使用AD5933测量电子器件复阻抗

■ 前言 下面使用 AD5933阻抗转换器、网络分析仪初步实验 对一些典型的器件测量相关的阻抗。分析测量所对应的工作频率,工作量程等问题。 相关的文献参阅: AD5933阻抗转换器、网络分析仪初步实验AD5933不同频率下的转换结果AD5933使用外部时钟获得更低…