【NLP学习】IMDB 情感分类实战:Word2Vec + 逻辑回归完整解析
在自然语言处理(NLP)入门阶段,如何把文本变成“模型能理解的数字”,往往是第一个真正的门槛。
本文将通过一个完整的实战案例,带你从原始文本出发,使用 Word2Vec 构建词向量表示,并结合逻辑回归(Logistic Regression),完成 IMDB 电影评论的情感分类任务。
整个流程覆盖了从数据预处理到模型评估的完整闭环,适合作为 NLP 特征工程与传统机器学习结合的经典示例。
一、项目背景与任务定义
1.1 任务目标
基于 IMDB 电影评论数据集,判断一条评论的情感倾向:
1:正面(positive)0:负面(negative)这是一个标准的 二分类文本情感分析问题。
1.2 技术方案选择
本文采用的整体技术路线如下:
- 使用 NLTK 进行文本分词与停用词过滤
- 使用 Gensim 训练 Word2Vec 模型,将词映射为稠密向量
- 通过词向量平均的方式,将句子转换为固定长度向量
- 使用 逻辑回归 完成情感二分类
- 为什么选择这个组合?下面做一个简单对比:
| 方法 | 优点 | 缺点 |
|---|---|---|
| TF-IDF + 逻辑回归 | 实现简单、可解释性强 | 无法建模词语语义相似性 |
| Word2Vec + 逻辑回归 | 能捕捉语义关系,泛化能力好 | 平均操作会丢失词序信息 |
| BERT + 微调 | 效果最好 | 计算资源消耗大,工程复杂 |
Word2Vec + 逻辑回归 在效果与成本之间取得了不错的平衡,是非常经典、也非常适合入门理解的 NLP 实战方案。
二、环境准备
2.1 依赖安装
pip install numpy pandas tqdm nltk gensim scikit-learn 2.2 NLTK 数据下载
首次运行需要下载分词器与停用词表:
import nltk nltk.download("punkt") nltk.download("stopwords") 三、数据集说明
本项目使用 Stanford 提供的 IMDB Movie Review Dataset( IMDB 电影评论数据集),共包含 50,000 条影评,正负样本各占一半。
- 数据格式(CSV):
| 字段 | 说明 |
|---|---|
text | 评论文本 |
label | 情感标签(1=正面,0=负面) |
- 数据划分:
data/ └── imdb/ ├── imdb_train.csv # 25,000 条训练样本 └── imdb_test.csv # 25,000 条测试样本 四、项目结构
Word2Vec/ ├── data/ │ └── imdb/ │ ├── imdb_train.csv │ └── imdb_test.csv ├── models/ # 训练好的模型 ├── src/ │ └── imdb_word2vec.py # 主程序 └── docs/ └── IMDB 情感分类实战.md 这种结构便于 数据、代码和文档解耦,也更符合真实工程实践。
五、核心代码解析
5.1 数据加载
defload_data(train_path:str, test_path:str):"""加载训练集与测试集""" train_df = pd.read_csv(train_path) test_df = pd.read_csv(test_path)return train_df, test_df 逻辑非常直接:分别读取训练集和测试集,返回 DataFrame 供后续处理。
5.2 文本预处理(分词 + 去停用词)
文本预处理是 NLP 的第一步,其目标是降低噪声、统一输入形式。
from nltk.tokenize import word_tokenize from nltk.corpus import stopwords stop_words =set(stopwords.words("english"))deftokenize_text(text_series):return text_series.progress_apply(lambda x:[ word for word in word_tokenize(x.lower())if word notin stop_words ])- 示例:
输入: "This movie is great! I really enjoyed it." 输出: ['movie', 'great', '!', 'really', 'enjoyed', '.'] - 说明:
- 全部转为小写,减少词表规模
- 去除停用词(the / is / a 等)以降低无信息噪声
5.3 训练 Word2Vec 模型
deftrain_word2vec_model( tokens, vector_size=100, window=5, min_count=5, sg=1, workers=4, epochs=5): model = Word2Vec( sentences=tokens, vector_size=vector_size, window=window, min_count=min_count, sg=sg, workers=workers, epochs=epochs )return model - 本实验中使用的关键参数如下:
| 参数 | 值 | 说明 |
|---|---|---|
vector_size | 300 | 较高维度,捕捉更多语义信息 |
window | 5 | 标准窗口大小 |
min_count | 40 | 过滤低频词,IMDB 语料较大,阈值可设高一些 |
sg | 1 | 使用 Skip-gram 算法 |
epochs | 5 | 训练轮数 |
5.4 句子向量化方法
Word2Vec 只能生成词向量,但分类器需要的是句子级特征。
最简单、也最常用的方法是 词向量平均:
s ⃗ = 1 n ∑ i = 1 n w i ⃗ \vec{s} = \frac{1}{n} \sum_{i=1}^{n} \vec{w_i} s=n1i=1∑nwi
defsentence_to_vec(tokens, model, vector_size=100):"""将句子转换为词向量的平均值""" vecs =[model.wv[word]for word in tokens if word in model.wv]iflen(vecs)==0:return np.zeros(vector_size)# 处理全部 OOV 的情况return np.mean(vecs, axis=0)- 其中,
w2v_model.wv返回的是一个KeyedVectors对象,它只负责“词 → 向量”的查询与相似度计算,不包含训练相关内容。 - 注意:
- 该方法会丢失词序信息,因此表达能力有限,但胜在简单、稳定、易解释。
- "我喜欢你"和"你喜欢我"的向量相同。
- 更好的方法包括 TF-IDF 加权平均、Doc2Vec、或使用 RNN/Transformer。
5.5 embedding映射:构建特征矩阵
这一步是连接 Word2Vec 和分类器的关键桥梁—将所有文本转换为统一格式的特征矩阵,供机器学习模型使用。
(1) 整体流程

