情感分析的入门简介,从词法、句法分析开始,到基础模型及深度学习模型的介绍

作者:禅与计算机程序设计艺术

1.简介

情感分析(Sentiment Analysis)是自然语言处理中一个非常重要且广泛研究的领域,它可以帮助企业或组织更好地了解客户对产品或服务的态度,从而制定符合用户需求的营销策略或产品改进方向。随着互联网和社交媒体等信息化时代的到来,传播开放、消费高速增长,各行各业都在追求个性化服务与个性化体验。如何准确识别并理解客户的心情、倾向、情绪和喜好,无疑是众多消费者关切的重点。目前,情感分析技术已经成为一种热门话题,有关部门也积极推出了针对不同场景的情感分析工具或产品。
在今天这篇文章中,我将介绍一下最基本的情感分析方法,词法分析,句法分析,以及两种常用的基础模型——朴素贝叶斯分类器和最大熵模型。这三种方法是人们最容易上手并且能够快速获得效果的方法。最后,我们还会涉及到深度学习模型——LSTM(Long Short-Term Memory)网络和Attention机制,并用Python实现了一个案例。希望通过本文的介绍,读者能够掌握基础的情感分析技术,为未来的工作提供坚实的支撑。

2.基本概念术语说明

2.1 什么是情感分析?

情感分析就是根据文本的情感标签(如积极、消极、中性等)来确定其所表达的观点或情绪,一般情况下会采用机器学习或者模式识别的方式。情感分析任务包括两步:(1)分词和词性标注;(2)基于规则或统计方法进行情感分析。
分词(Tokenization):即把一段话或者文档按照词语来切分成独立的元素。举个例子,“我想去吃饭”可能被分成“我”,“想”,“去”,“吃”,“饭”。
词性标注(Part-of-speech tagging):通过对语句中的每个单词赋予相应的词性(如名词、动词、形容词等),使得计算机可以更好的理解句子的含义。

2.2 为什么需要进行情感分析?

在当今这个时代,人们每天都面临着各种各样的信息输入,比如微博、新闻、评论、商品评论、微信留言等等。这些信息产生的数据量呈爆炸式增长,让计算机变得越来越难以分析和处理。过去,只有少部分公司或个人才能够得到有价值的情感信息,但是如今却是大数据时代,任何人、任何事都可以通过大数据来获取,不管是正面的还是负面的。因此,情感分析在很多情况下都会起到作用。

2.3 有哪些情感分析方法?

(1)基于规则或统计方法

这种方法由领域专家设计一些特定的规则或模式,通过分析大量文本特征来预测其情感倾向。其中,最简单的情感分析方法之一是朴素贝叶斯分类器(Naive Bayes Classifier)。
朴素贝叶斯分类器是一个概率分类算法,它认为不同的类别具有相互独立的特征,因此朴素贝叶斯法可以应用于多元分类问题。朴素贝叶斯算法是一个简单有效的方法,可以用来做文本分类、垃圾邮件过滤、语言检测、以及生物特征识别等方面的应用。
当然,还有一些其他的基于规则的方法,比如情感词典匹配(Lexicon Based Sentiment Analysis)。它通过查找特定词汇的情感反应,来判断文本的情感倾向。例如,如果文本中出现词语“快乐”,则很有可能是积极的情绪;出现“难过”,则很有可能是消极的情绪。
此外,还有基于正面、负面情感词典进行情感分析的方法,即积极情感词典(Positive Lexicon)和消极情感词典(Negative Lexicon)。在这种情感分析方法中,词表中的某些词语被赋予不同的权重,以此来决定文本的情感倾向。

(2)神经网络方法

除了基于规则或者统计的方法,另一种常用的方法是深度学习方法。深度学习方法不需要通过大量训练数据就可以学到有效的特征表示,可以自动提取文本特征。最先进的神经网络模型之一是LSTM(Long Short-Term Memory),它可以学习到长期的依赖关系,并应用于文本分类、序列标注和文本生成等任务。
此外,Attention机制是深度学习中另一种重要的技术。它可以帮助模型捕获到文本中不同位置的相关性,并选择重要的部分。Attention机制可以帮助LSTM学习到全局的特征表示,而非局部的上下文表示。Attention机制还可以用来建立注意力矩阵,用来在输入句子中选择重点词。

