python nlp情感分析之极性分析

背景

目前做情感分析基本使用机器学习或者深度学习进行情感分析,准确率已经很高了。最近与某高校新闻媒体学院合作进行大数据情感分析,学院老师要求采用情感字典进行情感极性分析,之前做项目情感分析都是采用深度模型做的,这次打算使用情感字典进行情感极性分析,并且以后可以用来收集数据。

1.数据准备

1.1 情感词典准备

话说是基于情感词典的极性分析,当然要有情感字典,可以采用下面的链接直接下载。

https://bosonnlp.com/resources/BosonNLP_sentiment_score.zip

解压缩之后可以看到BosonNLP_sentiment_score.txt文件,里面的数据如下:

如虎添翼 6.37503943135
定购 6.37503943135
富婆团 6.37503943135
赖世荣 6.37503943135

这里挑选了几个正面的词语,分为两列,第一列为情感词,第二列情感词的情感值,越大代表越正面。

1.2 否定词

文本情感分类(一):传统模型中提供了一个情感极性词典的下载包,包中带了一个否定词的txt。

https://kexue.fm/usr/uploads/2017/09/1922797046.zip

不大
不丁点儿
不甚
不怎么
聊
没怎么
不可以
怎么不
几乎不
从来不
从不
不用
不曾
不该
不必
不会
不好
不能
很少
极少
没有
不是
难以
放下
扼杀
终止
停止
放弃
反对
缺乏
缺少
不
甭
勿
别
未
反
没
否
木有
非
无
请勿
无须
并非
毫无
决不
休想
永不
不要
未尝
未曾
毋
莫
从未
从未有过
尚未
一无
并未
尚无
从没
绝非
远非
切莫
绝不
毫不
禁止
忌
拒绝
杜绝
弗

1.3 程度副词词典

程度副词可以使用从这里《知网》情感分析用词语集(beta版)下载,里面包含程度级别的词语,但是里面的格式是汇总的形式,需要转换为词典的形式,这里做了一个简单的程度副词标记,大于1,表示情感加强,小于1,表示情感弱化,下面主要按照极其1.8,超1.6,很1.5,较1,稍0.7,欠0.5进行了一个简单的标记,如下所示。也可以根据自己的需求及及进行修改。

百分之百,1.8
倍加,1.8
备至,1.8
不得了,1.8
不堪,1.8
不可开交,1.8
不亦乐乎,1.8
不折不扣,1.8
彻头彻尾,1.8
充分,1.8
到头,1.8
地地道道,1.8
非常,1.8
极,1.8
极度,1.8
极端,1.8
极其,1.8
极为,1.8
截然,1.8
尽,1.8
惊人地,1.8
绝,1.8
绝顶,1.8
绝对,1.8
绝对化,1.8
刻骨,1.8
酷,1.8
满,1.8
满贯,1.8
满心,1.8
莫大,1.8
奇,1.8
入骨,1.8
甚为,1.8
十二分,1.8
十分,1.8
十足,1.8
死,1.8
滔天,1.8
痛,1.8
透,1.8
完全,1.8
完完全全,1.8
万,1.8
万般,1.8
万分,1.8
万万,1.8
无比,1.8
无度,1.8
无可估量,1.8
无以复加,1.8
无以伦比,1.8
要命,1.8
要死,1.8
已极,1.8
已甚,1.8
异常,1.8
逾常,1.8
贼,1.8
之极,1.8
之至,1.8
至极,1.8
卓绝,1.8
最为,1.8
佼佼,1.8
郅,1.8
綦,1.8
齁,1.8
最,1.8
不过,1.5
不少,1.5
不胜,1.5
惨,1.5
沉,1.5
沉沉,1.5
出奇,1.5
大为,1.5
多,1.5
多多,1.5
多加,1.5
多么,1.5
分外,1.5
格外,1.5
够瞧的,1.5
够戗,1.5
好,1.5
好不,1.5
何等,1.5
很,1.5
很是,1.5
坏,1.5
可,1.5
老,1.5
老大,1.5
良,1.5
颇,1.5
颇为,1.5
甚,1.5
实在,1.5
太,1.5
太甚,1.5
特,1.5
特别,1.5
尤,1.5
尤其,1.5
尤为,1.5
尤以,1.5
远,1.5
着实,1.5
曷,1.5
碜,1.5
大不了,0.8
多,0.8
更,0.8
更加,0.8
更进一步,0.8
更为,0.8
还,0.8
还要,0.8
较,0.8
较比,0.8
较为,0.8
进一步,0.8
那般,0.8
那么,0.8
那样,0.8
强,0.8
如斯,0.8
益,0.8
益发,0.8
尤甚,0.8
逾,0.8
愈,0.8
愈 ... 愈,0.8
愈发,0.8
愈加,0.8
愈来愈,0.8
愈益,0.8
远远,0.8
越 ... 越,0.8
越发,0.8
越加,0.8
越来越,0.8
越是,0.8
这般,0.8
这样,0.8
足,0.8
足足,0.8
点点滴滴,0.7
多多少少,0.7
怪,0.7
好生,0.7
还,0.7
或多或少,0.7
略,0.7
略加,0.7
略略,0.7
略微,0.7
略为,0.7
蛮,0.7
稍,0.7
稍稍,0.7
稍微,0.7
稍为,0.7
稍许,0.7
挺,0.7
未免,0.7
相当,0.7
些,0.7
些微,0.7
些小,0.7
一点,0.7
一点儿,0.7
一些,0.7
有点,0.7
有点儿,0.7
有些,0.7
半点,0.5
不大,0.5
不丁点儿,0.5
不甚,0.5
不怎么,0.5
聊,0.5
没怎么,0.5
轻度,0.5
弱,0.5
丝毫,0.5
微,0.5
相对,0.5
不为过,1.6
超,1.6
超额,1.6
超外差,1.6
超微结构,1.6
超物质,1.6
出头,1.6
多,1.6
浮,1.6
过,1.6
过度,1.6
过分,1.6
过火,1.6
过劲,1.6
过了头,1.6
过猛,1.6
过热,1.6
过甚,1.6
过头,1.6
过于,1.6
过逾,1.6
何止,1.6
何啻,1.6
开外,1.6
苦,1.6
老,1.6
偏,1.6
强,1.6
溢,1.6
忒,1.6

