情感分析学习笔记(2) 您所在的位置:网站首页 pmi分析是什么意思啊 情感分析学习笔记(2)

情感分析学习笔记(2)

2024-07-18 03:33| 来源: 网络整理| 查看: 265

整个项目是我借鉴了论文的内容一行代码一行代码敲的(除了.scel转为.txt),没有查阅github上面的开源项目等(就是说我自己封装了一个SO-PMI算法),说不定有漏洞或者思考不清晰的地方,如果发现了请麻烦指正。当然在进行计算的时候,我是采用的循环,并没有将数据矩阵化或者向量化(主要是还不清楚怎样矩阵化或者向量化),在运行效率上确实很差。 这是我在3400条数据集上跑出来的效果,效果很烂,主要数据集太拉胯了。 整个项目的代码除了数据集已开源到了github上,我会在文章后放上链接。 该项目算是复现了少许论文《基于情感词典的中文微博情感分析与话题倾向性判定研究》中SO-PMI那部分的代码,只不过公式更贴近于原始公式。 本文将从项目的目的,SO-PMI算法,数据集获取,代码讲解四部分说明。

目录 1 项目目的2 SO-PMI算法2.1 PMI2.2 SO-PMI 3. 数据集获取4 代码讲解4.1 .scel转.txt4.2 so-pmi4.2.1 计算单独概率4.2.2 计算联合概率4.3.3 计算so-pmi 4.3 代码运行结果4.4 错误原因分析 5 参考

1 项目目的

通过已有的情感基准词判定网络用语的情感极性,包括积极的、消极的,中性的。

整个项目没有做性能度量,不过可以通过人工标注实际数据的真实情感极性来衡量准确率、召回率、F1度量等。

2 SO-PMI算法

SO-PMI(情感倾向点互信息算法,Semantic Orientation Pointwise Mutual Information),SO-PMI算法由两部分组成:SO-PMI和PMI。

算法整体思想很简单,判断需要判断的词语 P ( w o r d ) P(word) P(word)与基准词 P ( b a s e ) P(base) P(base)同时出现的概率,如果与积极(positive)的词同时出现的概率更高,那么就判断为积极的词语,如果与消极(negative)的词同时出现的概率更高,那么就判断为消极的词语,如果与积极和消极的概率相同,那么就判断为中性的词语。

下面分别介绍PMI和SO-PMI:

2.1 PMI

PMI(Pointwise Mutual Information,点互信息算法),用于判断某个词与基准词出现的概率。公式如下: P M I = log ⁡ 2 ( P ( w o r d 1 , w o r d 2 ) P ( w o r d 1 ) P ( w o r d 2 ) ) PMI=\log_2(\frac{P(word1, word2)}{P(word1)P(word2)}) PMI=log2​(P(word1)P(word2)P(word1,word2)​)

P ( w o r d 1 , w o r d 2 ) P(word1, word2) P(word1,word2)为联合概率,即 w o r d 1 word1 word1和 w o r d 2 word2 word2同时出现在语料中的概率,如果两者独立,那么 P ( w o r d 1 , w o r d 2 ) = P ( w o r d 1 ) P ( w o r d 2 ) P(word1, word2) = P(word1)P(word2) P(word1,word2)=P(word1)P(word2),即整个分数为1,那么 P M I = 0 PMI=0 PMI=0。

我查了很多资料并没有说明这个 log ⁡ 2 \log2 log2的含义,但是我估计是和log的曲线有关,不会影响到单调性,同时不会让1这个点附近的值变化过大这个原因。

PMI最终结果的分析如下:

P M I > 0 PMI>0 PMI>0,两个词语相关,值越大关联性越强; P M I = 0 PMI=0 PMI=0,两个词语独立; P M I < 0 PMI0 SO−PMI>0,词语判定为积极词语; S O − P M I = 0 SO-PMI=0 SO−PMI=0,词语判定为中性词语; S O − P M I < 0 SO-PMI'甄开心': 0.0, ...} 4.2.2 计算联合概率 def get_joint_probability(buzzwords, base_word_list, weibo_list): """ 获得联合概率, P(buzzword, baseword) :param buzzwords: 流行语列表 :param base_word_list: 基准词列表 :param weibo_list: 微博列表 :return jp_word: 联合概率词典, {buzzword: {baseword: probability}} """ jp_word = {} length = len(weibo_list) for buzzword in buzzwords: jp_word[buzzword] = {} for base_word in base_word_list: count = 0 for weibo in weibo_list: if re.search(buzzword, weibo) and re.search(base_word, weibo): count += 1 jp_word[buzzword][base_word] = count / length return jp_word

