Bootstrap

NLP03-NLP的三个阶段的情感分析案例

一、规则驱动阶段的情感分析

(一)案例描述:

通过预定义的情感词典(如积极词、消极词列表)实现文本的情感分析。

(二)方法特点:

1. 基于语言学专家构建的词典和规则。
2. 计算文本中积极词和消极词的出现次数,并根据规则判断情感倾向。

(三)示例

1. 定义情感词典

# 正向词典
positive_words=["happy","love","good","wonderful","great"]
# 负向词典
negative_words=["bad","sad","terrible","poor"]

2.  情感处理

def rule_base_sentiment_analysis(text):
    # 2.1 正面词计数
    positive_count=sum(1 for word in text.split() if word in positive_words)
    # 2.2 负面词计数
    negative_count = sum(1 for word in text.split() if word in negative_words)

此处的text.split():

将字符串text按空格分割成一个单词列表。例如,如果text = "I love this product",那么text.split()的结果是["I", "love", "this", "product"]

 3. 情感判断

    if positive_count>negative_count:
        return "Positive"
    elif positive_count<negative_count:
        return "Negative"
    else:
        return "Neutral"

4. 示例文本

text = "The movie was good but the ending was terrible ."
print(rule_base_sentiment_analysis(text))

运行结果:

完整代码如下:

# 1. 定义情感词典
# 正向词典
positive_words=["happy","love","good","wonderful","great"]
# 负向词典
negative_words=["bad","sad","terrible","poor"]

# 2. 情感处理
def rule_base_sentiment_analysis(text):
    # 2.1 正面词计数
    positive_count=sum(1 for word in text.split() if word in positive_words)
    # 2.2 负面词计数
    negative_count = sum(1 for word in text.split() if word in negative_words)

    # text.split():
    # 将字符串text按空格分割成一个单词列表。例如,如果text = "I love this product",那么text.split()的结果是["I", "love", "this", "product"]。
    # 3. 情感判断
    if positive_count>negative_count:
        return "Positive"
    elif positive_count<negative_count:
        return "Negative"
    else:
        return "Neutral"
# 4. 示例文本
text = "The movie was good but the ending was terrible ."
print(rule_base_sentiment_analysis(text))

特别提醒:Python 自带的 split() 函数默认是以空格作为分隔符来分割字符串,所以若想让“terrible”被识别为一个负面词汇,必须在标点符号前加空格才能保证分割结果正确。

因此,使用nltk进行分词效果更好。

(四)示例拓展(使用nltk进行分词)

1. 安装nltk

2. 手动安装nltk_data(数据包)

见本文最上方,可直接下载。(注意要解压到与源代码同一个根目录下)

3. 导入分词包word_tokenize

from nltk.tokenize import word_tokenize

4.  使用nltk库分词并计数

# 2. 情感处理
def rule_base_sentiment_analysis(text):
    # 2.1 使用nltk库分使用nltk库分词
    tokens = word_tokenize(text)
    print(f"分词后:{tokens}")
    # 2.2 正面词计数
    positive_count=sum(1 for word in tokens if word in positive_words)
    # 2.3 负面词计数
    negative_count = sum(1 for word in tokens if word in negative_words)

5. 其余稍作修改后完整代码如下:

from nltk.tokenize import word_tokenize
# 1. 定义情感词典
# 正向词典
positive_words=["happy","love","good","wonderful","great"]
# 负向词典
negative_words=["bad","sad","terrible","poor"]

# 2. 情感处理
def rule_base_sentiment_analysis(text):
    # 2.1 使用nltk库分使用nltk库分词
    tokens = word_tokenize(text)
    print(f"分词后:{tokens}")
    # 2.2 正面词计数
    positive_count=sum(1 for word in tokens if word in positive_words)
    # 2.3 负面词计数
    negative_count = sum(1 for word in tokens if word in negative_words)

    # 3. 情感判断
    if positive_count>negative_count:
        return "Positive"
    elif positive_count<negative_count:
        return "Negative"
    else:
        return "Neutral"
# 4. 示例文本
text = "The movie was good but the ending was terrible."
print(rule_base_sentiment_analysis(text))

运行结果:

可以看到使用nltk库分词,避免了标点符号未分割问题。

二、统计学习阶段的情感分析

(一)案例描述:

使用文本向量化(如TF-IDF)和机器学习算法(如朴素贝叶斯)进行情感分类。

(二)方法特点:

1. 利用标注数据集训练分类器。
2. 通过统计方法提取文本特征。

(三)示例(基于朴素贝叶斯的情感分析)

1. 安装scikit-learn

pip install scikit-learn

 2. 导入相关包

# nb_sentiment——基于朴素贝叶斯的情感分析
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.model_selection import train_test_split
  • TfidfVectorizer:用于将文本数据转化为 TF-IDF 特征矩阵。
  • MultinomialNB:朴素贝叶斯分类器,适用于文本分类任务,特别是多项式分布的情况。
  • train_test_split:用于将数据集分割为训练集和测试集。

3.  示例数据集

texts = ["I love this product", "This is a bad experience", "Excellent quality", "Terrible service"]
labels = ["Positive", "Negative", "Positive", "Negative"]

4. 文本向量化

vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(texts)

TfidfVectorizer 是 Scikit-learn 库中用于文本数据向量化的工具,它将文本转换为数值特征(通常是矩阵格式),使其能够被机器学习算法处理。fit_transform()TfidfVectorizer 类中的方法,它的功能是:

  1. 拟合 (fit):学习文本数据中的词汇(即创建一个字典,记录所有在数据集中出现的单词)。
  2. 转换 (transform):将文本数据转换成对应的 TF-IDF 特征矩阵

逐行解释代码:

vectorizer = TfidfVectorizer()

作用:创建 TfidfVectorizer 对象
它有很多参数(例如 stop_words 用来指定停用词,ngram_range 用来指定要考虑的词组的长度范围等),默认情况下,它会进行以下操作:
(1)小写化:将所有文本转换为小写。
(2)去除标点符号:将标点符号从文本中删除。
(3)去除停用词(默认停用词:英语中的常见词,如 "the", "is", "in" 等)如果没有指定。
(4)词频计算:计算每个词在文档中出现的频率。

X = vectorizer.fit_transform(texts)

做以下操作:
(1)学习词汇 (fit)
fit() 方法会基于 texts 训练 vectorizer。它会查看所有文本内容,并从中提取出所有不同的单词(词汇表)。也就是说,它构建了一个词袋模型(bag-of-words model),记录下所有在 texts 中出现过的词。
(2)转换文本为特征矩阵 (transform)
transform() 方法会根据 fit() 得到的词汇表,把每个文本转换成一个 稀疏矩阵,每一行代表一个文本,每一列代表词汇表中的一个单词。矩阵中的每个值是词语的 TF-IDF 值。
(3)返回稀疏矩阵
fit_transform() 会返回一个稀疏矩阵 X,其形状是 (n_samples, n_features),即每个文本的特征向量。每个特征对应于词汇表中的一个单词,值则是该单词在文本中的 TF-IDF 权重。 

TF-IDF的计算:

参考 TF-IDF的计算

举个例子:

假设我们有以下三个文本:

  1. "I love this product"
  2. "This is a bad experience"
  3. "Excellent quality"

所以最后稀疏矩阵的结果为:

假设有 3 个文本,并且从中提取出了 5 个特征(单词),则 X 可能是一个 3x5 的矩阵。每一行对应一个文本,每一列对应一个词汇表中的单词,矩阵的值是相应的 TF-IDF 权重

5. 训练分类器

X_train, X_test, y_train, y_test = train_test_split(X, labels, test_size=0.2)
model = MultinomialNB()
model.fit(X_train, y_train)

逐行解释代码:

X_train, X_test, y_train, y_test = train_test_split(X, labels, test_size=0.2)

 参数解释:

  • X:是之前通过 TfidfVectorizer 转换的特征矩阵(TF-IDF 值),每行表示一个文本,每列表示一个词的权重。
  • labels:是文本数据的标签(目标值),比如 "Positive" 或 "Negative"。
  • test_size=0.2:表示测试集占整个数据集的 20%,剩下的 80% 用于训练。你也可以指定一个 train_size 来控制训练集的比例。

