← 返回首页
🧠

Embedding:词向量与语义表示

📂 llm ⏱ 3 min 438 words

--- 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应用的关键。