Embedding/嵌入:把文字变成数字的魔法
这篇文章带你理解AI如何把文字变成数字,让计算机"理解"人类语言。
前言
计算机只认识数字,不认识文字。
那么问题来了:怎么让计算机理解"苹果"和"香蕉"都是水果?
答案就在一个词:Embedding(嵌入)
这是连接人类语言和计算机世界的"魔法翻译器"。
一、黑话原文 vs 人话翻译
场景模拟
arduino
🎯 NLP工程师面试:
面试官:"你们用的什么Embedding方案?"
求职者:"Word2Vec做基础,然后接Transformer的Contextual Embedding"
面试官:"词向量维度多少?"
求职者:"300维Word Embedding,768维Contextual"
面试官:"试过Sentence Embedding吗?"
求职者:"用过SBERT,效果不错"
人话翻译表
| 黑话 | 人话翻译 | 一句话理解 |
|---|---|---|
| Embedding | 嵌入/向量化 | 把字变成数字 |
| Word Embedding | 词嵌入 | 把词变成向量 |
| Word2Vec | 词转向量算法 | 经典的词向量方法 |
| 向量空间 | Vector Space | 数字世界的"地图" |
| 语义相似度 | Semantic Similarity | 意思有多像 |
| 维度 | Dimension | 向量的长度 |
二、Embedding是什么?
2.1 一句话定义
Embedding = 把文字变成一串数字(向量)
人话版:给每个词发一张"数字身份证",意思相近的词身份证也相近。
2.2 为什么需要Embedding?
arduino
┌─────────────────────────────────────────────────────────────┐
│ 计算机的困惑 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 人类看到的: │
│ "苹果" "香蕉" "汽车" │
│ │
│ 计算机看到的: │
│ ???(不认识汉字) │
│ │
│ 解决方案:把文字变成数字! │
│ │
│ "苹果" → [0.1, 0.5, -0.3, 0.8, ...] │
│ "香蕉" → [0.2, 0.6, -0.2, 0.7, ...] │
│ "汽车" → [-0.5, 0.1, 0.8, -0.3, ...] │
│ │
│ 注意:苹果和香蕉的数字很相似(都是水果) │
│ 汽车的数字差别很大(不是水果) │
│ │
└─────────────────────────────────────────────────────────────┘
2.3 生活类比
diff
Embedding就像:
🗺️ 地图坐标
- 北京: (116.4, 39.9)
- 上海: (121.5, 31.2)
- 东京: (139.7, 35.7)
北京和上海都在中国 → 坐标相近
东京在日本 → 稍远一点
🎵 音乐风格坐标
- 流行: [0.8, 0.6, 0.2]
- 摇滚: [0.7, 0.3, 0.8]
- 古典: [0.2, 0.1, 0.1]
流行和摇滚有点像 → 向量相近
古典很不一样 → 向量差别大
三、向量空间
3.1 一句话定义
向量空间 = 所有词的数字表示所在的"空间"
人话版:一张超级大的"词意地图",意思相近的词靠得近。
3.2 可视化理解
┌─────────────────────────────────────────────────────────────┐
│ 2D向量空间示意 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 🍎 苹果 │
│ 🍌 香蕉 │
│ │
│ 🐕 狗 🐱 猫 │
│ │
│ 🚗 汽车 │
│ │
│ 🏀 篮球 ⚽ 足球 │
│ │
│ │
│ 观察: │
│ - 水果类聚在一起(苹果、香蕉) │
│ - 动物类聚在一起(狗、猫) │
│ - 运动类聚在一起(篮球、足球) │
│ - 不同类别的词分开 │
│ │
└─────────────────────────────────────────────────────────────┘
3.3 有趣的向量运算
css
最经典的例子:
👑 国王 - 👨 男人 + 👩 女人 = 👸 女王
用向量表示:
[0.8, 0.6, 0.3] - [0.5, 0.4, 0.2] + [0.5, 0.5, 0.3] ≈ [0.8, 0.7, 0.4]
这意味着向量空间"学会"了性别关系!
更多例子:
中国 - 北京 + 东京 ≈ 日本
走路 - 快 + 慢 ≈ 散步
四、Word2Vec:经典的词嵌入
4.1 一句话定义
Word2Vec = 一种把词变成向量的经典方法
人话版:通过"猜词游戏"让计算机学会词的含义。
4.2 Word2Vec原理
sql
┌─────────────────────────────────────────────────────────────┐
│ Word2Vec的两种玩法 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. CBOW(连续词袋) │
│ 猜中间的词 │
│ │
│ "小 明 ___ 吃 苹 果" │
│ ↓ │
│ 猜出"喜欢" │
│ │
│ 2. Skip-gram │
│ 猜旁边的词 │
│ │
│ "喜欢" → 猜出周围的词 │
│ ↓ │
│ "小明" "吃" "苹果" │
│ │
│ 通过大量这样的"猜词游戏", │
│ 模型学会了:经常一起出现的词,意思相关 │
│ │
└─────────────────────────────────────────────────────────────┘
4.3 代码示例
python
from gensim.models import Word2Vec
# 训练数据(实际应用中需要大量文本)
sentences = [
['我', '喜欢', '吃', '苹果'],
['我', '喜欢', '吃', '香蕉'],
['他', '喜欢', '养', '猫'],
['她', '喜欢', '养', '狗'],
]
# 训练Word2Vec模型
model = Word2Vec(sentences, vector_size=100, window=2, min_count=1)
# 获取词向量
apple_vector = model.wv['苹果']
print(f"'苹果'的向量(前5维): {apple_vector[:5]}")
# 找相似的词
similar = model.wv.most_similar('苹果')
print(f"和'苹果'最相似的词: {similar}")
# 类比运算
# result = model.wv.most_similar(positive=['国王', '女人'], negative=['男人'])
五、不同类型的Embedding
5.1 演进历史
scss
┌─────────────────────────────────────────────────────────────┐
│ Embedding演进史 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 第一代:One-Hot 编码 │
│ ────────────────── │
│ "苹果" → [0,0,0,1,0,0,0] (第4个位置是1) │
│ 问题:维度爆炸,无法表达相似性 │
│ │
│ 第二代:Word2Vec / GloVe │
│ ──────────────────────── │
│ "苹果" → [0.1, 0.5, -0.3, ...] (稠密向量) │
│ 优点:能表达相似性,维度可控 │
│ 问题:一个词只有一个向量(多义词问题) │
│ │
│ 第三代:Contextual Embedding(BERT等) │
│ ──────────────────────────────────────── │
│ "苹果" 的向量取决于上下文 │
│ - "我吃了一个苹果" → 苹果(水果)的向量 │
│ - "苹果公司发布了新手机" → 苹果(公司)的向量 │
│ 优点:解决多义词问题 │
│ │
└─────────────────────────────────────────────────────────────┘
5.2 对比表
| 类型 | 特点 | 代表 |
|---|---|---|
| One-Hot | 稀疏,无法表示相似 | - |
| Word2Vec | 稠密,静态向量 | |
| GloVe | 全局统计信息 | Stanford |
| FastText | 考虑子词 | |
| BERT | 动态,上下文相关 | |
| GPT | 动态,生成式 | OpenAI |
5.3 静态 vs 动态Embedding
arduino
静态Embedding(Word2Vec):
┌─────────────────────────────────────────────────────────┐
│ "苹果" → 固定向量 [0.1, 0.5, -0.3, ...] │
│ │
│ 不管在什么句子中,"苹果"的向量都一样 │
│ 问题: │
│ - "我吃了一个苹果" │
│ - "苹果发布了新手机" │
│ 这两个"苹果"意思不同,但向量相同! │
└─────────────────────────────────────────────────────────┘
动态Embedding(BERT):
┌─────────────────────────────────────────────────────────┐
│ "我吃了一个苹果" → 苹果 → [0.1, 0.6, -0.2, ...] │
│ "苹果发布了新手机" → 苹果 → [0.7, 0.2, 0.5, ...] │
│ │
│ 根据上下文动态生成向量 │
│ 同一个词,不同语境,不同向量 │
└─────────────────────────────────────────────────────────┘
六、维度是什么?
6.1 一句话定义
维度 = 向量的长度,表示特征的丰富程度
人话版:就像描述一个人,维度越多,描述越详细。
6.2 维度的意义
arduino
┌─────────────────────────────────────────────────────────────┐
│ 不同维度的表示 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 3维向量(太简单): │
│ "苹果" → [0.8, 0.3, 0.5] │
│ 只能表达3个特征,不够精确 │
│ │
│ 100维向量(适中): │
│ "苹果" → [0.1, 0.5, -0.3, 0.8, 0.2, ...共100个] │
│ 能表达100个特征,够用 │
│ │
│ 768维向量(丰富): │
│ "苹果" → [...共768个] │
│ 非常详细,但计算量大 │
│ │
│ 12288维向量(超大): │
│ "苹果" → [...共12288个] │
│ GPT-3的维度,超级详细 │
│ │
└─────────────────────────────────────────────────────────────┘
6.3 常见维度
| 模型 | Embedding维度 |
|---|---|
| Word2Vec | 100-300 |
| GloVe | 50-300 |
| BERT-base | 768 |
| BERT-large | 1024 |
| GPT-2 | 768-1600 |
| GPT-3 | 12288 |
七、语义相似度
7.1 一句话定义
语义相似度 = 两个词/句子的意思有多像
人话版:看两个词的向量有多"接近"。
7.2 怎么计算相似度?
python
import numpy as np
def cosine_similarity(v1, v2):
"""
余弦相似度
返回值:-1到1之间,1表示完全相同
"""
dot_product = np.dot(v1, v2)
norm1 = np.linalg.norm(v1)
norm2 = np.linalg.norm(v2)
return dot_product / (norm1 * norm2)
# 示例
apple = np.array([0.8, 0.2, 0.5])
banana = np.array([0.7, 0.3, 0.6])
car = np.array([-0.3, 0.9, 0.1])
print(f"苹果 vs 香蕉: {cosine_similarity(apple, banana):.2f}") # 0.95 很相似
print(f"苹果 vs 汽车: {cosine_similarity(apple, car):.2f}") # 0.12 不相似
7.3 相似度可视化
css
相似度矩阵:
苹果 香蕉 狗 汽车
苹果 [ 1.00 0.95 0.20 0.12 ]
香蕉 [ 0.95 1.00 0.18 0.10 ]
狗 [ 0.20 0.18 1.00 0.25 ]
汽车 [ 0.12 0.10 0.25 1.00 ]
热力图:
苹果 香蕉 狗 汽车
苹果 [ ████ ████ ░░░░ ░░░░ ]
香蕉 [ ████ ████ ░░░░ ░░░░ ]
狗 [ ░░░░ ░░░░ ████ ░░░░ ]
汽车 [ ░░░░ ░░░░ ░░░░ ████ ]
颜色越深 = 越相似
八、Embedding的实际应用
8.1 搜索引擎
arduino
传统搜索:关键词匹配
搜索:"苹果手机"
结果:必须包含"苹果"和"手机"
Embedding搜索:语义匹配
搜索:"苹果手机"
结果:
- "iPhone 15 Pro" ← 意思一样
- "苹果公司的新产品" ← 相关
- "iOS设备" ← 相关
8.2 推荐系统
diff
用户喜欢:[复仇者联盟, 蜘蛛侠, 钢铁侠]
用户向量 = avg(复仇者联盟向量, 蜘蛛侠向量, 钢铁侠向量)
推荐:找和用户向量相似的电影
- 美国队长 ← 高相似
- 雷神 ← 高相似
- 哈利波特 ← 低相似
8.3 文本分类
python
from sklearn.linear_model import LogisticRegression
import numpy as np
# 假设我们有一些句子和标签
sentences = ["这个产品很好", "太差了", "非常满意", "垃圾"]
labels = [1, 0, 1, 0] # 1=正面, 0=负面
# 获取句子embedding(这里简化)
# 实际可以用BERT等模型
X = np.array([get_embedding(s) for s in sentences])
# 训练分类器
clf = LogisticRegression()
clf.fit(X, labels)
# 预测新句子
new_sentence = "超级棒"
new_embedding = get_embedding(new_sentence)
prediction = clf.predict([new_embedding])
print("正面" if prediction[0] == 1 else "负面")
小结
| 黑话 | 人话 | 记忆口诀 |
|---|---|---|
| Embedding | 嵌入 | 把字变数字 |
| Word2Vec | 词转向量 | 经典方法 |
| 向量空间 | 数字地图 | 意思相近靠得近 |
| 维度 | 向量长度 | 越长越详细 |
| 语义相似度 | 意思多像 | 向量多接近 |
关键认知:
- Embedding是把文字变成数字的方法
- 相似的词向量也相似
- 静态Embedding每个词一个向量
- 动态Embedding考虑上下文
- 维度越高越精确,但计算量越大
黑话等级
sql
⭐⭐⭐ 进阶级
├── 理解Embedding是什么
├── 知道静态和动态Embedding区别
└── 会计算语义相似度
下一期预告:Context Window/上下文窗口 - AI的短期记忆
思考与练习
-
思考题:
- 为什么相似的词向量也相似?
- Word2Vec和BERT的Embedding有什么区别?
-
动手练习:
- 用Word2Vec训练一个词向量模型
- 计算一些词的相似度
-
延伸探索:
- 了解Sentence Embedding
- 研究多语言Embedding
下期预告
下一篇文章,我们来聊:Context Window/上下文窗口 - AI的短期记忆
会解答这些问题:
- 上下文窗口到底怎么工作的?
- 为什么有的模型能记住很多,有的记不住?
- 超过上下文窗口会怎样?
关注专栏,不错过后续更新!
作者:ECH00O00 本文首发于掘金专栏《AI黑话翻译官》 欢迎评论区交流讨论,点赞收藏就是最大的鼓励