专栏首页源懒由码python 舆情分析 nlp主题分析 (2)-结合snownlp与jieba库,提高分词与情感判断 待续

python 舆情分析 nlp主题分析 (2)-结合snownlp与jieba库,提高分词与情感判断 待续

python 舆情分析 nlp主题分析 (1) 待续: https://www.cnblogs.com/cycxtz/p/13663895.html

前文摘要:
微博热门话题:#中印双方达成五点共识# 阅读量2.4亿,讨论7430条。

1、数据采集,使用python+selenium,采集该话题下的博文及作者信息,以及每个博文下的评论及作者信息;

2、数据预处理,采用Jieba库,构建用户词典,以达到更好的分词;情感分析,采用snownlp库,寻找政治类积极和负面词向量做一个训练,再进行评论分类;

3、对博文及评论作者信息进行分析,查看调查主体的用户类别概况;

4、lda主题分析,对博文做主题分析,依据top3主题关键字,对博文群主类看法进行分析;对正、负向评论做一次主题分析,并分别分析观点;

第一步已完成,现在到第二步;根据网上评价,snownlp作为国内情感分析做的较好的库,但是他的分词能力比较一般,而jieba库在分词这一块做得又比较好,可以扩展用户自定义词典。因此可以考虑,将snownlp与jieba分词库相结合使用。

大概最终的流程就是:

1、修改snownlp源代码使其可扩展;

2、自定义分词方法,jieba;

3、使用新的分词方法对样本进行训练得到新的情感判断器;

4、使用;

参考链接:

通过结合jieba分词优化snowNLP文本情感分析效果: https://blog.csdn.net/weixin_42007766/article/details/89824318

snownlp包结构如图所示:

其中常用库如此:

import jieba
from snownlp import SnowNLP # 使用
from snownlp import seg  # 分词库
from snownlp import sentiment # 情感分词
from snownlp import normal #停用词处理

snownlp常用情感分析方法如下:

s = SnowNLP(u'小明不诚信')
print("分词:",s.words)
print("情感评分(0.6以上为积极,0.2一下为负面):",s.sentiments)
输出:
分词: ['小明', '不', '诚信']
情感评分(0.6以上为积极,0.2一下为负面): 0.16586151271662786

从结果观察:“不诚信”被拆分成了,“不”,“诚信”,本应该一起的词汇被分开了。评分较为负面,判断结果正确。

继续观察snownlp分词的方法,查看源代码,可看到情感分析调用的是Sentiment类中的classify方法,调用的过程如下:

