3. 多语言词向量与嵌入:静态词向量(Word2Vec、FastText)、上下文嵌入(BERT、XLM-R)、跨语言对齐与映射

好,咱们今天聊聊多语言词向量。说实话,这个领域我踩过不少坑。早期做跨语言情感分析时,我天真地以为把中文词向量和英文词向量直接拼在一起就能用,结果模型训练出来一塌糊涂。后来才明白,不同语言的空间压根不在一个坐标系里。

多语言词向量的核心,说白了就是让不同语言的词语在同一个向量空间里找到自己的位置。这样,中文的「苹果」和英文的「apple」距离很近,而「苹果」和「汽车」距离很远。嗯,这个目标听起来简单,实现起来却各有门道。

3.1 静态词向量:Word2Vec 与 FastText

静态词向量,就是每个词只有一个固定的向量表示。不管这个词出现在什么语境里,它的向量都不变。我刚开始做 NLP 时,用的就是这种方案。

3.1.1 Word2Vec:经典但有限

Word2Vec 有两种训练方式:CBOW 和 Skip-gram。CBOW 用上下文预测当前词,Skip-gram 用当前词预测上下文。我个人习惯用 Skip-gram,尤其在数据量不大的时候,它对低频词的表现更好。

但 Word2Vec 有个硬伤——它不认识没见过的词。你在训练集里没见过「元宇宙」,那模型就傻眼了。而且它无法处理词形变化,比如「run」和「running」在它眼里是完全不同的词。

核心要点: Word2Vec 依赖词表,OOV(Out-of-Vocabulary)问题严重。跨语言场景下,这个问题会被放大。

3.1.2 FastText:子词信息的引入

FastText 是 Word2Vec 的升级版。它把每个词拆成字符级别的 n-gram。比如「apple」拆成「ap」、「pp」、「pl」、「le」这些子词。这样即使遇到新词,只要它的子词在训练中出现过,就能拼出向量。

我在做一个多语言电商评论分析项目时,遇到过大量拼写错误和变体词。比如用户把「delicious」打成「delicous」。Word2Vec 直接报错,FastText 却能通过子词匹配给出合理向量。这就是它的优势。

# FastText 训练示例(伪代码)
from gensim.models import FastText

# 假设我们有中英文混合的语料
sentences = [['我', '喜欢', 'apple'], ['he', 'likes', '苹果']]

# 训练 FastText 模型
model = FastText(sentences, vector_size=100, window=5, min_count=1, workers=4)

# 获取词向量
vec_apple = model.wv['apple']  # 存在
vec_appple = model.wv['appple']  # 不存在,但通过子词也能生成向量
我的经验: 在多语言场景下,FastText 的子词粒度建议设为 3-6 个字符。太短了噪音多,太长了又失去泛化能力。

3.2 上下文嵌入:BERT 与 XLM-R

静态词向量有个根本问题——一词多义。比如「bank」可以是银行,也可以是河岸。静态向量只能给一个平均表示,这显然不够用。

上下文嵌入就解决了这个问题。每个词的向量会根据它所在的句子动态变化。你想想看,这多符合人类理解语言的方式。

3.2.1 BERT:双向编码的突破

BERT 用 Transformer 的编码器,通过 Masked Language Model 任务训练。它同时看一个词左右两边的上下文,所以叫「双向」。我记得第一次用 BERT 做中文分词时,效果比传统方法好了将近 10 个点。

但 BERT 有个问题——它是单语言的。你用中文 BERT 处理英文,效果会大打折扣。而且不同语言的 BERT 模型,向量空间是独立的,没法直接比较。

3.2.2 XLM-R:真正的多语言王者

XLM-R 是 Facebook 推出的多语言模型,在 100 种语言上训练。它用了一个技巧——共享词表。所有语言的 token 都映射到同一个词表里,这样模型就能学到跨语言的共性。

我在做一个东南亚多语言客服系统时,用了 XLM-R 做句子编码。泰语、越南语、印尼语混在一起,模型照样能准确理解意图。说实话,当时我被惊艳到了。

# 使用 XLM-R 获取上下文嵌入
from transformers import XLMRobertaTokenizer, XLMRobertaModel

