Bootstrap

NLP之中文自然语言处理工具库:SnowNLP(情感分析/分词/自动摘要)

情感分析的基本流程通常包括:

  • 自定义爬虫抓取文本信息;
  • 使用Jieba工具进行中文分词、词性标注;
  • 定义情感词典提取每行文本的情感词;
  • 通过情感词构建情感矩阵,并计算情感分数;
  • 结果评估,包括将情感分数置于0.5到-0.5之间,并可视化显示。

SnowNLP

SnowNLP是一个常用的Python文本分析库,是受到TextBlob启发而发明的。由于当前自然语言处理库基本都是针对英文的,而中文没有空格分割特征词,Python做中文文本挖掘较难,后续开发了一些针对中文处理的库,例如SnowNLP、Jieba、BosonNLP等。注意SnowNLP处理的是unicode编码,所以使用时请自行decode成unicode。

Snownlp主要功能包括:

  • 中文分词(算法是Character-Based Generative Model)
  • 词性标注(原理是TnT、3-gram 隐马)
  • 情感分析
  • 文本分类(原理是朴素贝叶斯)
  • 转换拼音、繁体转简体
  • 提取文本关键词(原理是TextRank)
  • 提取摘要(原理是TextRank)、分割句子
  • 文本相似(原理是BM25)

安装和其他库一样,使用pip安装即可。

pip install snownlp
   
   
1、snownlp 常见功能及用法:

   
   
  1. # -*- coding: utf-8 -*-
  2. from snownlp import SnowNLP
  3. s = SnowNLP( u"这本书质量真不太好!")
  4. print( "1、中文分词:\n",s.words)
  5. """
  6. 中文分词:
  7. 这 本书 质量 真 不 太 好 !
  8. """
  9. print( "2、词性标注:\n",s.tags)
  10. print( "3、情感倾向分数:\n",s.sentiments)
  11. """
  12. 情感分数:
  13. 0.420002029202
  14. """
  15. print( "4、转换拼音:\n",s.pinyin)
  16. print( "5、输出前4个关键词:\n",s.keywords( 4))
  17. print( "6、输出关键(中心)句:\n",s.summary( 1))
  18. print( "7.1、输出tf:\n",s.tf)
  19. print( "7.2、输出idf:\n",s.idf)
  20. n = SnowNLP( '「繁體字」「繁體中文」的叫法在臺灣亦很常見。')
  21. print( "8、繁简体转换:\n",n.han)
  22. """
  23. 繁简体转换:
  24. 「繁体字」「繁体中文」的叫法在台湾亦很常见。
  25. """

除此之外,还可以进行文本相似度计算:

 

SnowNLP情感分析也是基于情感词典实现的,其简单的将文本分为两类,积极和消极,返回值为情绪的概率,越接近1为积极,接近0为消极。

2、统计各情感分数段出现的评率并绘制对应的柱状图

对txt文件逐行进行情感倾向值计算,代码如下:


   
   
  1. # -*- coding: utf-8 -*-
  2. from snownlp import SnowNLP
  3. import codecs
  4. import os
  5. source = open( "data.txt", "r", encoding= 'utf-8')
  6. line = source.readlines()
  7. sentimentslist = []
  8. for i in line:
  9. s = SnowNLP(i)
  10. print(s.sentiments)
  11. sentimentslist.append(s.sentiments)
  12. import matplotlib.pyplot as plt
  13. import numpy as np
  14. plt.hist(sentimentslist, bins = np.arange( 0, 1, 0.01), facecolor = 'g')
  15. plt.xlabel( 'Sentiments Probability')
  16. plt.ylabel( 'Quantity')
  17. plt.title( 'Analysis of Sentiments')
  18. plt.show()

结果如下:

3、利用新的数据训练情感分析模型

在实际的项目中,需要根据实际的数据重新训练情感分析的模型,大致分为如下的几个步骤:

  • 准备正负样本,并分别保存,如正样本保存到pos.txt,负样本保存到neg.txt
  • 利用snownlp训练新的模型
  • 保存好新的模型

