【Python机器学习】NLP分词——词的“情感”

2024-08-28 21:28

本文主要是介绍【Python机器学习】NLP分词——词的“情感”,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

VADER:一个基于规则的情感分析器

朴素贝叶斯


无论NLP流水线中使用的是单个词、n-gram、词干还是词元作为词条,每个词条都包含了一些信息,这些信息中一个重要部分是词的情感,即一个词所唤起的总体感觉或感情。这种度量短语或者文本块的情感的任务称为情感分析,是NLP中的一个常见应用。在很多公司中,NLP工程师要做的最主要的工作就是情感分析。

类似于研究/分析用户对商品的反馈,机器不会有人类的那种倾向性,也没有人类的情感触发器。而且,并不仅仅是人类才可以处理自然语言文本和从中提取信息甚至意义,NLP流水线也能够快速客观地处理大量用户反馈,而不会出现什么倾向性。同时,NLP流水线能够输入文本的正向性或者负向性以及任何其他的情感质量的数值等级。

另一个常见的情感分析应用是垃圾邮件或钓鱼消息的过滤。我们也希望自己的聊天机器人能够判断聊天信息中的情感以便能够合理地回复消息。甚至更重要的一点是:我们希望聊天机器人在输出语句之前能够知道该语句的情感倾向,从而引导机器人输出更加亲和、友好的语句。我们需要机器人能够度量要说的任何话的得体程度从而决定是否需要回复。

要度量一段文本的情感产生所谓的倾向性数值,我们希望NLP流水线和情感分析算法输出单个从-1到+1之间的浮点数。

有两种情感分词的方法,分别是:

  • 基于规则的算法,规则由人来撰写;
  • 基于机器学习的模型,模型是机器从数据中学习而得到的。

第一种情感分析的方法使用用户设计的规则(有时称为启发式规则)来度量文本的情感。一个常用的基于规则的方法是在文本中寻找关键词,并将每个关键词映射到某部字典或者映射上的数值得分或权重,例如这部字典可以是Python的dict。我们在字典中可以使用分词后的词干、词元或者n-gram词条,而不只是词。算法中的规则将迭加文档中每个关键词在字典中的情感得分。显然,在文本上运行我们的算法之前,我们必须要手工构建一步关键词及每个关键词的情感得分的字典。

第二中基于机器学习的方法利用一系列标注语句或者文档来训练机器学习模型以产生规则。机器学习的情感模型在经过训练以后能够处理输入文本并输出该文本的一个情感数值得分,该得分就像正向倾向性、垃圾程度和钓鱼程度一样。对于机器学习方法,需要大量标注好“正确”情感得分的文本数据。推文数据往往被用于这类方法,因为推文中的哈希标签往往可用于构建“自标注”的数据集。

VADER:一个基于规则的情感分析器

VADER算法时最早被成功提出的基于规则的情感分析算法,很多NLP包实现的是该算法的某种形式。NLTK包中的nltk.sentiment.vader实现了VADER算法。

下面是使用vaderSentiment的代码:

from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzersa=SentimentIntensityAnalyzer()
print(sa.lexicon)

上述代码呈现的是分词器最擅长处理的标点符合和表情符号,这样VADER才能更好地工作。如果在流水线中词干还原工具(或词形归并工具),需要将该工具也用于VADER词库,使单个词干或词元中的所有词的得分组合起来。

print([(tok,score) for tok,score in sa.lexicon.items()])

在VADER定义的7500个词条中,只有3个包含空格,其中两个实际上是n-gram,另一个是表达“kiss”的表情符号。

print(sa.polarity_scores(text="Python is very readable and it's great for NLP."))

VADER算法用3个不同的分数(正向、负向和中立)来表达情感极性的强度,然后将它们组合在一起得到一个复合的情感倾向性得分。

print(sa.polarity_scores(text="Python is not a bad choice for most applications."))

下面看上述基于规则的方法在前面提到的语句上的应用结果如何:

corpus=["Absolutely perfect! Love it! :-) :-) :-)","Horrible! Completely useless. :(","It was OK. Some good and some bad things."]
for doc in corpus:scores=sa.polarity_scores(doc)print('{:+}:{}'.format(scores['compound'],doc))

VADER的唯一不足在于,它只关注其词库中的7500个词条,而非文档中的所有词。

朴素贝叶斯