1.4 停止词

停用词词典有很多,可以使用科院计算所中文自然语言处理开放平台发布了有1208个停用词的中文停用词表,也可以使用其他的停用词词表,但是要注意一下需要将否定词或者是程度副词的词典过滤掉,不然否定词在去除停用词的时候都过滤掉了,就缺少了一些程度副词或者否定词。如果需要过滤的话可以使用下面的方面过滤。

#生成stopword生成,需要去除一些否定词和程度词
stopwords = set()
fr = codecs.open('data/中文停用词表.txt', 'r', 'utf-8')
for word in fr:
    stopwords.add(word.strip())
#否定词文件    
not_word_file = open('data/notDict.txt', 'r+', encoding='utf-8')
    # 由于否定词只有词,没有分值,使用list即可
not_word_list = not_word_file.readlines()
not_word_list = [w.strip() for w in not_word_list]
#程度副词文件
degree_file = open('data/degree.txt', 'r+', encoding='utf-8')
degree_list = degree_file.readlines()
degree_list = [d.split(",")[0] for d in degree_list]
#生成新的停止词
with open("data/stopwords.txt", "w") as f:
    for s in stopwords:
        if (s not in not_word_list) and (s not in degree_list):
            f.write(s+"\n")

2.数据预处理

2.1 jieba分词

直接使用jieba分词工具进行分词

2.2 去除停用词

在jieba分词之后过滤掉停用词

def seg_word(sentence):
    """使用jieba对文档分词"""
    seg_list = jieba.cut(sentence)
    seg_result = []
    for w in seg_list:
        seg_result.append(w)
    # 读取停用词文件
    stopwords = set()
    fr = codecs.open('data/stopwords.txt', 'r', 'utf-8')
    for word in fr:
        stopwords.add(word.strip())
    fr.close()
    # 去除停用词
    return list(filter(lambda x: x not in stopwords, seg_result))

3 模型构建

3.1 找出文本中的情感词,否定词和程度副词

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

3.2 计算分数

规则:分数采用情感词的分数和计算

遍历所有的情感词,查看当前情感词的前面是否有否定词和程度副词,如果没有否定词,就对当前情感词乘以1,如果有否定词或者有多个否定词,可以乘以(-1)^否定词的个数;如果有程度副词,就在当前情感词前面乘以程度副词的程度等级。

伪代码如下:

finalSentiScore = (-1) ^ (num of notWords) * degreeNum * sentiScore
finalScore = sum(finalSentiScore)
def socre_sentiment(sen_word, not_word, degree_word, seg_result):
    """计算得分"""
    # 权重初始化为1
    W = 1
    score = 0
    # 情感词下标初始化
    sentiment_index = -1
    # 情感词的位置下标集合
    sentiment_index_list = list(sen_word.keys())
    # 遍历分词结果(遍历分词结果是为了定位两个情感词之间的程度副词和否定词)
    for i in range(0, len(seg_result)):
        # 如果是情感词(根据下标是否在情感词分类结果中判断)
        if i in sen_word.keys():
            # 权重*情感词得分
            score += W * float(sen_word[i])
            # 情感词下标加1,获取下一个情感词的位置
            sentiment_index += 1
            if sentiment_index < len(sentiment_index_list) - 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])
        # 定位到下一个情感词
        if sentiment_index < len(sentiment_index_list) - 1:
            i = sentiment_index_list[sentiment_index + 1]
    return score