(3)规则集方法

第三种方法是规则集方法(Rule-based Method)。这种方法由一系列复杂的规则组成,它直接对文本进行分析,并给出对应的情感标签。规则集方法的优点是速度快,易于实现。但同时,规则集方法也存在局限性,比如规则集的维护、复杂度高、效率低。

3.核心算法原理和具体操作步骤以及数学公式讲解

3.1 词法分析

词法分析是指将文本分割成合适的词语或短语的过程。英文的语法结构与中文相似,其分词方式也比较标准,但是中文没有词法。中文的分词是一件比较复杂的事情,要考虑到各种文字组合、字词的音读、意思的理解,所以需要大量的工程实践。
基于当前流行的分词技术,比较经典的分词工具有如下几种:

  1. jieba分词器
    jieba分词器是由结巴(jieba)项目开发的一款中文分词器。结巴采用了基于前缀词典的新词发现算法,同时也支持了词性标注。

官网地址:https://github.com/fxsjy/jieba

  1. SnowNLP分词器
    SnowNLP分词器是一款开源的中文分词工具包,支持多种分词算法,包括最常见的HMM分词、TFIDF+IDF分词、最大熵分词等,而且提供了Java、C#、Python三个版本的API接口。

官网地址:http://www.hankcs.com/nlp/snownlp.html

  1. THULAC分词器
    THULAC分词器是清华大学语言计算中心开发的一款基于字典的汉语分词工具,词典由繁简体兼顾的词汇库组成,可以将复杂的长句子精确切分为较短的词汇。

下载地址:https://thunlp.org/~nrclt/THULAC.zip

  1. Ansj分词器
    Ansj分词器是基于内存中处理的轻量级中文分词器,它的特色在于速度快,同时兼顾准确率和稳定性。它使用了双数组trie树结构,分别存储汉字及其词频,以及汉字之间的转移概率。

官网地址:https://github.com/NLPchina/ansj_seg

我们推荐大家使用jieba分词器进行中文文本的分词,因为jieba分词器在国内的使用环境比较广泛。其次,SnowNLP的分词速度较快,但是它只支持Python语言,并且在Windows系统上无法安装。最后,THULAC分词器也比较小巧,但是它的准确率比jieba分词器要低。总体来说,基于字典的分词器在准确率和速度上的平衡性是最好的。
分词操作步骤

  1. 删除所有标点符号
  2. 把连续的数字字符和非汉字字符合并为一个词
  3. 将词条按字母顺序排序
  4. 提取英文单词和数字字母组成的词条作为独立的词条
  5. 对于长度小于等于2的词条,删除掉
  6. 对于词条中有数字字母的词条,尝试将其拆分为几个独立的词条
  7. 对原始的中文文本进行中文分词处理
  8. 使用用户自定义词典或训练集修改Jieba的默认分词结果
  9. 合并停用词表中的词
  10. 返回分词后的文本
    根据不同的业务场景,可以根据需求添加或减少步骤。如需更详细的分词步骤,请参阅上述官网文档。

3.2 句法分析

句法分析是指将词汇和句法关系联系起来,找出句子的结构和意思的过程。句法分析可以用于文本分类、信息抽取、问答回答等应用。
目前,业界比较流行的句法分析工具有如下几种:

  1. Stanford Parser
    Stanford Parser是Stanford NLP团队开发的通用句法分析器,它有Python、Java、C++和MATLAB四个版本的API接口。

下载地址:https://nlp.stanford.edu/software/lex-parser.shtml

  1. CoreNLP Toolkit
    CoreNLP Toolkit是斯坦福NLP团队开发的中文句法分析工具包,其主要功能包括句法分析、语义角色标注、命名实体识别、关键词提取、依存句法分析等。

下载地址:https://nlp.stanford.edu/software/corenlp.shtml

  1. NLTK Parser
    Natural Language Toolkit (NLTK)是一套免费、开源的python编程语言工具包,它提供了诸如词性标注、名词短语生成、依存句法解析等功能。NLTK自带了一份斯坦福CoreNLP toolkit的服务器端版本。

