4、词嵌入技术入门:Word2Vec原理(CBOW与Skip-gram)、Gensim库实战、词向量可视化
好,咱们进入正题。词嵌入,说白了就是把文字变成计算机能理解的数字。你想想看,计算机不认识「苹果」这个词,但它认识一串浮点数。Word2Vec 就是干这个的——把每个词映射到一个稠密的向量空间里。
我记得刚入行那会儿,还在用 one-hot 编码做文本分类。一个词就是一个 10 万维的稀疏向量,训练起来慢得要命,而且「苹果」和「香蕉」之间毫无相似度可言。后来接触到 Word2Vec,才真正体会到什么叫「语义相近的词,向量也相近」。
4.1 核心思想:分布假说
Word2Vec 的理论基础其实很简单——分布假说:
「一个词的含义,由它周围的词决定。」
说白了就是「物以类聚,词以群分」。比如「苹果」经常和「吃」、「水果」、「甜」一起出现,而「华为」经常和「手机」、「系统」、「芯片」一起出现。Word2Vec 就是通过这种上下文关系,把词映射到向量空间。
4.2 两种模型:CBOW 与 Skip-gram
Word2Vec 有两种训练方式,我分别讲讲。
4.2.1 CBOW(Continuous Bag of Words)
CBOW 的思路是:用上下文词,预测中心词。
举个例子,句子是「我 喜欢 吃 苹果」。窗口大小为 2 时,上下文词是「我」「喜欢」「吃」,目标词是「苹果」。模型的任务就是根据「我」「喜欢」「吃」这三个词,猜出「苹果」。
CBOW 适合高频词,训练速度更快。我在做新闻分类时,语料里「的」「了」「是」这类词特别多,用 CBOW 能快速收敛。
4.2.2 Skip-gram
Skip-gram 正好反过来:用中心词,预测上下文词。
还是「我 喜欢 吃 苹果」这个句子。中心词是「吃」,模型要预测它周围的词——「我」「喜欢」「苹果」。
Skip-gram 适合低频词,对罕见词的表示更准确。我做过一个金融研报的项目,里面有很多生僻的公司名和产品名,用 Skip-gram 效果明显更好。
经验总结:
- 语料大、高频词多 → 用 CBOW,速度快
- 语料小、低频词多 → 用 Skip-gram,精度高
4.3 核心逻辑流程图
下面这张图,是我自己画的 Word2Vec 训练流程。你看一眼就能明白整体脉络。
4.4 Gensim 库实战
Gensim 是 Python 里最常用的 Word2Vec 工具库。我几乎每个 NLP 项目都会用到它,稳定、高效、文档全。
4.4.1 安装与导入
pip install gensim
from gensim.models import Word2Vec
from gensim.utils import simple_preprocess
4.4.2 准备语料
假设我们有一些金融研报的句子:
sentences = [
"央行 下调 存款 准备金率 50 个 基点",
"新能源 汽车 销量 同比 增长 30%",
"芯片 短缺 影响 汽车 产能",
"消费 升级 推动 高端 白酒 需求",
"光伏 行业 迎来 新一轮 扩产 周期"
]
# 分词处理
corpus = [s.split() for s in sentences]
4.4.3 训练模型
model = Word2Vec(
sentences=corpus,
vector_size=100, # 向量维度
window=5, # 上下文窗口
min_count=1, # 最低词频
sg=0, # 0=CBOW, 1=Skip-gram
epochs=50, # 训练轮数
workers=4 # 并行线程
)
我的习惯:刚开始训练时,先用小维度(50-100)快速跑一轮,看看效果。确认没问题后,再加大维度(200-300)做正式训练。这样能省不少时间。
4.4.4 常用操作
# 查看词向量
vector = model.wv['芯片']
print(vector[:10]) # 打印前10个维度
# 找相似词
similar_words = model.wv.most_similar('汽车', topn=5)
print(similar_words)
# 输出示例:[('新能源', 0.85), ('销量', 0.78), ('产能', 0.72), ...]
# 词类比:国王 - 男人 + 女人 = 女王
result = model.wv.most_similar(positive=['新能源', '汽车'], negative=['传统'], topn=3)
print(result)
4.5 词向量可视化
训练好的词向量是高维的(比如100维),我们没法直接看。需要降维到2D或3D才能可视化。
我常用的是 t-SNE 或 PCA。下面用 t-SNE 做个例子:
from sklearn.manifold import TSNE
import matplotlib.pyplot as plt
# 提取词向量
words = list(model.wv.index_to_key)
vectors = [model.wv[word] for word in words]
# t-SNE 降维到2D
tsne = TSNE(n_components=2, random_state=42, perplexity=5)
vectors_2d = tsne.fit_transform(vectors)
# 绘图
plt.figure(figsize=(10, 8))
for i, word in enumerate(words):
x, y = vectors_2d[i]
plt.scatter(x, y, c='blue', alpha=0.6)
plt.annotate(word, (x, y), fontsize=12, alpha=0.8)
plt.title('Word2Vec 词向量可视化 (t-SNE)')
plt.show()
避坑指南:我曾经在可视化时踩过一个坑——语料太小,t-SNE 的 perplexity 参数设得太大,结果所有词都挤成一团。后来我把 perplexity 调小到 5-10,效果才正常。记住:语料少,perplexity 就设小点。
4.6 实际应用场景
在金融研报分析里,Word2Vec 能帮我们做不少事:
| 场景 | 说明 | 示例 |
|---|---|---|
| 相似词发现 | 找到语义相近的金融术语 | 「降息」→「降准」「宽松」「逆回购」 |
| 主题聚类 | 将研报中的关键词分组 | 「芯片」「半导体」「光刻机」自动聚为一类 |
| 情感分析 | 判断词语的情感倾向 | 「增长」「突破」为正面,「下滑」「亏损」为负面 |
| 实体识别 | 辅助识别公司名、产品名 | 「茅台」「五粮液」向量相近,可归为白酒类 |
4.7 几点补充
嗯,最后说几个容易忽略的点:
- 语料质量比数量重要。我见过有人拿几十G的网页文本训练,结果全是噪音,效果还不如几万条高质量的研报。
- 训练前一定要做预处理。数字、特殊符号、停用词该处理就处理,不然向量里全是垃圾信息。
- Word2Vec 是静态的。一个词只有一个向量,无法处理一词多义。比如「苹果」既可以是水果,也可以是公司。如果你需要处理多义词,可以考虑 BERT 这类动态模型。
一句话总结:Word2Vec 是词嵌入的入门基石,CBOW 快、Skip-gram 准,Gensim 帮你三行代码搞定训练,t-SNE 帮你把高维向量画成图。搞懂了这些,后面学 BERT、GPT 会轻松很多。
公众号:蓝海资料掘金营,微信deep3321