【机器学习实战】词向量 + 朴素贝叶斯实现中文情感分析

什么是词向量

在自然语言处理(Natural Language Processing,NLP)任务中,文本是最基础也是最核心的数据形式。然而,计算机并不能像人类一样直接理解文字的含义,它只能对数字进行计算和建模。因此,如何将文本信息转化为数值形式,成为机器学习处理文本数据的首要问题。

词向量(Word Embedding)正是在这一背景下提出的一种重要表示方法

主流词向量模型

一、词袋模型

词袋模型(Bag of Words)是最早也是最基础的文本向量化方法之一。该方法将文本看作词语的集合,仅统计每个词在文档中出现的次数,而不考虑词语的顺序和语义关系。在词袋模型中,每个文档可以表示为一个高维向量,向量的每一维对应词表中的一个词,其取值表示该词在文档中的出现频率。

词袋模型实现简单、计算效率高,但其缺点也较为明显:一方面向量维度较高且稀疏,另一方面无法刻画词语之间的语义相似性,因此在复杂语义任务中的表现有限。

Python 示例代码:

python 复制代码
from sklearn.feature_extraction.text import CountVectorizer

texts = [
    "这家餐厅的菜很好吃",
    "服务态度非常好",
    "这家店的菜太难吃了"
]

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

print("词表:", vectorizer.get_feature_names_out())
print("向量表示:\n", X.toarray())

二、TF-IDF 模型

TF-IDF(Term Frequency--Inverse Document Frequency)是一种在词袋模型基础上引入权重机制的文本表示方法。其核心思想是:一个词在当前文档中出现得越频繁,同时在整个语料库中出现得越少,则该词对文档的区分能力越强。

与传统词频统计相比,TF-IDF 能有效降低"的、了、是"等高频但区分度较低词语的权重,从而突出文本中的关键词信息。因此,TF-IDF 被广泛应用于文本分类、信息检索和情感分析等任务中。

Python 示例代码:

python 复制代码
from sklearn.feature_extraction.text import TfidfVectorizer

texts = [
    "这家餐厅的菜很好吃",
    "服务态度非常好",
    "这家店的菜太难吃了"
]

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

print("词表:", tfidf.get_feature_names_out())
print("TF-IDF 向量:\n", X.toarray())

TF-IDF 在保证模型简单性的同时,显著提升了文本特征的区分能力,是传统机器学习情感分析中最常用的向量化方法。

三、Word2Vec

Word2Vec 是一种基于神经网络的词向量模型,其核心思想是通过上下文信息学习词语的语义表示。与传统基于词频的表示方法不同,Word2Vec 能够将词语映射为低维、稠密的向量,并使语义相近的词在向量空间中距离更近。

Word2Vec 主要包含两种训练模型:CBOW(通过上下文预测中心词)和 Skip-gram(通过中心词预测上下文)。该模型在捕捉词语语义相似性方面表现突出,是现代自然语言处理的重要基础方法之一。

Python 示例代码(gensim):

python 复制代码
from gensim.models import Word2Vec

sentences = [
    ["这家", "餐厅", "的", "菜", "很好吃"],
    ["服务", "态度", "非常", "好"],
    ["这家", "店", "的", "菜", "太", "难吃", "了"]
]

model = Word2Vec(
    sentences,
    vector_size=100,
    window=5,
    min_count=1,
    workers=4
)

查看某个词的词向量

python 复制代码
print(model.wv["好"])

计算相似词

python 复制代码
print(model.wv.most_similar("好"))

四、GloVe

GloVe(Global Vectors for Word Representation)是一种结合全局词频统计信息的词向量模型。与 Word2Vec 侧重局部上下文不同,GloVe 利用整个语料库中词与词的共现关系进行建模,从而学习词语的向量表示。

在实际应用中,GloVe 常以预训练词向量的形式使用,能够在多种自然语言处理任务中取得稳定效果。

词向量转化的小例子

下面通过一个简单示例,演示如何使用 CountVectorizer 将文本转化为词袋向量表示。

python 复制代码
from sklearn.feature_extraction.text import CountVectorizer
texts=["dog cat fish","dog cat cat","fish bird", 'bird']
cont =  []
#实例化一个模型
cv = CountVectorizer(max_features=6,ngram_range=(1,3))  #,统计每篇文章中每个词出现的频率次数
#训练此模型
cv_fit=cv.fit_transform(texts)#每个词在这篇文章中出现的次数
print(cv_fit)
# 打印出模型的全部词库
print(cv.get_feature_names())
#打印出每个语句的词向量
print(cv_fit.toarray())
# #打印出所有数据求和结果
# print(cv_fit.toarray().sum(axis=0))#

输出结果

  1. 示例数据说明