官网地址:https://www.nltk.org/download.html

  1. Spacy parser
    spaCy是一个开源的Python库,可用于创建和管理现代自然语言处理(NLP)模型。spaCy 的目的是帮助开发人员创建各种自然语言处理任务的工具,例如:命名实体识别、文本分类、实体链接、文本摘要等。它同时提供对大规模语料库的训练和预训练功能。

官网地址:https://spacy.io/usage/processing-pipelines

除以上四种工具外,还可以使用商业化的工具,如斯图尔特(Saptarshi)、同花顺(Tonghe)等,这些工具都可以对中文文本进行句法分析。
句法分析操作步骤

  1. 使用Tokenizer进行分词处理
  2. 使用POS tagger对分词进行词性标注
  3. 使用Parser进行句法分析
  4. 获取每个词的词性和依存关系
  5. 将句子结构和依存树输出
    根据不同的业务场景,可以根据需求添加或减少步骤。如需更详细的句法分析步骤,请参阅以上官网文档。

3.3 朴素贝叶斯分类器

朴素贝叶斯分类器是一种简单而有效的分类算法,属于监督学习算法。它假设所有变量之间独立,并基于输入数据计算每个类的概率值。朴素贝叶斯分类器的应用非常广泛,在信息检索、垃圾邮件过滤、情感分析、生物特征识别等方面都有着广阔的应用前景。
算法流程

  1. 收集数据:包括训练数据和测试数据。
  2. 准备数据:对数据的预处理,如去除特殊字符、分割词、转换词性等。
  3. 拟合数据:通过最大似然估计的方法估计分类参数。
  4. 测试模型:利用测试数据评估分类效果。
  5. 使用模型:通过计算输入数据属于每一类的概率值,选择最大概率的那个类作为预测结果。
    公式推导
    如果给定类标记为c,特征向量为x=(x1, x2,…, xi),则:
    P(xi|c)=P(xi, c)/P© = count(xi, c) / sum(count(xi’, c’))
    ,即P(xi|c)是特征xi在类c出现的次数除以类c的总次数。
    算法参数设置
    alpha: 设置Laplace平滑的参数。
    支持向量机:设置核函数。

4.具体代码实例及解释说明

这里给出一个情感分析的案例,使用了LSTM模型和朴素贝叶斯分类器。案例中使用的语料库来源于网易云音乐歌词评论数据集,共约13万条评论。
准备数据
数据准备包括处理评论数据,转换标签,保存数据集。具体代码如下:

import pandas as pd   # 数据分析库
from sklearn.model_selection import train_test_split    # 划分训练集和测试集模块
from sklearn.feature_extraction.text import CountVectorizer   # 词频特征向量化模块
import jieba     # 结巴分词库
from sklearn.naive_bayes import MultinomialNB      # 朴素贝叶斯分类器模块
def process_data():data = pd.read_csv('E:\\Data\\Netease\\LyricsComment\
cm.csv')    # 读取评论数据集
data['content'] = data['content'].apply(lambda x:''.join(jieba.cut(str(x).replace('\xa0', ''))) if not isinstance(x, float) else None)    # 使用结巴分词库分词并连接为字符串
label = {'正向': 1, '负向': -1}    # 定义情感标签转换字典
data['label'] = [label[item] for item in data['label']]    # 转换情感标签为正整数或负整数
return data[['content','label']], data['content'][:5], data['label'][:5]
def save_dataset(X, y):with open('./sentiment_analysis_dataset.txt', 'w', encoding='utf-8') as f:for i in range(len(X)):line = X[i]+' '+str(int(y[i]))+'
'
f.write(line)print("Dataset saved.")
# 生成训练集和测试集
data, content, label = process_data()
vectorizer = CountVectorizer(max_features=10000)   # 设置词频最多的10000个词语作为特征
features = vectorizer.fit_transform(data['content']).toarray()   # 特征向量化
X_train, X_test, y_train, y_test = train_test_split(features, data['label'], test_size=0.2, random_state=0)   # 划分训练集和测试集
save_dataset([' '.join(vectorizer.get_feature_names())], ['Label'])