tokenizer = XLMRobertaTokenizer.from_pretrained('xlm-roberta-base')
model = XLMRobertaModel.from_pretrained('xlm-roberta-base')

# 中英文混合句子
text = "I like 苹果 and 香蕉"
inputs = tokenizer(text, return_tensors='pt')
outputs = model(**inputs)

# 获取每个 token 的上下文向量
token_embeddings = outputs.last_hidden_state
注意: XLM-R 虽然强大,但模型很大(base 版本 270M 参数)。在资源受限的场景下,我建议用蒸馏版本或者量化技术压缩模型。

3.3 跨语言对齐与映射

好,现在问题来了。我们有中文词向量空间,也有英文词向量空间,怎么让它们对齐?

跨语言对齐,说白了就是找到一个映射矩阵,把一种语言的向量空间映射到另一种语言的空间里。这样,中文的「猫」和英文的「cat」在映射后的空间里距离很近。

3.3.1 基于映射的方法

最经典的方法是使用双语词典做监督学习。比如我们有 5000 对中英文词对,用这些词对训练一个线性映射矩阵 W。训练目标是让映射后的中文词向量和对应的英文词向量尽可能接近。

我曾经试过用这种方法做中英跨语言情感分析。效果还行,但有个坑——映射后的空间会有扭曲。有些词映射得很好,有些词却跑偏了。后来我改用正交约束,效果稳定了不少。

# 跨语言映射示例(伪代码)
import numpy as np

# 假设我们有中英文词向量矩阵
X = chinese_vectors  # 形状: (n, d)
Y = english_vectors  # 形状: (n, d)

# 求解映射矩阵 W,使得 ||XW - Y|| 最小
# 使用正交约束保证映射保距
U, _, Vt = np.linalg.svd(Y.T @ X)
W = U @ Vt

# 映射中文词向量到英文空间
mapped_vector = chinese_word_vector @ W

3.3.2 无监督对齐方法

没有双语词典怎么办?别急,还有无监督方法。核心思想是利用向量空间的几何结构。不同语言的词向量空间,虽然坐标系不同,但几何结构是相似的。比如「国王-王后」和「king-queen」的向量差应该差不多。

我记得有一篇论文用 GAN 做无监督对齐,效果出奇的好。生成器负责把一种语言的向量映射到另一种语言,判别器负责判断映射后的向量是否和真实向量分布一致。嗯,这个思路很巧妙。

关键洞察: 跨语言对齐的成功,依赖于一个假设——不同语言的词向量空间具有相似的几何结构。这个假设在印欧语系中成立得很好,但在中文和英文这种差异较大的语言对中,效果会打折扣。

3.3.3 多语言 BERT 的隐式对齐

XLM-R 这类多语言模型,其实已经隐式地做了跨语言对齐。因为它在训练时,不同语言的 token 共享同一个 Transformer 层,模型被迫学习跨语言的共性。

我在实际项目中发现,XLM-R 的最后一层隐藏状态,天然具有跨语言对齐的特性。你拿中文句子和英文句子分别过模型,得到的句子向量可以直接比较相似度。这比单独训练映射矩阵方便多了。

方法 优点 缺点 适用场景
Word2Vec 训练快,资源消耗小 OOV 问题,无上下文 小规模项目,资源受限
FastText 处理 OOV,支持子词 仍为静态表示 拼写错误多,形态丰富语言
BERT 上下文感知,效果好 单语言,模型大 需要高质量语义理解
XLM-R 多语言,隐式对齐 模型巨大,推理慢 多语言混合场景
映射对齐 可解释性强 需要双语词典 有双语资源时
我的建议: 如果你做的是多语言项目,直接上 XLM-R 是最省事的。虽然模型大,但省去了对齐的麻烦。如果资源有限,用 FastText + 映射对齐也是个不错的选择。

最后说一句,词向量这个领域发展很快。从静态到动态,从单语言到多语言,每一步都在解决实际问题。我当年做跨语言项目时,光是对齐就折腾了两个月。现在有了 XLM-R,几行代码就能搞定。技术迭代真快啊。