1. Embedding模型概述:什么是Embedding、Embedding在NLP中的作用、从词袋模型到分布式表示的演进
1.1 到底什么是Embedding?
先别急着看公式。我习惯用一个比喻来解释:Embedding就是把文字变成计算机能理解的“坐标”。
你想想看,计算机不认识“苹果”这个词,它只认识0和1。那怎么让机器理解“苹果”和“水果”是近亲,而和“汽车”八竿子打不着?
早期的做法是给每个词发一个“身份证号”——比如“苹果”是10086,“水果”是10010。但问题来了:10086和10010的数值差是76,而10086和99999的差是89913,这能说明“苹果”和“水果”比“苹果”和“汽车”更近吗?显然不能。这种编号方式完全丢失了语义关系。
Embedding的思路完全不同。它把每个词映射到一个低维稠密向量里,比如一个300维的浮点数数组。在这个向量空间里,语义相近的词距离就小,语义无关的词距离就大。说白了,Embedding就是给每个词找了个“语义坐标”。
核心定义:Embedding是将离散的符号(词、句子、图节点等)映射到连续向量空间的技术。在NLP里,它让机器能“感知”语义相似度。
1.2 Embedding在NLP中的作用
我在做文本分类项目时,深刻体会过Embedding的价值。没有它,你只能靠词频硬扛;有了它,模型才能真正“理解”上下文。
具体来说,Embedding解决了三个关键问题:
- 语义表示:把“开心”和“快乐”映射到相近的向量,模型就知道它们差不多是一回事
- 降维:词袋模型动辄几万维,Embedding压缩到几百维,计算量直接降两个数量级
- 泛化能力:训练时没见过“苹果手机”,但见过“苹果”和“手机”的向量,模型就能推断出它是个电子产品
举个例子。假设我们有三个词的Embedding:
| 词 | 维度1 | 维度2 | 维度3 | 维度4 | 维度5 |
|---|---|---|---|---|---|
| 国王 | 0.8 | 0.1 | 0.7 | 0.3 | 0.9 |
| 王后 | 0.7 | 0.9 | 0.6 | 0.4 | 0.8 |
| 男人 | 0.6 | 0.2 | 0.5 | 0.1 | 0.7 |
| 女人 | 0.5 | 0.8 | 0.4 | 0.2 | 0.6 |
你看,“国王”和“王后”在维度2上差异明显(0.1 vs 0.9),这个维度很可能编码了“性别”信息。而“国王”和“男人”在维度1、3、5上都很接近,说明它们共享了“男性”和“权力”的语义。这就是Embedding的魔力——向量之间的算术运算能反映语义关系。
避坑指南:我曾经在项目里直接用随机初始化的Embedding,结果模型怎么训都不收敛。后来才意识到,Embedding的初始值对训练影响很大。建议用预训练好的词向量做初始化,或者至少用Xavier初始化。
1.3 从词袋模型到分布式表示:一场语义革命
要理解Embedding为什么重要,得先看看它之前的“前辈”们有多坑。我按时间线梳理一下:
1.3.1 词袋模型(Bag-of-Words, BoW)
这是最原始的做法。把每个文档变成一个向量,向量的每一维对应一个词,值就是这个词在文档里出现的次数。
# 假设有两个文档
doc1 = "我 喜欢 吃 苹果"
doc2 = "我 喜欢 吃 香蕉"
# 构建词表:{"我":0, "喜欢":1, "吃":2, "苹果":3, "香蕉":4}
# 词袋向量:
doc1_vec = [1, 1, 1, 1, 0] # 长度5
doc2_vec = [1, 1, 1, 0, 1] # 长度5
问题很明显:
- 维度爆炸:词表多大,向量就多长。中文词表动辄几十万,向量稀疏得可怕
- 丢失顺序:“我打你”和“你打我”的向量一模一样
- 语义鸿沟:“苹果”和“香蕉”在向量里毫无关系,尽管它们都是水果
1.3.2 TF-IDF(词频-逆文档频率)
这是词袋模型的升级版。它不光看词频,还考虑这个词在整个语料里是否常见。比如“的”这种停用词,虽然出现频率高,但IDF值很低,权重就被压下来了。
TF-IDF(t, d) = TF(t, d) × IDF(t)
其中:
TF(t, d) = 词t在文档d中出现的次数 / 文档d的总词数
IDF(t) = log(总文档数 / 包含词t的文档数)
TF-IDF比纯词袋好一些,但本质还是稀疏表示,语义鸿沟问题没解决。
1.3.3 分布式表示(Distributed Representation)
这才是真正的革命。分布式表示的核心思想是:一个词的语义由它周围的词决定。这句话来自语言学里的“分布假说”(Distributional Hypothesis)。
2013年,Google的Tomas Mikolov提出了Word2Vec,把分布式表示推向了实用化。Word2Vec有两种训练方式:
- CBOW(Continuous Bag-of-Words):用上下文词预测中心词
- Skip-gram:用中心词预测上下文词
我当年用Word2Vec训练了一个中文词向量,发现“北京-中国≈巴黎-法国”这种类比关系居然成立。那一刻我才真正理解分布式表示有多强大。
注意:Word2Vec虽然好,但它有两个硬伤:一是无法处理一词多义(比如“苹果”既可以是水果也可以是公司);二是对罕见词的学习效果很差。后来的BERT、ELMo等模型就是专门解决这些问题的。
1.4 三种表示方法的对比
我把它们放在一起对比,你一眼就能看出差距:
| 特性 | 词袋模型 | TF-IDF | 分布式表示(Embedding) |
|---|---|---|---|
| 向量维度 | 词表大小(几万~几十万) | 词表大小 | 自定义(通常100~768) |
| 向量类型 | 稀疏(大部分为0) | 稀疏 | 稠密(大部分非0) |
| 语义相似度 | 无法衡量 | 弱 | 强(余弦相似度有效) |
| 计算开销 | 低 | 中 | 高(但可接受) |
| 泛化能力 | 无 | 弱 | 强 |
| 典型应用 | 垃圾邮件过滤 | 信息检索 | 语义搜索、文本分类、机器翻译 |
1.5 知识体系总览
下面这张图概括了本章的核心脉络。从词袋模型到分布式表示,每一步演进都在解决前一步的痛点。
1.6 我的个人建议
如果你刚开始接触Embedding,我建议你从Word2Vec入手。原因很简单:它概念清晰、训练快、效果也够用。我在做文本相似度计算时,用Word2Vec加余弦相似度就能达到不错的基线效果。
但要注意一点:Embedding的质量高度依赖语料。我曾经用一个小规模的中文新闻语料训练词向量,结果“苹果”和“香蕉”的相似度只有0.3,远低于预期。后来换成了几十G的百科语料,相似度直接跳到0.7。所以,语料规模和质量是Embedding效果的基石。