朴素贝叶斯模型视图从一系列文档集合中寻找对目标(输出)变量有预测作用的关键词。当目标变量是要预测的情感时,模型将寻找那些能预测该情感的词,朴素贝叶斯模型的一个好处是:其内部的系数会将词或词条映射为类似于VADER中的情感得分。只有这时,我们才不必受限于让人来决定这些分数应该是多少,机器将寻找任何其认为的“最佳”得分。

对于任一机器学习算法,首先必须要有一个数据集,即需要一些已经标注好正向情感的文本文档。nlpia包中有4个不同的情感数据集:

from nlpia.data.loaders import get_data
movies=get_data('hutto_movies')
print(movies.head().round(2))

print(movies.describe().round(2))

可以看到,该数据集中,对电影的评分区间在-4到+4之间。

下面使用分词器对所有电影评论文本进行切分,从而得到每篇评论文本的词袋,然后将他们放入DataFrame中:

import pandas as pd
from nltk.tokenize import casual_tokenize
from collections import Counter
pd.set_option('display.width',75)
bags_of_words=[]
for text in movies.text:bags_of_words.append(Counter(casual_tokenize(text)))
df_bows=pd.DataFrame.from_records(bags_of_words)
df_bows=df_bows.fillna(0).astype(int)
print(df_bows.shape)
print(df_bows.head())

上述代码中,词袋表格可能会快速增长到很大的的规模,特别是在没有使用大小写归一化、停用词过滤、词干还原和词形归并过程时更是如此。在这里可以考虑插入上述降维工具观察对流水线的影响。

现在我们有了朴素贝叶斯模型所需要的所有数据,利用这些数据可以从自然语言文本中寻找那些预测情感的关键词:

from sklearn.naive_bayes import MultinomialNB
nb=MultinomialNB()
nb=nb.fit(df_bows,movies.sentiment>0)
predicted_s=list(nb.predict_proba(df_bows)*8-4)
print(predicted_s[:9])
ps=[]
for i in range(len(predicted_s)):ps.append(list(predicted_s[i])[1])
movies['predicted_sentiment']=ps
movies['error']=(movies.predicted_sentiment-movies.sentiment).abs()
print(movies.error.mean().round(1))
movies['sentiment_ispositive']=(movies.sentiment>0).astype(int)
movies['predicted_ispositive']=(movies.predicted_sentiment>0).astype(int)
print(movies['''sentiment predicted_sentiment sentiment_ispositive predicted_ispositive'''.split()].head(8))
print((movies.predicted_ispositive == movies.sentiment_ispositive).sum()/len(movies))

可以看到,最终的点赞评级的正确率是93.44%。

只需要短短的几行代码,就可以构建一个不错非情感分析器。我们不需要像VADER一样构建一个包含7500个词及其对应情感得分的列表,而只需要给出一些文本及其标注。这就是机器学习和NLP的优势所在。

在另一种数据上,如果想和上面一样构建一个实际的情感分析器,要对训练数据进行分割。如果强行对所有的文本点赞或点差,那么一个随机猜测的MAE大概在4左右,因此,上面的情感分析器大概比随机猜测好一半:

products=get_data('hutto_products')
bags_of_words=[]
for text in products.text:bags_of_words.append(Counter(casual_tokenize(text)))
df_product_bows=pd.DataFrame.from_records(bags_of_words)
df_product_bows=df_product_bows.fillna(0).astype(int)
df_all_bows=pd.concat([df_bows,df_product_bows],ignore_index=True)
#=df_bows.append(df_product_bows)
print(df_all_bows.columns)
df_product_bows=df_all_bows.iloc[len(movies):][df_bows.columns]
df_product_bows=df_product_bows.fillna(0).astype(int)
print(df_product_bows.shape)
print(df_bows.shape)from sklearn.naive_bayes import MultinomialNB
nb=MultinomialNB()
nb=nb.fit(df_bows,movies.sentiment>0)
products['ispos']=(products.sentiment>0).astype(int)
products['predicted_ispositive']=nb.predict(df_product_bows.values).astype(int)
print(products.head())
print((products.predicted_ispositive==products.ispos).sum()/len(products))

因此,上述朴素贝叶斯模型在预测商品评论是否正向(即点赞)时表现得很糟糕。造成如此糟糕效果的一个原因是,利用casual_tokenize从商品文本中得到的词汇表中有2546个词条不在电影评论中。这个数目大约占电影评论分词结果的10%,这些词在朴素贝叶斯模型中不会有任何权重或者得分。另外,朴素贝叶斯模型也没有像VADER一样处理否定词。我们必须要将n-gram放在分词器中才能够将否定词(如“not”、“never”)与其修饰的可能要用的正向词关联起来。

