Embedding:词向量与语义表示
--- title: "Embedding:词向量与语义表示" description: "理解词嵌入技术从Word2Vec到现代Transformer嵌入的发展历程" tags: ["Embedding", "词向量", "语义表示", "NLP"] category: "llm" icon: "🧠"
Embedding:词向量与语义表示
什么是Embedding
Embedding(嵌入)是将离散的符号(如词语、句子、文档)映射到连续的向量空间中的过程。在向量空间中,语义相似的文本会被映射到相近的位置。
从独热编码到词向量
独热编码的局限
import numpy as np
# 独热编码示例
vocab = ['猫', '狗', '鱼', '老虎', '狮子']
one_hot = np.eye(len(vocab))
# 每个词都是正交的,无法表达语义关系
# "猫" 和 "狗" 的距离 = "猫" 和 "鱼" 的距离 = √2
print(f"猫-狗距离: {np.linalg.norm(one_hot[0] - one_hot[1]):.2f}")
print(f"猫-鱼距离: {np.linalg.norm(one_hot[0] - one_hot[2]):.2f}")
Word2Vec
Word2Vec 通过预测上下文关系学习词向量:
from gensim.models import Word2Vec
# 训练Word2Vec模型
sentences = [
['我', '喜欢', '学习', '机器', '学习'],
['深度', '学习', '是', '人工', '智能', '的', '分支'],
['自然', '语言', '处理', '是', 'NLP', '的', '全称'],
]
model = Word2Vec(
sentences,
vector_size=100, # 向量维度
window=5, # 上下文窗口
min_count=1, # 最小词频
workers=4 # 并行线程数
)
# 获取词向量
vector = model.wv['学习']
print(f"'学习'的向量维度: {vector.shape}")
# 找相似词
similar_words = model.wv.most_similar('学习', topn=5)
print("与'学习'相似的词:", similar_words)
现代Embedding技术
Transformer嵌入
在Transformer模型中,嵌入层将token ID转换为稠密向量:
import torch
import torch.nn as nn
class TransformerEmbedding(nn.Module):
def __init__(self, vocab_size, d_model, max_len=512, dropout=0.1):
super().__init__()
self.token_embedding = nn.Embedding(vocab_size, d_model)
self.position_embedding = nn.Embedding(max_len, d_model)
self.scale = d_model ** 0.5
self.dropout = nn.Dropout(dropout)
def forward(self, x):
seq_len = x.size(1)
positions = torch.arange(seq_len, device=x.device).unsqueeze(0)
token_emb = self.token_embedding(x) * self.scale
pos_emb = self.position_embedding(positions)
return self.dropout(token_emb + pos_emb)
# 使用示例
vocab_size = 30000
d_model = 768
embedding = TransformerEmbedding(vocab_size, d_model)
# 输入token IDs
input_ids = torch.randint(0, vocab_size, (2, 10)) # batch=2, seq_len=10
output = embedding(input_ids)
print(f"嵌入输出形状: {output.shape}") # [2, 10, 768]
句子嵌入
将整个句子编码为单一向量,用于语义相似度计算:
from sentence_transformers import SentenceTransformer
# 加载预训练的句子嵌入模型
model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2')
# 编码句子
sentences = [
"机器学习是人工智能的子领域",
"深度学习是机器学习的一个分支",
"今天天气真好"
]
embeddings = model.encode(sentdings)
print(f"嵌入形状: {embeddings.shape}") # (3, 384)
# 计算相似度矩阵
from sentence_transformers import util
similarity_matrix = util.cos_sim(embeddings, embeddings)
print("相似度矩阵:")
print(similarity_matrix)
实际应用示例
语义搜索
import numpy as np
from sentence_transformers import SentenceTransformer
class SemanticSearch:
def __init__(self):
self.model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2')
self.documents = []
self.embeddings = None
def add_documents(self, docs):
self.documents.extend(docs)
new_embeddings = self.model.encode(docs)
if self.embeddings is None:
self.embeddings = new_embeddings
else:
self.embeddings = np.vstack([self.embeddings, new_embeddings])
def search(self, query, top_k=3):
query_embedding = self.model.encode([query])
# 计算余弦相似度
similarities = np.dot(self.embeddings, query_embedding.T).flatten()
top_indices = np.argsort(similarities)[-top_k:][::-1]
results = []
for idx in top_indices:
results.append({
'document': self.documents[idx],
'score': float(similarities[idx])
})
return results
# 使用示例
search_engine = SemanticSearch()
search_engine.add_documents([
"Python是一种流行的编程语言",
"机器学习需要大量的训练数据",
"神经网络是深度学习的核心",
"自然语言处理处理文本数据",
])
results = search_engine.search("什么是深度学习")
for r in results:
print(f"文档: {r['document'][:20]}...")
print(f"相关度: {r['score']:.4f}\n")
文档聚类
from sklearn.cluster import KMeans
from sentence_transformers import SentenceTransformer
# 准备文档
documents = [
"人工智能正在改变医疗行业",
"机器学习算法可以预测疾病",
"深度学习在图像识别中表现优异",
"自然语言处理用于文本分析",
"区块链技术确保数据安全",
"云计算提供弹性计算资源",
]
# 获取文档嵌入
model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2')
embeddings = model.encode(documents)
# K-means聚类
kmeans = KMeans(n_clusters=3, random_state=42)
clusters = kmeans.fit_predict(embeddings)
# 输出聚类结果
for cluster_id in range(3):
print(f"\n=== 聚类 {cluster_id} ===")
for i, doc in enumerate(documents):
if clusters[i] == cluster_id:
print(f" - {doc[:30]}...")
嵌入模型的选择
不同任务需要不同的嵌入模型:
| 任务类型 | 推荐模型 | 特点 |
|---|---|---|
| 通用语义 | all-MiniLM-L6-v2 | 轻量高效 |
| 多语言 | paraphrase-multilingual-MiniLM-L12-v2 | 支持50+语言 |
| 长文档 | BGE-M3 | 支持8192 tokens |
| 代码 | CodeBERT | 代码理解优化 |
向量数据库集成
# 使用FAISS进行高效向量搜索
import faiss
import numpy as np
# 创建索引
dimension = 384 # 嵌入维度
index = faiss.IndexFlatIP(dimension) # 内积相似度
# 添加向量(需要归一化以使用内积)
embeddings_normalized = embeddings / np.linalg.norm(embeddings, axis=1, keepdims=True)
index.add(embeddings_normalized.astype('float32'))
# 搜索
query = model.encode(["什么是机器学习"])
query_normalized = query / np.linalg.norm(query)
distances, indices = index.search(query_normalized.astype('float32'), k=2)
print(f"最相似文档索引: {indices[0]}")
print(f"相似度分数: {distances[0]}")
总结
Embedding 是现代NLP和LLM系统的基础技术。从Word2Vec的词向量到Transformer的上下文嵌入,嵌入技术不断演进,为语义理解、信息检索、推荐系统等应用提供了强大的支持。理解不同嵌入技术的特点和适用场景,是构建高效AI应用的关键。