python 复制代码
texts = ["dog cat fish", "dog cat cat", "fish bird", "bird"]

该示例中包含 4 条英文文本,每条文本可以看作一条简单的"评论"或"文档"。

这些文本由少量词语组成,适合用于演示词袋模型的基本原理。

  1. CountVectorizer 的作用
python 复制代码
cv = CountVectorizer(max_features=6, ngram_range=(1, 3))

CountVectorizer 是 scikit-learn 中用于构建**词袋模型(Bag of Words)**的工具,其核心功能是:

建立词表(Vocabulary)

统计每个词或词组在文档中出现的次数

将文本转换为数值向量

参数说明:

max_features=6

表示只保留词频最高的前 6 个特征(词或词组),用于控制向量维度,防止特征过多。

ngram_range=(1, 3)

表示同时考虑:

1-gram(单词,如 dog)

2-gram(连续两个词,如 dog cat)

3-gram(连续三个词,如 dog cat fish)

这使得模型不仅能捕捉单个词,还能捕捉局部的词序信息。

  1. 模型训练与文本转换
python 复制代码
cv_fit = cv.fit_transform(texts)

该语句完成了两个步骤:

fit:从所有文本中学习词表(统计词频并筛选特征)

transform:将每条文本转换为词频向量

返回的 cv_fit 是一个稀疏矩阵,用于高效存储高维文本特征。

  1. 查看稀疏矩阵结果
python 复制代码
print(cv_fit)

输出结果为稀疏矩阵格式,只显示非零元素的位置和值,表示:

行索引:文本编号

列索引:词表中特征的索引

值:该特征在文本中出现的次数

这种表示方式可以节省大量内存,适合大规模文本数据。

  1. 查看模型词表
python 复制代码
print(cv.get_feature_names())

该语句用于输出模型最终保留的所有特征,即词袋模型的词表。

由于设置了 ngram_range=(1,3),词表中不仅包含单个词,还可能包含多个连续词组成的短语。例如:

单词:dog、cat

二元词组:dog cat

三元词组:dog cat fish

  1. 查看每条文本的词向量表示
python 复制代码
print(cv_fit.toarray())

该语句将稀疏矩阵转换为普通的二维数组,方便观察。

每一行表示一条文本

每一列对应词表中的一个特征

数值表示该特征在对应文本中出现的次数

例如,如果某一列对应特征 cat,那么数值为 2 表示该文本中 cat 出现了两次。

项目案例

为了训练一个能够自动判断评论情感倾向(好评或差评)的模型,本文选取苏宁易购商品评论数据作为实验数据来源。相关评论数据通过网络爬虫方式获取,并根据情感极性分为优质评价(好评)和差评两类,为后续的文本向量化和模型训练提供数据基础。

1. 数据读取与初步整理

实验中分别使用两个文本文件存储不同情感类别的评论数据,其中:

优质评价.txt:存储正向情感评论(好评)

差评.txt:存储负向情感评论(差评)

使用 Pandas 对文本数据进行读取,代码如下:

python 复制代码
import pandas as pd
 
cp_content = pd.read_table(r".\差评.txt",encoding='gbk')
yzpj_content = pd.read_table(r".\优质评价.txt",encoding='gbk')

中文评论的分词处理(jieba)

在中文文本处理中,词语之间不存在天然的空格分隔,因此在进行词向量构建之前,必须先对评论文本进行分词操作。本文采用 jieba 分词库对苏宁易购评论数据进行分词处理。

jieba 提供了两种常用分词接口:

jieba.cut():返回生成器,适合大规模数据

jieba.lcut():直接返回列表,使用更加方便

本实验中采用 jieba.lcut() 方法。

差评文本分词

python 复制代码
import jieba
import pandas as pd

cp_segments = []

提取差评文本内容

python 复制代码
contents = cp_content['content'].values.tolist()

对每条评论进行分词

python 复制代码
for text in contents:
    words = jieba.lcut(text)
    if len(words) > 1:          # 过滤分词结果过短的评论
        cp_segments.append(words)

将分词结果保存为 DataFrame

python 复制代码
cp_fc_results = pd.DataFrame({'content': cp_segments})
cp_fc_results.to_excel('cp_fc_results.xlsx', index=False)

好评文本分词

python 复制代码
yzpj_segments = []

提取好评文本内容

python 复制代码
contents = yzpj_content['content'].values.tolist()

for text in contents:
    words = jieba.lcut(text)
    if len(words) > 1:
        yzpj_segments.append(words)

保存分词结果

python 复制代码
yzpj_fc_results = pd.DataFrame({'content': yzpj_segments})
yzpj_fc_results.to_excel('yzpj_fc_results.xlsx', index=False)

至此,好评与差评的分词结果已分别存储,为后续文本清洗和特征提取做好准备。