3.3 计算每句话的分数

def setiment_score(sententce):
    # 1.对文档分词
    seg_list = seg_word(sententce)
    # 2.将分词结果列表转为dic,然后找出情感词、否定词、程度副词
    sen_word, not_word, degree_word = classify_words(list_to_dict(seg_list))
    # 3.计算得分
    score = socre_sentiment(sen_word, not_word, degree_word, seg_list)
    return score

3.4 计算整个新闻的情感值

这里对整个文本根据标点符号进行分割,然后求整个文本的平均值。

def sem_analyses(content):

    pattern = r',|\.|/|;|\'|`|\[|\]|<|>|\?|:|"|\{|\}|\~|!|@|#|\$|%|\^|&|\(|\)|-|=|\_|\+|,|。|、|;|‘|’|【|】|·|!| |…|(|)'
    test_text = 'b,b.b/b;b\'b`b[b]b<b>b?b:b"b{b}b~b!b@b#b$b%b^b&b(b)b-b=b_b+b,b。b、b;b‘b’b【b】b·b!b b…b(b)b'
    result_list = re.split(pattern, content)
    scores = 0
    for text in result_list:
        score = setiment_score(text)
        scores += score
    print(scores/len(result_list))
    return scores/len(result_list)
#     print(result_list)
content = "所长世界观政教分离才是伊拉克人民的美好未来方向,伊拉克没有共产党,不会有春天。伊拉克需要一个社会主义特色系统,宗教归宗教,宗教在心中,但人总不能用宗教治国吧。宗教是人的信仰,但治国是人类的发展方向,定好治国标准和信仰干涉治国的范围后,我相信伊拉克会有不一样未来,会非常美好。总之而言,伊拉克必须依法治国为主,依教为辅。"

sem_analyses(content)

以上就是根据情感词对文本数据进行极性分析。

 

Reference:

https://blog.csdn.net/cjjwwss/article/details/79953397

https://blog.csdn.net/lom9357bye/article/details/79058946

  • 6
    点赞
  • 87
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
可以使用Python中的自然语言处理库NLTK来对txt文本进行情感极性分析。具体步骤如下: 1. 安装NLTK库:在命令行中输入`pip install nltk`。 2. 导入所需模块:在Python中导入nltk、re、string、collections模块。 3. 准备数据:将要进行情感分析的txt文本文件读取进来,保存为一个字符串变量。 4. 数据预处理:对文本进行分词、去除停用词、去除标点符号、词干化等操作。 5. 构建情感分析模型:使用已经标注好的情感数据集训练出一个分类器模型。 6. 对文本进行情感分析:使用训练好的模型对预处理后的文本进行情感分析,输出其情感极性。 以下是一个简单的示例代码: ```python import nltk import re import string import collections # 准备数据 with open('text.txt', 'r', encoding='utf-8') as f: text = f.read() # 数据预处理 # 分词 tokens = nltk.word_tokenize(text) # 去除停用词 stopwords = nltk.corpus.stopwords.words('english') tokens = [word for word in tokens if word.lower() not in stopwords] # 去除标点符号 tokens = [word for word in tokens if word not in string.punctuation] # 词干化 porter_stemmer = nltk.PorterStemmer() tokens = [porter_stemmer.stem(word) for word in tokens] # 构建情感分析模型 positive = open('positive_words.txt', 'r').read() negative = open('negative_words.txt', 'r').read() positive_tokens = nltk.word_tokenize(positive) negative_tokens = nltk.word_tokenize(negative) all_tokens = positive_tokens + negative_tokens all_tokens = list(set(all_tokens)) t = [({word: (word in nltk.word_tokenize(x.lower())) for word in all_tokens}, x.split('/')[-1]) for x in positive.split('\n') + negative.split('\n')] classifier = nltk.NaiveBayesClassifier.train(t) # 对文本进行情感分析 # 将文本转换为特征向量 features = {word: (word in tokens) for word in all_tokens} # 输出情感极性 print(classifier.classify(features)) ``` 其中,positive_words.txt和negative_words.txt是已经标注好的情感数据集,可以从网上下载。在这个示例中,使用了朴素贝叶斯分类器作为情感分析模型。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值