阶段2
|
NLP传统 · 第9课/共30课
📖 第09课:Word2Vec
🎯 课程目标
Word2Vec开创了分布式词表示的时代。理解Word2Vec是理解所有现代词嵌入的前提。
- 理解CBOW和Skip-gram两种架构
- 使用gensim训练Word2Vec模型
- 探索词向量的语义特性:相似度、类比、线性关系
📐 核心原理
分布式假设
"出现在相似上下文中的词具有相似的语义" —— J.R. Firth, 1957
两种架构
- CBOW:上下文词 → 预测中心词。速度快,适合大语料
- Skip-gram:中心词 → 预测上下文词。慢但更精细
💡 经典类比:vec("国王") - vec("男人") + vec("女人") ≈ vec("女王")
🔬 训练Word2Vec模型
CBOW与Skip-gram训练
from gensim.models import Word2Vec
sentences = [
['自然', '语言', '处理', '是', '人工智能', '的', '分支'],
['深度', '学习', '推动', '了', '自然', '语言', '处理'],
['机器', '学习', '是', '人工智能', '的', '核心'],
['神经网络', '在', '自然', '语言', '处理', '中', '广泛', '应用'],
['词', '向量', '是', '词', '的', '数值', '表示'],
['Word2Vec', '通过', '上下文', '学习', '词', '向量'],
['词', '嵌入', '技术', '在', 'NLP', '中', '很', '重要'],
['计算机', '视觉', '和', '自然', '语言', '处理', '是', 'AI', '的', '两大', '方向'],
['文本', '分类', '是', '自然', '语言', '处理', '的', '基本', '任务'],
['情感', '分析', '属于', '文本', '分类', '的', '一种'],
]
model_cbow = Word2Vec(sentences, vector_size=50, window=3, min_count=1, sg=0, epochs=100, seed=42)
print("=== CBOW模型 ===")
print(f"词表大小: {len(model_cbow.wv)}")
print(f"向量维度: {model_cbow.wv.vector_size}")
model_sg = Word2Vec(sentences, vector_size=50, window=3, min_count=1, sg=1, epochs=100, seed=42)
print("\n=== Skip-gram模型 ===")
word = '自然'
print(f"\n'{word}'的向量(CBOW, 前10维): {model_cbow.wv[word][:10]}")
if '语言' in model_cbow.wv:
sim_words = model_cbow.wv.most_similar('语言', topn=5)
print(f"\n与'语言'最相似的词(CBOW):")
for w, s in sim_words:
print(f" {w}: {s:.4f}")
=== CBOW模型 ===
词表大小: 44
向量维度: 50
=== Skip-gram模型 ===
'自然'的向量(CBOW, 前10维): [-0.00317759 0.01438905 -0.00014437 0.00904658 -0.00126335 -0.00911889
0.0070724 0.02187837 -0.010876 0.01119402]
与'语言'最相似的词(CBOW):
人工智能: 0.4637
中: 0.3871
是: 0.3739
处理: 0.3575
应用: 0.3559
✅ 验证通过:代码实机运行结果如上
🔧 词向量的语义特性
词类比与相似度
from gensim.models import Word2Vec
import numpy as np
sentences = [
['国王', '女王', '男人', '女人', '王子', '公主'],
['中国', '北京', '法国', '巴黎', '日本', '东京'],
['苹果', '香蕉', '水果', '蔬菜', '西红柿'],
['汽车', '火车', '飞机', '交通', '出行'],
['猫', '狗', '宠物', '动物', '鱼'],
['大学', '学院', '学校', '教育', '学生'],
['医生', '医院', '病人', '治疗', '健康'],
['程序员', '代码', '计算机', '软件', '开发'],
]
model = Word2Vec(sentences, vector_size=100, window=5, min_count=1, sg=1, epochs=200, seed=42)
print("=== 词类比实验 ===")
try:
result = model.wv.most_similar(positive=['女王', '男人'], negative=['国王'], topn=3)
print(f"国王 - 男人 + 女王 = ? → {result}")
except Exception as e:
print(f"词类比:{e}")
word_pairs = [('国王', '女王'), ('中国', '北京'), ('猫', '狗'), ('大学', '学校'), ('苹果', '汽车')]
print("\n=== 词相似度 ===")
for w1, w2 in word_pairs:
if w1 in model.wv and w2 in model.wv:
sim = model.wv.similarity(w1, w2)
print(f" sim('{w1}', '{w2}') = {sim:.4f}")
try:
odd = model.wv.doesnt_match(['苹果', '香蕉', '汽车', '水果'])
print(f"\n不匹配词: {odd}")
except:
pass
=== 词类比实验 ===
国王 - 男人 + 女王 = ? → [('公主', 0.20177878439426422), ('苹果', 0.16739119589328766), ('飞机', 0.1651587039232254)]
=== 词相似度 ===
sim('国王', '女王') = 0.2118
sim('中国', '北京') = -0.0582
sim('猫', '狗') = -0.0180
sim('大学', '学校') = 0.0777
sim('苹果', '汽车') = -0.0561
不匹配词: 苹果
✅ 验证通过:代码实机运行结果如上
📝 练习
动手练习
- 用维基百科中文语料训练大规模Word2Vec
- 对比不同window_size对词向量的影响
- 实现负采样的简化版本
🧬
🏆 成就解锁:向量炼金师
掌握了Word2Vec,理解了从离散符号到连续向量的转换。
🧪 扩展:Word2Vec训练技巧
超参数选择指南
| 参数 | 推荐值 | 说明 |
| vector_size | 100-300 | 太小丢失信息,太大噪声增加 |
| window | 5 | 语法任务用3-5,语义任务用8-10 |
| min_count | 5 | 低于5次的词太稀疏,训练不稳定 |
| sg | 1(Skip-gram) | 小语料用SG,大语料用CBOW |
| negative | 5-20 | 负采样数,越多越精确但越慢 |
| epochs | 10-50 | 小语料需要更多轮次 |
负采样 vs 层次Softmax
- 负采样:随机选几个负样本,O(K)复杂度,适合大词表
- 层次Softmax:用霍夫曼树组织词表,O(log|V|)复杂度,适合小词表
- 实践建议:词表>10万用负采样,否则两者差异不大
🔬 扩展实践:Word2Vec的工程部署
大规模训练注意事项
- 内存:加载300维2M词表的向量需要约2.4GB内存
- 增量训练:gensim支持online训练,新语料可增量更新
- 向量归一化:推理时先归一化可加速余弦相似度计算
- 量化压缩:float32→float16可减半内存,精度损失很小
词向量质量评估
评估词向量质量的两个维度:
- 内部评估:词类比任务(king-queen=man-woman),直接衡量向量空间结构
- 外部评估:在下游任务(NER、分类)上的性能,衡量实用性
注意:内部评估好不代表外部评估好。在特定领域,领域特定的小语料词向量可能比通用大语料词向量更好。
🧪 扩展:Word2Vec训练技巧
超参数选择指南
| 参数 | 推荐值 | 说明 |
| vector_size | 100-300 | 太小丢失信息,太大噪声增加 |
| window | 5 | 语法任务用3-5,语义任务用8-10 |
| min_count | 5 | 低于5次的词训练不稳定 |
| sg | 1(Skip-gram) | 小语料用SG,大语料用CBOW |
| negative | 5-20 | 负采样数 |
| epochs | 10-50 | 小语料需要更多轮次 |
词向量质量评估
评估词向量质量的两个维度:
- 内部评估:词类比任务(king-queen=man-woman)
- 外部评估:在下游任务(NER、分类)上的性能
注意:内部评估好不代表外部评估好。领域特定的小语料词向量可能比通用大语料词向量更好。
📚 参考文献
推荐阅读
- Jurafsky & Martin. Speech and Language Processing (3rd ed). 第9课相关章节
- Manning, Raghavan & Schutze. Introduction to Information Retrieval
- Goodfellow, Bengio & Courville. Deep Learning. 自然语言处理章节
在线资源
- NLTK文档: https://www.nltk.org/
- spaCy文档: https://spacy.io/
- gensim文档: https://radimrehurek.com/gensim/
- sklearn文本处理: https://scikit-learn.org/stable/modules/feature_extraction.html
Word2Vec - 关键概念速查
| 概念 | 定义 | 应用 |
| Pipeline | 处理流水线,各步骤串行执行 | 文本处理系统 |
| Tokenization | 将文本切分为词/子词单元 | 分词、子词分割 |
| Embedding | 将离散符号映射到连续向量空间 | 词向量、句向量 |
| Feature Engineering | 从原始数据提取有效数值特征 | 传统ML模型输入 |
| Fine-tuning | 在预训练模型基础上微调 | BERT等模型适配 |
本课要点回顾
- Word2Vec是NLP技术栈的重要组件
- 理解原理比调用API更重要——知道为什么比知道怎么做更有价值
- 代码验证是学习的好方法——动手跑一遍胜过读十遍
- 从简单方法开始,逐步过渡到复杂方法——简单方法的基线作用不可替代
- 实践出真知——用自己的数据跑一遍,发现课本上没写的问题
❓ 常见问题FAQ
- Q: 这个方法的数据需求量是多少?
- A: 传统方法通常需要几百到几千条标注数据。深度学习方法通常需要万级以上。数据量少时优先用传统方法。
- Q: 如何处理中文的特殊情况?
- A: 中文没有天然词边界,分词质量直接影响下游效果。建议:1)使用领域词典优化分词 2)比较不同分词工具的效果 3)对关键任务做分词错误分析。
- Q: 传统方法和深度学习如何选择?
- A: 考虑三个因素:1)数据量——少数据用传统方法 2)可解释性——需要解释选传统方法 3)计算资源——资源受限选传统方法。深度学习在大数据+强算力场景下优势明显。
- Q: 如何评估和调优?
- A: 1)建立基线:用最简单方法确定性能下限 2)错误分析:找出模型最常犯的错误类型 3)针对性改进:根据错误模式选择改进策略 4)避免过拟合:在独立测试集上验证。
- Q: 生产环境部署要注意什么?
- A: 1)延迟要求:简单模型推理更快 2)吞吐量:批处理提升吞吐 3)模型版本:做好版本管理和回滚 4)监控:持续跟踪线上模型性能 5)A/B测试:新模型上线前小流量验证。
🛠️ 实用工具箱
| 工具 | 用途 | 安装 |
| jieba | 中文分词 | pip install jieba |
| gensim | 词向量训练 | pip install gensim |
| scikit-learn | 传统ML | pip install scikit-learn |
| nltk | 英文NLP工具 | pip install nltk |
| spaCy | 工业NLP管线 | pip install spacy |
| hanlp | 中文NLP工具包 | pip install hanlp |
| fasttext | Facebook文本分类 | pip install fasttext |
| textblob | 简单NLP接口 | pip install textblob |