机器学习7:词向量转换与文本分类
·
前言
在自然语言处理(NLP)中,词向量是将文本转换为数值型数据的重要手段,也是后续进行文本分类、情感分析等任务的基础。今天我们将通过两个案例,系统地学习词向量转换的原理及实际应用,并在此基础上完成一个基于朴素贝叶斯的评论情感分类任务。
一、词向量转换基础:CountVectorizer
1.1 什么是词向量?
计算机无法直接理解文本,我们需要将文本转化为数字向量。词向量就是将文本中的词语映射为数值特征的一种表示方式。最基础的方法是词袋模型(Bag of Words),统计每个词在文档中出现的次数。
1.2 基础案例
from sklearn.feature_extraction.text import CountVectorizer
texts = ["dog cat fish", "dog cat cat", "fish bird", "bird"]
# 建立模型,ngram_range=(1,1) 表示只考虑单个词
cv = CountVectorizer(ngram_range=(1, 1))
# 训练模型
cv_fit = cv.fit_transform(texts)
# 打印词频矩阵(稀疏格式)
print(cv_fit)
# 打印词库
print(cv.get_feature_names_out())
# 打印每个句子的完整词向量
print(cv_fit.toarray())
运行结果解析
cv_fit 输出的是稀疏矩阵,只记录非零值的位置和数量,节省内存。
get_feature_names_out() 输出词库,例如:['bird', 'cat', 'dog', 'fish']
toarray() 转换为二维数组,每行对应一个句子,每列对应一个词,值为该词在句子中出现的次数。
| 句子 | bird | cat | dog | fish |
|---|---|---|---|---|
| dog cat fish | 0 | 1 | 1 | 1 |
| dog cat cat | 0 | 2 | 1 | 0 |
| fish bird | 1 | 0 | 0 | 1 |
| bird | 1 | 0 | 0 | 0 |
核心理解:CountVectorizer 将文本变成了计算机可识别的“词频矩阵”。
二、综合实战:评论情感分类
2.1 环境准备与数据读取
# -*- coding: utf-8 -*-
import pandas as pd
import jieba
cp_content = pd.read_table(r".\差评.txt", encoding='gbk')
yzpj_content = pd.read_table(r".\优质评价.txt", encoding='gbk')
注意中文编码问题,文件首行加 # -*- coding: utf-8 -*-,并根据文件实际编码指定 encoding(如 gbk、utf-8)。
2.2 中文分词(使用 jieba)
def segment_text(contents):
segments = []
for content in contents:
results = jieba.lcut(content)
if len(results) > 1:
segments.append(results)
return segments
jieba.lcut()返回分词列表- 过滤掉长度为 1 的结果(通常是标点或单个无意义词)
- 分词结果保存为 Excel,方便后续查看。
2.3 去除停用词
stopwords = pd.read_csv(r".\StopwordsCN.txt", encoding='utf-8', engine='python', index_col=False)
def drop_stopwords(contents, stopwords):
segments_clean = []
for content in contents:
line_clean = [word for word in content if word not in stopwords]
segments_clean.append(line_clean)
return segments_clean
停用词表(StopwordsCN.txt)可从网上下载,包含“的、了、是”等常见无意义词,去除后可以减少噪声,提高分类准确率。
2.4 构建训练集并切分
cp_train = pd.DataFrame({'segments_clean': cp_fc_contents_clean_s, 'label': 1})
yzpj_train = pd.DataFrame({'segments_clean': yzpj_fc_content_clean_s, 'label': 0})
pj_train = pd.concat([cp_train, yzpj_train])
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)
- 标签定义:差评 = 1,优质评价 = 0
- 训练集/测试集默认按 75% / 25% 切分
2.5 词向量转换(关键步骤)
# 将分词列表拼接成空格分隔的字符串
words = [' '.join(seg) for seg in x_train]
vec = CountVectorizer(max_features=4000, lowercase=False, ngram_range=(1, 3))
vec.fit(words)
x_train_vec = vec.transform(words)
参数解读:
max_features=4000:只保留出现频率最高的 4000 个词,防止维度爆炸lowercase=False:中文无需小写转换ngram_range=(1, 3):保留 1~3 个连续词的组合(如“不喜欢”、“非常不好”),能捕捉更多语义信息
2.6 朴素贝叶斯分类
from sklearn.naive_bayes import MultinomialNB
classifier = MultinomialNB(alpha=0.1)
classifier.fit(x_train_vec, y_train)
MultinomialNB适用于多项式分布数据,适合文本分类alpha=0.1是平滑参数,防止概率为 0
2.7 模型评估
from sklearn import metrics
train_pr = classifier.predict(x_train_vec)
print(metrics.classification_report(y_train, train_pr))
test_words = [' '.join(seg) for seg in x_test]
test_pr = classifier.predict(vec.transform(test_words))
print(metrics.classification_report(y_test, test_pr))
输出包括精确率、召回率、F1-score,可以直观看到模型在训练集和测试集上的表现。
如果测试集准确率明显低于训练集,可能存在过拟合,可尝试减少特征数或增大训练数据。
2.8 预测新评论
s = "这个手机超好,我很喜欢"
s_seg = jieba.lcut(s)
s_clean = [w for w in s_seg if w not in stopwords]
s_vec = vec.transform([' '.join(s_clean)])
pred = classifier.predict(s_vec)
print("好评" if pred[0] == 0 else "差评")
最终可以判断该评论为 好评。
三、总结
| 模块 | 技术点 |
|---|---|
| 词向量转换 | CountVectorizer 基本用法、ngram 参数 |
| 中文处理 | jieba 分词、停用词过滤 |
| 分类模型 | 朴素贝叶斯(MultinomialNB) |
| 数据预处理 | pandas 读取、DataFrame 操作 |
| 模型评估 | classification_report 详解 |
更多推荐

所有评论(0)