(2) 数据维度变化
| 阶段 | 数据形式 | 维度 |
|---|---|---|
| 原始数据 | 文本字符串 | 25,000 条评论 |
| 分词后 | 词语列表 | 每条评论 N N N个词 |
| Word2Vec 映射 | 词向量矩阵 | 每个词 → 300 维向量 |
| 句子向量化 | 句子向量 | 每条评论 → 300 维向量 |
| 最终输入 | 特征矩阵 X \mathbf{X} X | (25000, 300) |
(3) 代码实现
# 将所有句子转换为向量,堆叠成特征矩阵 X_train = np.vstack([sentence_to_vec(t, w2v_model, vector_size)for t in train_df["tokens"]]) X_test = np.vstack([sentence_to_vec(t, w2v_model, vector_size)for t in test_df["tokens"]])print(X_train.shape)# (25000, 300)print(X_test.shape)# (25000, 300)# 标签 y_train = train_df["label"]# (25000,) y_test = test_df["label"]# (25000,)(4) 映射示例
# 单条评论的映射过程 text ="This movie is great!" tokens =['movie','great','!']# 分词后(已去停用词)# 查询每个词的向量 movie_vec = w2v_model.wv['movie']# shape: (300,) great_vec = w2v_model.wv['great']# shape: (300,)# '!' 不在词汇表中,跳过# 取平均得到句子向量 sentence_vec = np.mean([movie_vec, great_vec], axis=0)# shape: (300,)- 经过这一步,我们得到了:
- X_train: (25000, 300) 的特征矩阵,每行是一条评论的向量表示
- y_train: (25000,) 的标签数组,0 或 1
- 这正是 scikit-learn 等机器学习库所需要的标准输入格式。
5.6 逻辑回归分类器
有了特征矩阵 X \mathbf{X} X和标签 y \mathbf{y} y,就可以使用任意分类器进行训练。这里选择逻辑回归作为分类器:
(1) 为什么选择逻辑回归?
| 优点 | 说明 |
|---|---|
| 简单高效 | 训练速度快,适合作为 baseline |
| 可解释性 | 可以分析特征权重 |
| 适合稠密特征 | 300 维的句子向量正好适用 |
(2) 代码实现
from sklearn.linear_model import LogisticRegression deftrain_model(X_train, y_train):"""训练逻辑回归分类器""" clf = LogisticRegression(max_iter=1000) clf.fit(X_train, y_train)return clf - 核心思想:两者各司其职,组成完整的文本分类 pipeline。
- Word2Vec 负责「特征提取」——将文本转换为捕捉语义信息的向量;
- 逻辑回归负责「分类决策」——根据这些向量判断情感极性。
5.7 模型评估
from sklearn.metrics import accuracy_score, classification_report defevaluate_model(clf, X_test, y_test):"""评估模型性能""" y_pred = clf.predict(X_test) acc = accuracy_score(y_test, y_pred) report = classification_report(y_test, y_pred)return acc, report 六、运行流程
完整的执行流程如下:
1. 加载数据 ├── 读取 imdb_train.csv(25,000 条) └── 读取 imdb_test.csv(25,000 条) 2. 文本预处理 ├── 分词(word_tokenize) └── 去除停用词 3. 训练 Word2Vec ├── 输入:分词后的训练集 ├── 输出:词向量模型 └── 保存模型到 models/ 目录 4. 句子向量化 ├── 训练集 → X_train (25000, 300) └── 测试集 → X_test (25000, 300) 5. 训练逻辑回归 └── 输入 X_train, y_train 6. 评估模型 └── 在测试集上计算准确率和分类报告 运行命令:
python src/imdb_word2vec.py 七、总结
本文以 IMDB 电影评论情感分类为例,完整演示了 Word2Vec + 逻辑回归 在文本分类任务中的实际应用流程。从原始文本出发,经过分词、去停用词、词向量训练、句子向量构建,最终完成情感预测,形成了一条清晰、可复现的 NLP 处理链路。
在该方案中,Word2Vec 负责将文本映射到语义向量空间,逻辑回归负责基于这些向量进行分类决策。两者分工明确,使得整个模型结构简单、训练高效,也非常适合作为文本分类任务的 baseline。
需要注意的是,词向量平均的方法会丢失词序和词重要性信息,因此模型性能存在一定上限。实际应用中,可以通过 TF-IDF 加权平均、Doc2Vec 或引入更复杂的深度模型来进一步提升效果。
总体而言,这一实战的核心价值在于帮助理解:文本是如何一步步转化为模型可学习的数值特征的。掌握这一过程,对后续学习更复杂的 NLP 模型具有重要意义。