#词向量空间 (Word Embeddings):从 One-Hot 到 Word2Vec
#1. 为什么需要词向量?
#1.1 One-Hot 编码的问题
# One-Hot 编码:每个词一个维度,只有自己为 1
import numpy as np
vocab = ["我", "爱", "机器", "学习"]
vocab_size = len(vocab)
# 词的 One-Hot 表示
def one_hot(word, vocab):
vec = np.zeros(len(vocab))
if word in vocab:
vec[vocab.index(word)] = 1
return vec
print(one_hot("机器", vocab))
# [0, 0, 1, 0]
# 问题一:维度爆炸(10万词汇 → 10万维)
# 问题二:语义无关("机器"和"电脑"都是 1,和其他词无关)
# 问题三:稀疏(99.999% 都是 0)#1.2 词向量的革命
分布式表示:将词的意思分散到多个维度
One-Hot(稀疏,高维):
机器 = [0, 0, 1, 0, 0, ...]
Word2Vec(稠密,低维):
机器 = [0.23, -0.45, 0.89, -0.12, ...] (100-300维)
为什么有效:语义相似的词,在向量空间中距离更近!
"机器" ≈ "电脑" → 距离近
"机器" ≠ "食物" → 距离远#2. Word2Vec 原理
#2.1 两个核心模型
Word2Vec 包含两个模型:
Skip-Gram:给定中心词,预测上下文词
"机器" → 预测 "我", "爱", "学习"
CBOW(Continuous Bag-of-Words):给定上下文,预测中心词
"我", "爱", "学习" → 预测 "机器"
训练数据来源:互联网语料(无需标注!)#2.2 Skip-Gram 示例
窗口大小 = 2
句子:"我 爱 机器 学习"
↓ ↓
中心词 上下文词
"机器" 的训练样本:
(机器, 我) (机器, 爱) (机器, 学习)
目标:学会 "机器" 和 "我/爱/学习" 的关系#2.3 Word2Vec 的数学本质
# Word2Vec 训练过程(简化)
"""
1. 随机初始化词向量
2. 定义损失函数:给定中心词,最大化上下文词的概率
3. 反向传播更新向量
4. 最终每个词有一个稠密向量
"""
# 关键洞察:出现在相似上下文的词有相似的向量
# "机器学习" 和 "深度学习" 经常出现在相似上下文 → 向量相似#2.4 使用预训练 Word2Vec
# 使用 Gensim 加载预训练中文词向量
pip install gensim
from gensim.models import KeyedVectors
# 加载腾讯中文词向量(需要自行下载,约 6GB)
model = KeyedVectors.load_word2vec_format(
"Tencent_AILab_Chinese_Embedding.txt",
binary=False
)
# 找相似词
result = model.most_similar("人工智能", topn=5)
print(result)
# [('机器学习', 0.85), ('深度学习', 0.82), ...]
# 词语类比
# 北京 - 中国 + 日本 = 东京
result = model.most_similar(
positive=["北京", "日本"],
negative=["中国"],
topn=1
)
print(result)
# [('东京', 0.92)]#3. GloVe
#3.1 GloVe 原理
GloVe = Global Vectors
核心思想:结合全局统计信息和局部上下文
统计信息:词-词共现矩阵(整个语料中词A和词B一起出现的次数)
这是一个 "全局" 信息
Word2Vec:只利用局部窗口信息
GloVe:结合全局共现统计 + 局部窗口
效果:GloVe 通常训练更快,效果稳定#3.2 使用 GloVe 词向量
import numpy as np
# 加载 GloVe 词向量(英文)
# 下载:glove.6B.zip(822MB)
def load_glove(filepath, vocab):
embeddings = {}
with open(filepath, encoding="utf-8") as f:
for line in f:
values = line.strip().split()
word = values[0]
vector = np.array(values[1:], dtype="float32")
if word in vocab:
embeddings[word] = vector
return embeddings
# 使用
vocab = {"hello": 0, "world": 1}
embeddings = load_glove("glove.6B.50d.txt", vocab)
# 平均词向量表示句子
def sentence_embedding(tokens, embeddings, dim=50):
vectors = [embeddings[w] for w in tokens if w in embeddings]
if vectors:
return np.mean(vectors, axis=0)
return np.zeros(dim)
tokens = ["hello", "world"]
vec = sentence_embedding(tokens, embeddings)
print(vec.shape) # (50,)#4. 词向量的使用场景
#4.1 文本分类
import numpy as np
def text_to_vector(text, tokenizer, embedding_model, dim=300):
"""将文本转为平均词向量"""
tokens = tokenizer.tokenize(text)
vectors = []
for token in tokens:
if token in embedding_model:
vectors.append(embedding_model[token])
if vectors:
return np.mean(vectors, axis=0)
return np.zeros(dim)
# 文本相似度
def cosine_similarity(a, b):
return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
vec1 = text_to_vector("机器学习", jieba_tokenizer, word2vec_model)
vec2 = text_to_vector("深度学习", jieba_tokenizer, word2vec_model)
print(cosine_similarity(vec1, vec2)) # 相似度分数#5. 小结
词向量演进:
One-Hot → Word2Vec → GloVe → BERT(上下文词向量)
One-Hot:稀疏、高维、无语义
Word2Vec:稠密、低维、捕捉语义关系(需要训练)
GloVe:结合全局统计信息
BERT:每个词在不同上下文有不同向量(最强)💡 2026 年的实践:预训练大模型(BERT、GPT)的词向量效果远超 Word2Vec。简单任务直接用 Hugging Face 的预训练 Embedding,复杂任务才需要训练自己的词向量。
🔗 扩展阅读

