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

情感分析是大数据时代常见的一种分析方法,多用于对产品评论的情感挖掘,以探究顾客的满意度程度。在做情感分析时,有两种途径:一种是基于情感词典的分析方法,一种是基于机器学习的方法,两者各有利弊。
在此,笔者主要想跟大家分享基于python平台利用情感词典做情感分析的方法。本文主要参考https://blog.csdn.net/lom9357bye/article/details/79058946这篇文章,在此文章中,博主用一句简单的语句“我今天很高兴也非常开心”向我们清楚的展示的利用情感词典做情感分析的方法,这篇文章对笔者很受用。
然而这篇文章博主也向我们抛出了几个问题,笔者就是基于此改写的算法。主要分以下几个步骤:
(1)过滤掉停用词表中的否定词和程度副词
有时候,停用词表中的词包括了否定词和程度副词,因此在做情感分析时首要先过滤掉停用词表中的否定词和程度副词,防止这些有意义的词被过滤掉。词表的下载见上述博主。

"""在停用词表中过滤否定词和程度副词"""
#生成stopword表,需要去除一些否定词和程度词汇
stopwords = set()
fr = open('stopwords.txt','r',encoding='utf-8')
for word in fr:
    stopwords.add(word.strip())#Python strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。
    # #读取否定词文件
    not_word_file = open('否定词.txt','r+',encoding='utf-8')
    not_word_list = not_word_file.readlines()
    not_word_list = [w.strip() for w in not_word_list]
    #读取程度副词文件
    degree_file = open('程度副词.txt','r+')
    degree_list = degree_file.readlines()
    degree_list = [item.split(',')[0] for item in degree_list]
    #生成新的停用词表
    with open('stopwords_new.txt','w',encoding='utf-8') as f:
        for word in stopwords:
            if(word not in not_word_list) and (word not in degree_list):
                f.write(word+'\n')

(2)分词,过滤停用词

def seg_word(sentence):
    jieba.load_userdict("./dict.txt")
    seg_list = jieba.cut(sentence)
    seg_result = []
    # 读取停用词文件
    stopwords = [line.strip() for line in open('stopwords_new.txt', encoding='UTF-8').readlines()]
    # 去停用词
    for word in seg_list:  # 读取每一行分词
        if word not in stopwords:  # 如果分词不在停用词列表中
            if word != '\t':
                seg_result.append(word)
    print(seg_result)
    return seg_result

(3)找出分词结果中的情感词、否定词和程度副词
在博主的文章中,这里出现了一个错误就是如果句子中出现两个相同的情感词、程度副词和否定词的话,前面的就会被后面的覆盖掉了,这是因为博主将分词结果转换成了以词作为key,索引作为value的字典形式,但如果我们只对分词结果以列表的形式进行遍历,则可避免这种情况的发生。

def classify_words( word_list):
    """词语分类,找出情感词、否定词、程度副词"""
    # 读取情感字典文件
    sen_file = open('BosonNLP_sentiment_score.txt', 'r+', encoding='utf-8')
    # 获取字典文件内容
    sen_list = sen_file.readlines()  # sen_list是一个二维列表
    # 创建情感字典
    sen_dict = defaultdict()
    # 读取字典文件每一行内容,将其转换为字典对象,key为情感词,value为对应的分值
    for s in sen_list:
        # 每一行内容根据空格分割,索引0是情感词,索引1是情感分值(情感词典文件中有一行是空行,因此执行的时候会报错,注意处理一下空行,这里没有处理)
        # print(s)
        sen_dict[s.split(' ')[0]] = s.split(' ')[1]  # 字典的键值对形式
    # 读取否定词文件
    not_word_file = open('否定词.txt', 'r+', encoding='utf-8')
    # 由于否定词只有词,没有分值,使用list即可
    not_word_list = not_word_file.readlines()
    not_dict = defaultdict()
    for n in not_word_list:
        not_dict[n.split(',')[0]] = n.split(',')[1]
    # 读取程度副词文件
    degree_file = open('程度副词.txt', 'r+', encoding='ANSI')
    degree_list = degree_file.readlines()
    degree_dict = defaultdict()
    # 程度副词与情感词处理方式一样,转为程度副词字典对象,key为程度副词,value为对应的程度值
    for d in degree_list:
        degree_dict[d.split(',')[0]] = d.split(',')[1]
    # 分类结果,词语的index作为key,词语的分值作为value,否定词分值设为-1
    sen_word = dict()
    not_word = dict()
    degree_word = dict()
    # 分类
    for i in range(len(word_list)):
        word = word_list[i]
        if word in sen_dict.keys() and word not in not_dict.keys() and word not in degree_dict.keys():
            # 找出分词结果中在情感字典中的词
            sen_word[i] = sen_dict[word]
        elif word in not_dict.keys() and word not in degree_dict.keys():
            # 分词结果中在否定词列表中的词
            not_word[i] = -1
        elif word in degree_dict.keys():
            # 分词结果中在程度副词中的词
            degree_word[i] = degree_dict[word]
    # 将分类结果返回
    print(sen_word,not_word,degree_word)
    return sen_word, not_word, degree_word