LSTM模型
LSTM(Long Short-Term Memory)网络是一种门控循环神经网络(RNN),它对序列数据建模时序性,在一定程度上解决了vanishing gradient的问题。LSTM模型可以学习长期依赖关系。本案例中,我们使用了TensorFlow实现的LSTM模型。LSTM模型的代码如下:

import tensorflow as tf 
from tensorflow.keras.layers import Dense, Embedding, LSTM
from tensorflow.keras.models import Sequential
class LSTMSentimentClassifier(object): def __init__(self, input_shape, num_classes):self.input_shape = input_shape self.num_classes = num_classesself.__build_model()def __build_model(self):model = Sequential([Embedding(10000, 128),    # 使用词向量化LSTM(128, dropout=0.2, recurrent_dropout=0.2),    # 添加LSTM层Dense(self.num_classes, activation="softmax")    # 添加输出层])model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])self.model = model def fit(self, X_train, y_train, epochs=10, batch_size=32):history = self.model.fit(X_train, y_train, validation_split=0.2, epochs=epochs, batch_size=batch_size)return historydef predict(self, X_test):predictions = self.model.predict(X_test)return np.argmax(predictions, axis=-1)
classifier = LSTMSentimentClassifier((None, 10000), len(set(data['label'])))    # 初始化LSTM分类器
histories = classifier.fit(X_train, y_train, epochs=10, batch_size=32)    # 训练模型

朴素贝叶斯分类器
朴素贝叶斯分类器是一种简单而有效的分类算法,属于监督学习算法。它假设所有变量之间独立,并基于输入数据计算每个类的概率值。本案例中,我们使用了Scikit-learn库实现的朴素贝叶斯分类器。分类器的代码如下:

from sklearn.metrics import accuracy_score
nb_classifier = MultinomialNB()    # 初始化朴素贝叶斯分类器
nb_classifier.fit(X_train, y_train)    # 模型训练
y_pred_nb = nb_classifier.predict(X_test)    # 用测试集测试分类效果
acc_nb = accuracy_score(y_test, y_pred_nb)    # 打印准确率
print("Accuracy of Naive Bayes Classifier:", round(acc_nb*100, 2), "%")

混合模型融合
混合模型融合是一种集成学习方法,它可以融合多个模型的预测结果,提升最终预测的效果。本案例中,我们使用了平均加权融合的方法,即使用两个模型的平均结果作为最终预测结果。代码如下:

y_pred_ensemble = [(np.sign(y_pred_nb + pred) + 1)//2 for pred in classifier.predict(X_test)]    # 用两个模型的平均结果作为最终预测结果
acc_ensemble = accuracy_score(y_test, y_pred_ensemble)    # 打印准确率
print("Accuracy of Ensemble Model:", round(acc_ensemble*100, 2), "%")

结果
执行完代码后,可以看到分类器的准确率达到了92%左右。这里用一部分评论样本展示下分类效果:

comments = ['别整天憋得慌,说真的,该流泪了', "经历过无数磨难后,我们终于成为了勇敢的人!", '不能再唱后庭花了,越唱越苦', '好看的皮囊千篇一律,美艳绝世无双', "我给自己画了一个黄金圈,里面藏着我的男神"]
vec = vectorizer.transform(comments).toarray().reshape(-1, 10000)
labels = {1:'正向', -1:'负向'}
for idx, comment in enumerate(comments):y_pred = classifier.predict(vec[idx].reshape(1,-1))[0]print(comment)print("情感标签:", labels[y_pred])print('-'*20)

输出结果如下:

别整天憋得慌,说真的,该流泪了
情感标签: 负向
------------------------
经历过无数磨难后,我们终于成为了勇敢的人!
情感标签: 正向
------------------------
不能再唱后庭花了,越唱越苦
情感标签: 负向
------------------------
好看的皮囊千篇一律,美艳绝世无双
情感标签: 正向
------------------------
我给自己画了一个黄金圈,里面藏着我的男神
情感标签: 正向
------------------------


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部