重新训练情感分析的代码如下所示:


   
   
  1. #coding:UTF-8
  2. from snownlp import sentiment
  3. if __name__ == "__main__":
  4. # 重新训练模型
  5. sentiment.train( './neg.txt', './pos.txt')
  6. # 保存好新训练的模型
  7. sentiment.save( 'sentiment.marshal')

使用训练后的模型需注意:


   
   
  1. 注意:若是想要利用新训练的模型进行情感分析,需要修改代码中的调用模型的位置。
  2. data_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'sentiment.marshal')
4、snownlp情感分析的源码解析

snownlp中支持情感分析的模块在sentiment文件夹中,其核心代码为__init__.py

如下是Sentiment类的代码:


   
   
  1. class Sentiment( object):
  2. def __init__( self):
  3. self.classifier = Bayes() # 使用的是Bayes的模型
  4. def save( self, fname, iszip=True):
  5. self.classifier.save(fname, iszip) # 保存最终的模型
  6. def load( self, fname=data_path, iszip=True):
  7. self.classifier.load(fname, iszip) # 加载贝叶斯模型
  8. # 分词以及去停用词的操作
  9. def handle( self, doc):
  10. words = seg.seg(doc) # 分词
  11. words = normal.filter_stop(words) # 去停用词
  12. return words # 返回分词后的结果
  13. def train( self, neg_docs, pos_docs):
  14. data = []
  15. # 读入负样本
  16. for sent in neg_docs:
  17. data.append([self.handle(sent), 'neg'])
  18. # 读入正样本
  19. for sent in pos_docs:
  20. data.append([self.handle(sent), 'pos'])
  21. # 调用的是Bayes模型的训练方法
  22. self.classifier.train(data)
  23. def classify( self, sent):
  24. # 1、调用sentiment类中的handle方法
  25. # 2、调用Bayes类中的classify方法
  26. ret, prob = self.classifier.classify(self.handle(sent)) # 调用贝叶斯中的classify方法
  27. if ret == 'pos':
  28. return prob
  29. return 1-probclass Sentiment( object):
  30. def __init__( self):
  31. self.classifier = Bayes() # 使用的是Bayes的模型
  32. def save( self, fname, iszip=True):
  33. self.classifier.save(fname, iszip) # 保存最终的模型
  34. def load( self, fname=data_path, iszip=True):
  35. self.classifier.load(fname, iszip) # 加载贝叶斯模型
  36. # 分词以及去停用词的操作
  37. def handle( self, doc):
  38. words = seg.seg(doc) # 分词
  39. words = normal.filter_stop(words) # 去停用词
  40. return words # 返回分词后的结果
  41. def train( self, neg_docs, pos_docs):
  42. data = []
  43. # 读入负样本
  44. for sent in neg_docs:
  45. data.append([self.handle(sent), 'neg'])
  46. # 读入正样本
  47. for sent in pos_docs:
  48. data.append([self.handle(sent), 'pos'])
  49. # 调用的是Bayes模型的训练方法
  50. self.classifier.train(data)
  51. def classify( self, sent):
  52. # 1、调用sentiment类中的handle方法
  53. # 2、调用Bayes类中的classify方法
  54. ret, prob = self.classifier.classify(self.handle(sent)) # 调用贝叶斯中的classify方法
  55. if ret == 'pos':
  56. return prob
  57. return 1-prob

从上述的代码中,classify函数和train函数是两个核心的函数,其中,train函数用于训练一个情感分类器,classify函数用于预测。在这两个函数中,都同时使用到的handle函数,handle函数的主要工作为:

  1. 对输入文本分词
  2. 去停用词

情感分类的基本模型是贝叶斯模型Bayes,对于贝叶斯模型,可以参见文章简单易学的机器学习算法——朴素贝叶斯

 

中文自然语言分析系统:http://ictclas.nlpir.org/nlpir/

本文参考于:

情感分析——深入snownlp原理和实践

自然语言处理库之snowNLP

;