(4)计算情感值
在计算情感值的过程中,博主提出了两个问题,第一是对第一个情感词之前的程度副词和否定词的判断情况,第二个就是权重W没有初始化,被累乘的情况。笔者将它改成下面的代码形式,完美解决了这两个问题。

#1.用来判断第一个情感词之前的程度副词和否定词
def get_init_weight(sen_word, not_word, degree_word):
    # 权重初始化为1
    W = 1
    # 将情感字典的key转为list
    sen_word_index_list = list(sen_word.keys())
    if len(sen_word_index_list) == 0:
        return W
    # 获取第一个情感词的下标,遍历从0到此位置之间的所有词,找出程度词和否定词
    for i in range(0, sen_word_index_list[0]):
        if i in not_word.keys():
            W *= -1
        elif i in degree_word.keys():
            #更新权重,如果有程度副词,分值乘以程度副词的程度分值
            W *= float(degree_word[i])
    return W
    #2.计算得分
def socre_sentiment(sen_word, not_word, degree_word, seg_result):
    W = get_init_weight(sen_word, not_word, degree_word)
    print(W)
    score = 0
    # 情感词下标初始化
    sentiment_index = -1
    # 情感词的位置下标集合
    sentiment_index_list = list(sen_word.keys())
    #print(sentiment_index_list)
    # 遍历分词结果(遍历分词结果是为了定位两个情感词之间的程度副词和否定词)
    for i in range(0, len(seg_result)):
        # 如果是情感词(根据下标是否在情感词分类结果中判断)
        if i in sen_word.keys():
            # 权重*情感词得分
            score += W * float(sen_word[i])
            print(score)
            # 情感词下标加1,获取下一个情感词的位置
            sentiment_index += 1
            print("sentiment_index:",sentiment_index)
            if sentiment_index < len(sentiment_index_list) - 1:  #总的情感词的个数
                # 判断当前的情感词与下一个情感词之间是否有程度副词或否定词
                """这个是解决W累乘情况的"""
                W=1  #防止第二轮的权重出现累乘的情况
                for j in range(sentiment_index_list[sentiment_index], sentiment_index_list[sentiment_index + 1]):
                    # 更新权重,如果有否定词,取反
                    if j in not_word.keys():
                        W *= -1
                    elif j in degree_word.keys():
                        # 更新权重,如果有程度副词,分值乘以程度副词的程度分值
                        W *= float(degree_word[j])
                    print(W)
                    """这里又出现了一个问题,就是后一个没有否定词和程度副词的权重会将前一个覆盖掉,所以初始化权重W=1不能放在for循环中"""
        # 定位到下一个情感词
        if sentiment_index < len(sentiment_index_list) - 1:
            i = sentiment_index_list[sentiment_index + 1]
    return score

(5)测试
测试过程中,笔者用了一句和博主测试语句情感相反的语句,“我很不高兴也非常不开心”

seg_list = seg_word("我很不高兴也非常不开心")  
sen_word, not_word, degree_word = classify_words(seg_list)
score = socre_sentiment(sen_word, not_word, degree_word, seg_list)
print(score)

测试结果如下图所示:在这里插入图片描述
其中,第一行表示的是分词结果,第二行表示的是分词结果中情感词、否定词和程度副词词典
第三行表示的就是第一个情感词之前的否定词和程度副词所代表的权重,其中“很”的权重是1.6,“不”的权重是-1,那么第一次循环中的得分score=(-1)1.6score(“高兴”),第二次循环求得的是第一个情感词“高兴”和第二个情感词“开心”之间的权重,也就是“非常”=1.8,"不“=-1,第二次求得的分数score=上一次循环中求得的分值+(-1)1.8score(”开心“)。由于没有下一个情感词了,所以这也是最终句子的情感值得分。

参考来源:https://blog.csdn.net/lom9357bye/article/details/79058946

  • 7
    点赞
  • 97
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
情感分析是一种将自然语言处理技术应用于文本的方法,旨在确定文本中的情感倾向和情感极性。利用情感词典对CSV文件的公司年报进行情感分析,可以帮助我们了解年报中所述的内容对公司的情绪影响。 首先,将CSV文件导入Python编程环境,并使用适当的库进行数据处理和情感分析。接着,选择一种可靠的情感词典,如“情感词典A”或“情感词典B”。 情感词典通常包含一系列词汇,每个词汇都标记有情感极性(如积极、中性或消极)。我们可以根据情感词典中的词汇,在年报中进行情感分析。将每个词与情感词典进行比对,并计算得分。 对于每一段文字,我们可以计算其情感得分。这可以通过统计文字中出现的积极和消极词汇的数目以及其情感极性来完成。可以使用统计方法,如加权平均法或简单计数法。 最后,根据情感得分,可以对公司年报的情感进行综合评估。如果得分为正,意味着年报中的情感倾向更积极;如果得分为负,表示情感倾向更消极。 值得注意的是,情感分析并非绝对准确,可能受到词义歧义、语境和复杂的句子结构等因素的影响。因此,在执行情感分析时,需要考虑更多的因素,并运用其他NLP技术和机器学习方法进行更精确的情感分析。 总之,利用情感词典对CSV文件公司年报进行情感分析可以帮助我们了解年报的情感倾向,对公司的发展和经营状况进行评估,以便更准确地出决策。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值