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 训练流程。你看一眼就能明白整体脉络。

Word2Vec 训练流程 原始语料(文本) 分词 + 去停用词 构建词表 + 生成训练样本 选择模型:CBOW / Skip-gram 输出词向量 关键参数 • vector_size: 向量维度 • window: 窗口大小 • min_count: 最低词频 • sg: 0=CBOW, 1=Skip-gram • epochs: 训练轮数 • workers: 并行线程数 训练技巧: 1. 语料越大,向量维度越高 2. 窗口大小一般取 5-10 3. min_count 建议 5-10 4. 多轮训练可提升质量

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-SNEPCA。下面用 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