train_test_split 会:

  • Xlabels 对应的内容按照给定的比例划分成两个部分:训练集和测试集

假设 X 共有 4 个文本数据,labels 中有 4 个标签,执行这行代码后,X_trainy_train 将包含 80%(3个文本)的训练数据和标签,X_testy_test 则包含 20%(1个文本)的测试数据和标签。

model = MultinomialNB()

作用:创建一个 Multinomial Naive Bayes(多项式朴素贝叶斯)模型。
MultinomialNB 是一种常见的朴素贝叶斯分类器,特别适用于分类任务中的文本数据。它假设每个特征(即每个词)的出现概率符合多项式分布(特别适合处理计数数据或离散数据,如文本中的词频)。

这种分类器的核心思想是通过计算每个类别的条件概率来预测新数据的标签。在文本分类任务中,朴素贝叶斯分类器通常表现良好,特别是对于高维稀疏数据(如 TF-IDF 特征矩阵)。

model.fit(X_train, y_train)

作用:使用 训练数据(X_train)和对应的 标签(y_train)来训练分类器。
fit() 方法:
(1)计算模型中各个类别(如 Positive 和 Negative)的 先验概率(各个类别出现的概率)。
(2)计算各个 特征(单词)在每个类别下的条件概率:即某个单词在某一类别中出现的概率。
(3)通过最大化每个类别的似然函数来学习模型参数,使得模型能够根据输入的特征(TF-IDF 权重)预测文本的类别。

6. 测试

test_text = ["The product is of terrible quality"]
test_data = vectorizer.transform(test_text)
test_y = model.predict(test_data)
print(test_y)

逐行解释代码:

test_text = ["The product is of terrible quality"]

作用:定义测试文本 

test_data = vectorizer.transform(test_text)

context:在训练时我们已经使用 TfidfVectorizer 来将文本转换成特征矩阵(即一堆数字),那么,test_text = ["The product is of terrible quality"] 是我们需要预测的文本。为了让模型进行预测,必须把这个文本 转化为和训练时相同的格式,即 TF-IDF 特征矩阵。

作用:这一行代码的作用就是把你想预测的 新文本(test_text) 转换成你在训练时所使用的 相同的数字特征格式。

怎么转换?

由vectorizer.transform() 做以下几件事:
(1)读取测试文本中的每个词,并在之前的词汇表中找出它的位置。
(2)对比词汇表,找到 "The", "product", "is", "quality" 等词的 TF-IDF 值。
(3)对于没有出现在词汇表中的词(比如 "terrible"),它会分配一个权重值(通常是 0),因为模型在训练过程中没有见过这个词。

最终结果如:

test_data = [0.5, 0.1, 0.3, 0.0, 0.0, 0.6, 0.0, 0.0]

test_y = model.predict(test_data)

作用:用已经训练好的 朴素贝叶斯分类器(model)来对 测试数据(test_data) 进行分类预测,并将预测的结果保存到 test_y 中。

模型预测的过程:

  1. 计算特征的概率:模型会通过 朴素贝叶斯算法 根据训练数据中学到的词频和词类分布来计算 test_data 中每个词出现时属于某个类别的概率。

  2. 选择最可能的类别:最终,模型会选择那个概率最高的类别作为预测结果。

完整代码:

# pip install scikit-learn
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.model_selection import train_test_split

# 示例数据集
texts = ["I love this product", "This is a bad experience", "Excellent quality", "Terrible service"]
labels = ["Positive", "Negative", "Positive", "Negative"]

# 文本向量化
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(texts)

# 训练分类器
X_train, X_test, y_train, y_test = train_test_split(X, labels, test_size=0.2)
model = MultinomialNB()
model.fit(X_train, y_train)

# 测试
test_text = ["The product is of terrible quality"]
test_data = vectorizer.transform(test_text)
test_y = model.predict(test_data)
print(test_y)

三、深度学习阶段的情感分析

(一)案例描述

通过深度神经网络(如LSTM)或预训练模型(如BERT)实现情感分析。

(二)方法特点

1. 使用大规模语料库训练模型。
2. 模型能够捕获文本的复杂语义和上下文信息。

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;