停用词去除

分词完成后,文本中仍然包含大量无实际语义价值的词语,如"的""了""是"等。这类词被称为停用词,若不加处理,会对模型训练产生干扰,因此需要将其移除。

导入停用词表

python 复制代码
stopwords_df = pd.read_csv(
    r'./StopwordsCN.txt',
    encoding='utf8',
    engine='python'
)

stopwords = stopwords_df['stopword'].values.tolist()

定义去停用词函数

python 复制代码
def remove_stopwords(texts, stopwords):
    cleaned_texts = []
    for text in texts:
        clean_words = [word for word in text if word not in stopwords]
        cleaned_texts.append(clean_words)
    return cleaned_texts

差评去停用词

python 复制代码
cp_contents = cp_fc_results['content'].values.tolist()
cp_clean = remove_stopwords(cp_contents, stopwords)

好评去停用词

python 复制代码
yzpj_contents = yzpj_fc_results['content'].values.tolist()
yzpj_clean = remove_stopwords(yzpj_contents, stopwords)

基于朴素贝叶斯的情感分类模型

构建训练数据集

为实现监督学习,需要为评论数据添加情感标签:

差评:1

好评:0

python 复制代码
cp_train = pd.DataFrame({
    'segments_clean': cp_clean,
    'label': 1
})

yzpj_train = pd.DataFrame({
    'segments_clean': yzpj_clean,
    'label': 0
})

pj_train = pd.concat([cp_train, yzpj_train], axis=0)
pj_train.to_excel('pj_train.xlsx', index=False)

划分训练集与测试集

python 复制代码
from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(
    pj_train['segments_clean'].values,
    pj_train['label'].values,
    random_state=0
)

文本向量化(CountVectorizer)

由于 CountVectorizer 接受的是字符串形式输入,因此需要先将分词列表重新拼接成字符串。

python 复制代码
train_texts = [' '.join(words) for words in x_train]

from sklearn.feature_extraction.text import CountVectorizer

vectorizer = CountVectorizer(
    max_features=4000,
    lowercase=False,
    ngram_range=(1, 3)
)

vectorizer.fit(train_texts)

训练朴素贝叶斯模型

python 复制代码
from sklearn.naive_bayes import MultinomialNB
from sklearn import metrics

classifier = MultinomialNB(alpha=0.1)
classifier.fit(vectorizer.transform(train_texts), y_train)

训练集评估

python 复制代码
train_pred = classifier.predict(vectorizer.transform(train_texts))
print(metrics.classification_report(y_train, train_pred))

测试集评估

python 复制代码
test_texts = [' '.join(words) for words in x_test]
test_pred = classifier.predict(vectorizer.transform(test_texts))

print(metrics.classification_report(y_test, test_pred))

模型交互测试

训练完成后,可以通过命令行输入文本,实时测试模型的情感预测效果。

python 复制代码
while True:
    text = input('请输入一段评价(输入 exit 退出):')
    if text == 'exit':
        break

    words = jieba.lcut(text)
    words_clean = [w for w in words if w not in stopwords]
    text_vec = vectorizer.transform([' '.join(words_clean)])

    result = classifier.predict(text_vec)

    if result[0] == 1:
        print("预测结果:差评")
    else:
        print("预测结果:优质评价")
相关推荐
Σίσυφος19002 小时前
视觉矩阵 之 单应矩阵
人工智能·算法·矩阵
叫我:松哥2 小时前
基于Flask的心理健康咨询管理与智能分析,集成AI智能对话咨询、心理测评(PHQ-9抑郁量表/GAD-7焦虑量表)、情绪追踪记录、危机预警识别
大数据·人工智能·python·机器学习·信息可视化·数据分析·flask
合新通信 | 让光不负所托2 小时前
氟化液、矿物油、改性硅油三种冷却液,分别适合搭配什么功率等级的浸没式液冷光模块?
人工智能·安全·云计算·信息与通信·光纤通信
啊阿狸不会拉杆2 小时前
《机器学习》第五章-集成学习(Bagging/Boosting)
人工智能·算法·机器学习·计算机视觉·集成学习·boosting
Programmer boy2 小时前
我是一名软件行业从业者,AI主要帮助我做哪些工作?
人工智能
Coder_Boy_2 小时前
基于SpringAI的在线考试系统-成绩管理功能实现方案
开发语言·前端·javascript·人工智能·spring boot
lxs-2 小时前
探索自然语言处理(NLP)的旅程:从分词到文本生成
人工智能·自然语言处理
大模型任我行2 小时前
腾讯:RAG生成器感知的排序模型
人工智能·语言模型·自然语言处理·论文笔记
玩转AI6662 小时前
AI-论文智能降重工具
人工智能