这篇关于【Python机器学习】NLP分词——词的“情感”的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1115929

相关文章

Python实现图片分割的多种方法总结

《Python实现图片分割的多种方法总结》图片分割是图像处理中的一个重要任务,它的目标是将图像划分为多个区域或者对象,本文为大家整理了一些常用的分割方法,大家可以根据需求自行选择... 目录1. 基于传统图像处理的分割方法(1) 使用固定阈值分割图片(2) 自适应阈值分割(3) 使用图像边缘检测分割(4)

一文带你搞懂Python中__init__.py到底是什么

《一文带你搞懂Python中__init__.py到底是什么》朋友们,今天我们来聊聊Python里一个低调却至关重要的文件——__init__.py,有些人可能听说过它是“包的标志”,也有人觉得它“没... 目录先搞懂 python 模块(module)Python 包(package)是啥?那么 __in

使用Python实现图像LBP特征提取的操作方法

《使用Python实现图像LBP特征提取的操作方法》LBP特征叫做局部二值模式,常用于纹理特征提取,并在纹理分类中具有较强的区分能力,本文给大家介绍了如何使用Python实现图像LBP特征提取的操作方... 目录一、LBP特征介绍二、LBP特征描述三、一些改进版本的LBP1.圆形LBP算子2.旋转不变的LB

Python中__init__方法使用的深度解析

《Python中__init__方法使用的深度解析》在Python的面向对象编程(OOP)体系中,__init__方法如同建造房屋时的奠基仪式——它定义了对象诞生时的初始状态,下面我们就来深入了解下_... 目录一、__init__的基因图谱二、初始化过程的魔法时刻继承链中的初始化顺序self参数的奥秘默认

Python实现特殊字符判断并去掉非字母和数字的特殊字符

《Python实现特殊字符判断并去掉非字母和数字的特殊字符》在Python中,可以通过多种方法来判断字符串中是否包含非字母、数字的特殊字符,并将这些特殊字符去掉,本文为大家整理了一些常用的,希望对大家... 目录1. 使用正则表达式判断字符串中是否包含特殊字符去掉字符串中的特殊字符2. 使用 str.isa

python中各种常见文件的读写操作与类型转换详细指南

《python中各种常见文件的读写操作与类型转换详细指南》这篇文章主要为大家详细介绍了python中各种常见文件(txt,xls,csv,sql,二进制文件)的读写操作与类型转换,感兴趣的小伙伴可以跟... 目录1.文件txt读写标准用法1.1写入文件1.2读取文件2. 二进制文件读取3. 大文件读取3.1

使用Python实现一个优雅的异步定时器

《使用Python实现一个优雅的异步定时器》在Python中实现定时器功能是一个常见需求,尤其是在需要周期性执行任务的场景下,本文给大家介绍了基于asyncio和threading模块,可扩展的异步定... 目录需求背景代码1. 单例事件循环的实现2. 事件循环的运行与关闭3. 定时器核心逻辑4. 启动与停

基于Python实现读取嵌套压缩包下文件的方法

《基于Python实现读取嵌套压缩包下文件的方法》工作中遇到的问题,需要用Python实现嵌套压缩包下文件读取,本文给大家介绍了详细的解决方法,并有相关的代码示例供大家参考,需要的朋友可以参考下... 目录思路完整代码代码优化思路打开外层zip压缩包并遍历文件:使用with zipfile.ZipFil

Python处理函数调用超时的四种方法

《Python处理函数调用超时的四种方法》在实际开发过程中,我们可能会遇到一些场景,需要对函数的执行时间进行限制,例如,当一个函数执行时间过长时,可能会导致程序卡顿、资源占用过高,因此,在某些情况下,... 目录前言func-timeout1. 安装 func-timeout2. 基本用法自定义进程subp

Python实现word文档内容智能提取以及合成

《Python实现word文档内容智能提取以及合成》这篇文章主要为大家详细介绍了如何使用Python实现从10个左右的docx文档中抽取内容,再调整语言风格后生成新的文档,感兴趣的小伙伴可以了解一下... 目录核心思路技术路径实现步骤阶段一:准备工作阶段二:内容提取 (python 脚本)阶段三:语言风格调