Day 19: NLP 基础与词表示 (NLP Basics & Word Embeddings)

摘要:欢迎进入自然语言处理 (NLP) 板块!如果说 CV 是教 AI “看”,那么 NLP 就是教 AI “读”和“写”。计算机无法直接理解人类的语言(符号),我们需要把文字变成数字。从最古老的 One-Hot 到经典的 Word2Vec,再到子词切分 (Subword),本文将带你走完文本向量化的进化之路。


1. 语言模型的核心难题:如何把词变成数?

计算机只认识 0 和 1,不认识 “Apple”。我们需要一种方法把单词映射到数学空间。

1.1 上古时代:One-Hot 编码

  • 做法:假设字典里有 10000 个词。“Apple” 是第 3 个,向量就是 [0, 0, 1, 0, ...]
  • 缺点
    1. 稀疏:维度太高,全是 0,浪费空间。
    2. 语义鸿沟:它认为 “Apple” 和 “Orange” 的距离,跟 “Apple” 和 “Car” 的距离是一样的(都是 2\sqrt{2}2 )。实际上苹果和橘子应该更近。

1.2 分布式表示:Word Embedding

  • 核心思想一个词的含义由它的上下文决定(Distributional Hypothesis)。
  • 目标:把每个词映射为一个低维、稠密的向量(如 256 维),且语义相似的词在空间距离更近

2. Word2Vec:NLP 的第一个里程碑

2013年,Google 发布的 Word2Vec 让 NLP 突飞猛进。它不是一个深度神经网络,而是一个浅层的双层网络。

2.1 两种模式

  1. CBOW (Continuous Bag of Words)
    • 任务:看周围的词(上下文),填中间的词。
    • Example: The ? sat on the mat. →\to cat
  2. Skip-Gram
    • 任务:看中间的词,猜周围的词。
    • Example: cat →\to The, sat, on…

2.2 训练黑科技:负采样 (Negative Sampling)

  • 如果字典有 10万 个词,做 Softmax 分类计算量太大了(分母要算 10万 次指数)。
  • 负采样:既然正确答案是 “cat” (正样本),我就随机挑 5 个不是 “cat” 的词(负样本,如 “car”, “sky”)。
  • 任务变成了一个简单的二分类:分辨这个词是正样本还是负样本。计算量瞬间降下来了。

2.3 神奇的加减法

Word2Vec 训练出来的向量具有有趣的代数性质:
Vector(King)−Vector(Man)+Vector(Woman)≈Vector(Queen) Vector(\text{King}) - Vector(\text{Man}) + Vector(\text{Woman}) \approx Vector(\text{Queen}) Vector(King)Vector(Man)+Vector(Woman)Vector(Queen)


3. 分词的进化:从 Word 到 Subword

在深度学习时代,我们很少直接用 Word(单词)做单位了,因为会有 OOV (Out of Vocabulary) 问题。

  • Word-level:字典必须包含 “look”, “looks”, “looked”, “looking”。遇到 “lookup” 就傻了(Unknown Token)。
  • Character-level:把单词拆成字母 ‘l’, ‘o’, ‘o’, ‘k’。粒度太细,序列太长,语义太散。
  • Subword-level (子词):折中方案。这也是目前大模型(GPT/BERT)的标准配置。

3.1 BPE (Byte Pair Encoding)

  • 原理:统计语料库,把最常一起出现的字符对合并成一个新的 Token。
  • 过程
    1. 初始状态:l o o k, l o o k i n g
    2. 发现 in 经常在一起 →\to 合并为 in
    3. 发现 ing 经常在一起 →\to 合并为 ing
    4. 最后:look 是一个 Token,ing 是一个 Token。
  • 优势
    • 常见词(High frequency)保留完整单词:Apple
    • 生僻词(Low frequency)拆成词根:unfriendly →\to un, friend, ly
    • 彻底解决了 OOV 问题

4. 文本预处理 Pipeline

做一个 NLP 任务,标准流程通常是:

  1. Normalization:转小写、去标点、去特殊符号。
  2. Tokenization:分词(使用训练好的 Tokenizer,如 BERT 的 WordPiece)。
  3. Indexing:把 Token 变成 ID (Lookup Table)。
  4. Padding/Truncating:把所有句子对齐到相同长度(短补 0,长截断)。
  5. Embedding:输入模型查找 Embedding Matrix。

5. 代码实践:使用 PyTorch 的 Embedding

nn.Embedding 本质上就是一个查表操作,它可以被训练。

import torch
import torch.nn as nn

# 1. 定义词表大小和向量维度
vocab_size = 10000
embed_dim = 256

# 2. 初始化 Embedding 层
# 这是一个 [10000, 256] 的矩阵,每一行代表一个词的向量
embedding_layer = nn.Embedding(num_embeddings=vocab_size, embedding_dim=embed_dim)

# 3. 输入数据 (必须是 LongTensor 类型的 ID)
# 假设是一个 Batch,包含两个句子,每个句子 4 个词
input_ids = torch.LongTensor([
    [1, 523, 23, 9],    # Sentence 1 IDs
    [2, 44, 888, 0]     # Sentence 2 IDs
])

# 4. 前向传播
# Output shape: [2, 4, 256]
vectors = embedding_layer(input_ids)

print(f"Input shape: {input_ids.shape}")
print(f"Output vectors shape: {vectors.shape}")

# 5. Word2Vec 的负采样 Loss 示例 (伪代码)
# pos_score = torch.sigmoid(torch.sum(center_vec * context_vec, dim=1))
# neg_score = torch.sigmoid(torch.sum(center_vec * negative_vec, dim=1))
# loss = -torch.log(pos_score) - torch.sum(torch.log(1 - neg_score))

6. 总结

  • One-Hot 是过去式,Word Embedding(稠密向量)是现代 NLP 的基石。
  • Word2Vec 利用上下文自监督学习词义,开启了 Embedding 时代。
  • Subword (BPE/WordPiece) 解决了未登录词 (OOV) 问题,是 Transformer 模型的标配。
  • 预告:虽然 Word2Vec 很强,但它有个致命缺陷——它是静态的。不管上下文怎么变,“Bank” 的向量永远不变(无法区分“银行”和“河岸”)。明天我们将学习 ELMo 和 BERT,看看如何解决多义词问题。

思考:为什么现在的 LLM (如 GPT-4) 还是用 Embedding?不能直接把文字当图像处理吗?

  • 虽然有尝试(如 Pixel-based LLM),但文字本身是高度抽象的符号系统,Embedding 是目前最高效的将离散符号转化为连续语义空间的手段。

如果有更多问题,欢迎关注公众号【算法最TOP】进一步讨论!

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