分词(seg.seg(doc))->去除停用词(normal.filter_stop(words))->贝叶斯分类(classifier.classify(self.handle(sent))。

class SnowNLP(object):
    @property
    def sentiments(self):
        return sentiment.classify(self.doc)
class Sentiment(object):
    def handle(self, doc):
        words = seg.seg(doc)
        words = normal.filter_stop(words)
        return words
    
    # 从这里发现,训练和分词,采用的都是 self.handle 函数,如果只修改这里,确实也是可以,还不影响他自带的分词
    # 如果修改seg.seg的话,就得从新训练过
    def train(self, neg_docs, pos_docs):
        data = []
        for sent in neg_docs:
            data.append([self.handle(sent), 'neg'])
        for sent in pos_docs:
            data.append([self.handle(sent), 'pos'])
        self.classifier.train(data)

    def classify(self, sent):
        ret, prob = self.classifier.classify(self.handle(sent))
        if ret == 'pos':
            return prob
        return 1-prob

综上所述:如果需要改善分词,则需要修正seg包,如果要完善去除停用词,则修正Normal包。其中去除停用词比较方便:

对snownlp中-normal文件夹中-stopwords.txt进行补充即可。

再继续观察分词,可以发现原分词方法的使用了正则,为了能让他扩展使用其他分词方法,增加my_handle全局变量:

class SnowNLP(object):
    @property
    def words(self):
        return seg.seg(self.doc)  #分词调用seg方法
def seg(sent):
    words = []
    if my_handle==None:         #此行为更新的代码
        for s in re_zh.split(sent):
            s = s.strip()
            if not s:
                continue
            if re_zh.match(s):
                words += single_seg(s)
            else:
                for word in s.split():
                    word = word.strip()
                    if word:
                        words.append(word)
    else:                                        #此行为更新的代码
        words = my_handle(sent)      #此行为更新的代码
    return words

在seg文件中,补充设置my_handle分词方法:

my_handle=None

# 查看当前的分词方法
def get_now_handle():
    if my_handle == None:
        return seg
    else:
        return my_handle

# 设置自定义分词方法
def set_my_handle(h):
    global my_handle
    my_handle = h

最终调用执行时,定义分词方法->补充用户自定义词典->调用判断:

# 定义自定义分词函数
def my_cut_handle(sent):
    return jieba.lcut(sent)

# 修改分词方法
seg.set_my_handle(my_cut_handle)
jieba.add_word("不诚信")
s = SnowNLP(u'小明不诚信')
print("分词:",s.words)
print("情感评分(0.6以上为积极,0.2一下为负面):",s.sentiments)

输出:

分词: ['小明', '不诚信']

由此看到,分词已经是准确的,但是,情感评分提升到了中性,与我们的预期不符合,这是因为snownlp库初始读取的情感分析训练器是基于以前的分词方法,因此,如果我们更新了分词方法以后,要使用新的方法重新训练,训练调用如下:

# 输入为正负样本
sentiment.train(r'../data/npl_asan/neg.txt',r'../data/npl_asan/pos.txt')
fname = r'../data/npl_asan/sentiment.marshal'
sentiment.save(fname)    # 保存训练结果
# sentiment.load(fname)  #读取已经训练好的数据
# 重新执行
s = SnowNLP(u'小明不诚信')
print("分词:",s.words)
print("情感评分(0.6以上为积极,0.2一下为负面):",s.sentiments)
输出如下:
分词: ['小明', '不诚信']
情感评分(0.6以上为积极,0.2一下为负面): 0.17156078146853382

到此发现:分词与预期到进行了提升。

不足:情感训练样本较少,需要进行补充才能进行更好的判断,如,修改句子增加形容词,表达意思应该是一样的,但是情感提升到了中性:

jieba.add_word("邻居家")
s = SnowNLP(u'邻居家的小明不诚信')
print("分词:",s.words)
print("情感评分(0.6以上为积极,0.2一下为负面):",s.sentiments)
输出:
分词: ['邻居家', '的', '小明', '不诚信']
情感评分(0.6以上为积极,0.2一下为负面): 0.44767845850986676

nlp处理是一个复杂的基础工程,对需要分析的专业场景需要搜集特定的词典以及较完善的正负样本才能进行更好的判断。

emmmm,还需要解决这个最终判断不合适的问题。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 关于time的使用

    一般来说,我们会用time做这些事情,一个是,获取日期,一个是计算某段代码的运行时间。额,这是vs2008的。C++11有更好的精度。

    forxtz
  • sql serve2008是否自带互斥锁

    近期突然想到,一道珠海笔试题,让你写atm机的逻辑,当时想多了,以为重点是让你写清楚其中的事务互斥关系,当时也忘记数据库是否会自动互斥,从而不会出现脏数据。所以...

    forxtz
  • muduo Dispatcher消息分发器 通过多态和模板进行向上类型转换

    所谓消息分发(muduo 中,就是接收到buffer之后,额,或者说是 protobuf),在简单的程序设计里面的话,估计就是 type-switch 了,但是...

    forxtz
  • 神级WordPress主题框架Genesis 2.8发布:容易引起极大舒适感

    根本毛病在哪呢?那是因为,当你安装了一个新主题时,这个主题的演示内容不会自动导入进来(译注:这就好比方便面包装上的图,“图片仅供参考”)。这就导致用户需要在文档...

    丘壑
  • 用大数据教你如何快速写出汪峰风格的歌?

    有一位网友统计了汪老师在大陆发行的9张专辑共117首歌曲的歌词,同一个词语在一首歌出现只算一次。形容词,名词和动词的前十名分别是(词语后面的数字为出现的次数) ...

    小莹莹
  • 智能合约编写之Solidity的高级特性

    Solidity是一门面向区块链平台设计、图灵完备的编程语言,支持函数调用、修饰器、重载,事件、继承和库等多种高级语言的特性。

    区块链大本营
  • 中国SaaS死与生——纷享销客的变与思

    纵观中国SaaS十多年的发展历史,有欢笑,也有血泪。有的坚持不住成为了先烈,也有的坚持下来成为了大佬。作为当前SaaS与CRM市场中主要玩家之一,纷享销客(下称...

    人称T客
  • 究极面试题:如何用有限个栈模拟常数效率操作的队列?

    写这篇博客来源于一次面试的经历。经典面试题:如何用两个栈实现一个队列?它经常被拿来面试。如果对栈和队列比较掌握的人,就可以轻松的答出来。

    ShenduCC
  • 典型数据库架构设计与实践 | 架构师之路

    本文,将介绍数据库架构设计中的一些基本概念,常见问题以及对应解决方案,为了便于读者理解,将以“用户中心”数据库为例,讲解数据库架构设计的常见玩法。

    Javen
  • JSP引擎、JSP容器、Web服务器的区别

    广义上来说,JSP引擎是用来管理和运行Web应用程序的软件,而安装了JSP引擎的计算机就是Web服务器。

    Arebirth

扫码关注云+社区

领取腾讯云代金券