这里联合概率一样,可以同样计算 P ( w o r d , p o s ) P(word, pos) P(word,pos)和 P ( w o r d , n e g ) P(word, neg) P(word,neg),不过我是用的两个正则来判断的,就是在这个微博里面同时发现了 w o r d word word和 b a s e w o r d baseword baseword才增加一次 c o u n t count count。

返回的部分数据如下:

{'甄开心': {'美丽': 0.0, ...}, ...} 4.3.3 计算so-pmi def get_so_pmi(p_buzzwords, p_base_positive, p_base_negative, jp_buzzword_pos, jp_buzzword_neg): """ 计算so-pmi值 :param p_buzzwords: 流行词出现概率的字典 :param p_base_positive: 正向基准词出现概率的字典 :param p_base_negative: 负向基准词出现概率的字典 :param jp_buzzword_pos: 流行语与正向基准词的联合概率字典 :param jp_buzzword_neg: 流行语与负向基准词的联合概率字典 :return so_pmi: so-pmi值, {buzzword: so-pmi} """ # {buzzword: so-pmi} so_pmi = {} for buzzword in p_buzzwords.keys(): pos_pmi = 0 neg_pmi = 0 # 加1平滑 for pos in p_base_positive.keys(): pos_pmi += log((jp_buzzword_pos[buzzword][pos] + 1) / (p_base_positive[pos] * p_buzzwords[buzzword] + 1), 2) for neg in p_base_negative.keys(): neg_pmi += log((jp_buzzword_neg[buzzword][neg] + 1) / (p_base_negative[neg] * p_buzzwords[buzzword] + 1), 2) so_pmi[buzzword] = pos_pmi - neg_pmi return so_pmi

这里我是分开计算的 log ⁡ 2 \log_2 log2​的值然后相减,不清楚把这个转为 l o g log log内相除会不会效率高点,不过感觉好像也没那么重要,毕竟我主要考虑的是能否实现,并非算法效率。

这里最主要的是加1平滑,在分子分母上都选择了+1,主要理由如下:

当数据集够大的时候,分子分母+1其实对整体结果影响不会太大;分子+1,是考虑到如果联合概率为0,那么 log ⁡ 2 P ( w o r d , b a s e w o r d ) \log_2P(word, baseword) log2​P(word,baseword)会直接报错;分母+1,是考虑到如果分母为0,那么会直接报错。

返回的数据格式如下:

{'甄开心': 0.0, ...} 4.3 代码运行结果

由于数据集太小了(3400+),所以运行的结果不尽如人意,许多判断错误的情况,部分结果截图如下: 结果截图 那么我们看到,就光上面的截图,“嗨皮”,“甄开心”,“真德秀”,“真不戳”都是分类错误了的,我们接下来分析下错误原因。

4.4 错误原因分析

根据论文《基于情感词典的中文微博情感分析与话题倾向性判定研究》中的内容,设定了 n u m ( p o s ) = n u m ( n e g ) num(pos)=num(neg) num(pos)=num(neg) 这里 n u m ( p o s ) num(pos) num(pos)是积极基准词独立出现在的微博中的数量, n u m ( n e g ) num(neg) num(neg)同理,这一部分就是作者论文中推导的内容,这段推导挺简单的,大家有兴趣可以拿论文来推导下,这一部分我简单说明一下,就是如果 n u m ( p o s ) ! = n u m ( n e g ) num(pos)!=num(neg) num(pos)!=num(neg),那么这个常数项会影响到最终情感极性的判定,为了避免这样的错误产生,所以作者人为设定这两个值相等。但是我并没有设置这样的情况,所以可能这方面也造成了偏差。

数据集太小了,我们可以从上面返回的结果来看,许多词语出现的概率都为0,而且论文《基于情感词典的中文微博情感分析与话题倾向性判定研究》中的判断语料是45万+微博数据,我的3400+,都不在同一个数量级上面了对吧……

在微博语料环境中,许多人发的内容估计只有短短一句话,比如“就这?”,“针不戳”之类的,那么这种的分析我估计不光是我,程序也是一头的黑人问号,所以导致了分类错误的情况。

5 参考

[1]陈佳慧. 基于情感词典的中文微博情感分析与话题倾向性判定研究[D].西南大学,2019. [2]冯跃. 面向微博的情感倾向性研究[D].吉林大学,2018. [3]寒江共雪.Python读取scel文件[EB/OL].https://blog.csdn.net/cqdiy/article/details/82840027,2018-9-25. [4]今夜无风.点互信息算法(PMI)[EB/OL].https://www.cnblogs.com/demo-deng/p/13085188.html,2020-6-10. [5]owolf.全网最详:python3调用新浪微博API接口获取数据[EB/OL].https://www.jianshu.com/p/7c68f3ca73ed,2018-10-21.



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有