2.1 词嵌入技术基础


文档摘要

2.1 词嵌入技术基础 词嵌入的概念与意义 词嵌入是将离散的词语转换为连续向量空间中的点,实现语义的数学化表示: 语义映射:将词语的语义关系转换为向量空间中的几何关系 降维表示:将高维稀疏的one-hot编码压缩为低维稠密向量 相似性计算:通过向量运算量化词语间的语义相似度 词嵌入技术的核心思想来自于分布式语义假说:一个词语的含义可以通过其上下文来定义。通过在大规模文本语料上进行训练,算法能够学习到词语间的语义关系,并将其编码为向量空间中的几何关系。

2.1 词嵌入技术基础

词嵌入的概念与意义

词嵌入是将离散的词语转换为连续向量空间中的点,实现语义的数学化表示:

  • 语义映射:将词语的语义关系转换为向量空间中的几何关系
  • 降维表示:将高维稀疏的one-hot编码压缩为低维稠密向量
  • 相似性计算:通过向量运算量化词语间的语义相似度

词嵌入技术的核心思想来自于分布式语义假说:一个词语的含义可以通过其上下文来定义。通过在大规模文本语料上进行训练,算法能够学习到词语间的语义关系,并将其编码为向量空间中的几何关系。

词嵌入的数学原理

One-hot编码的局限性

在传统的自然语言处理中,词语通常使用one-hot编码表示:

词语:机器学习 编码:[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0] 维度:V=12(词汇表大小)

One-hot编码存在以下严重问题:

  • 维度灾难:词汇表很大时,向量维度极高
  • 语义稀疏性:向量大部分元素为0,无法表示语义相似性
  • 计算效率低:高维向量的存储和计算成本高昂
  • 无语义信息:无法反映词语间的语义关系

词向量的表示方法

词嵌入使用低维稠密向量表示词语,例如:

"机器学习" → [0.23, -0.45, 0.67, 0.12, -0.34, 0.89, -0.56, 0.43] "人工智能" → [0.21, -0.43, 0.65, 0.15, -0.32, 0.87, -0.54, 0.41] "深度学习" → [0.25, -0.47, 0.69, 0.14, -0.36, 0.91, -0.58, 0.45]

这样的表示具有以下优势:

  • 维度适中:通常100-300维,避免维度灾难
  • 稠密表示:所有维度都有意义值
  • 语义连续性:语义相似的词语在向量空间中距离相近
  • 计算高效:向量运算简单快捷

Word2Vec模型详解

Word2Vec的基本原理

Word2Vec是Google在2013年提出的词嵌入模型,包含两种主要架构:

1. CBOW(Continuous Bag of Words)

上下文词语 --> 中间词 [学生, 在, 学校, 里] --> 学习

CBOW通过上下文词语预测中间词语,学习到的向量能够反映词语的语法和语义信息。

2. Skip-gram

中间词 --> 上下文词语 学习 --> [学生, 在, 学校, 里]

Skip-gram通过中间词语预测上下文词语,更适合处理低频词语和不规则表达。

Word2Vec的数学模型

Word2Vec的核心是softmax函数和负采样技术:

Softmax函数

P(w_j | w_i) = exp(u_j · v_i) / Σ(exp(u_k · v_i))

其中:

  • w_i 是中心词
  • w_j 是候选词
  • v_i 是中心词的输入向量
  • u_j 是候选词的输出向量

负采样:为了避免计算整个词汇表的softmax,使用负采样方法,只计算正样本和少量负样本的损失函数。

Word2Vec的实现细节

import numpy as np from collections import defaultdict class Word2Vec: def __init__(self, vector_size=100, window=5, min_count=5): self.vector_size = vector_size self.window = window self.min_count = min_count self.vocab = {} self.word_vectors = {} self.context_vectors = {} def build_vocab(self, sentences): """构建词汇表""" word_counts = defaultdict(int) # 统计词频 for sentence in sentences: for word in sentence: word_counts[word] += 1 # 过滤低频词 self.vocab = { word: idx for word, count in word_counts.items() if count >= self.min_count } # 初始化词向量 for word, idx in self.vocab.items(): self.word_vectors[word] = np.random.normal(0, 0.1, self.vector_size) self.context_vectors[word] = np.random.normal(0, 0.1, self.vector_size) def generate_training_data(self, sentences): """生成训练数据""" training_data = [] for sentence in sentences: for i, word in enumerate(sentence): if word not in self.vocab: continue # 生成上下文窗口 for j in range(max(0, i-self.window), min(len(sentence), i+self.window+1)): if j == i or sentence[j] not in self.vocab: continue positive_sample = (self.vocab[word], self.vocab[sentence[j]]) training_data.append(positive_sample) return training_data def train(self, training_data, epochs=10, learning_rate=0.01): """训练Word2Vec模型""" for epoch in range(epochs): total_loss = 0 for center_word, context_word in training_data: # 获取向量 v_center = self.word_vectors[center_word] u_context = self.context_vectors[context_word] # 计算softmax scores = np.dot(list(self.word_vectors.values()), u_context) exp_scores = np.exp(scores) probs = exp_scores / np.sum(exp_scores) # 计算梯度 grad_output = probs.copy() grad_output[center_word] -= 1 # 更新向量 word_list = list(self.word_vectors.keys()) for i, word in enumerate(word_list): if i == center_word: self.word_vectors[word] -= learning_rate * np.dot(u_context, grad_output) else: self.context_vectors[word] -= learning_rate * np.dot(v_center, grad_output) total_loss += -np.log(probs[center_word]) print(f"Epoch {epoch+1}, Loss: {total_loss}")

GloVe模型详解

GloVe的统计基础

GloVe(Global Vectors for Word Representation)是斯坦福大学提出的词嵌入模型,基于全局词-词共现矩阵的统计信息。

核心思想:词向量的点积应该近似等于对数共现概率:

w_i · w_j = log P(i|j)

其中:

  • w_iw_j 是两个词的向量
  • P(i|j) 是词j出现时词i出现的条件概率

GloVe的损失函数

GloVe使用加权最小二乘法:

J = Σ_{i,j=1}^{V} f(X_{ij}) (w_i · w_j + b_i + b_j - log X_{ij})²

其中:

  • X_{ij} 是词i和词j的共现次数
  • f(X_{ij}) 是权重函数,用于调节高频词的影响
  • b_ib_j 是偏置项

GloVe与Word2Vec的区别

特性 Word2Vec GloVe
训练目标 局部上下文预测 全局统计关系
数学基础 概率模型 线性代数模型
计算效率 高(在线学习) 中等(批处理)
语义表示 上下文语义 全局语义关系
词向量质量 良好 更稳定

FastText模型详解

FastText的核心创新

FastText是Facebook在2016年提出的词嵌入模型,主要创新在于:

  1. 词形处理:使用n-gram表示词语,解决OOV问题
  2. 分层softmax:使用霍夫曼编码加速训练
  3. 子词信息:能够处理形态丰富的语言

n-gram表示法

FastText将词语表示为其n-gram字符序列的向量和:

"机器学习" = ["机器", "学习", "器学", "习学"] vector("机器学习") = vector("机器") + vector("学习") + vector("器学") + vector("习学")

这种表示方式具有以下优势:

  • 解决OOV问题:即使新词不存在,其字符n-gram可能存在于训练集中
  • 形态处理:能够处理词形变化和屈折变化
  • 信息丰富:保留了词语的内部结构信息

FastText的实现特点

from collections import defaultdict class FastText: def __init__(self, vector_size=100, ngram_min=3, ngram_max=5): self.vector_size = vector_size self.ngram_min = ngram_min self.ngram_max = ngram_max self.word_vectors = {} self.ngram_vectors = {} def generate_ngrams(self, word): """生成词语的n-gram""" ngrams = [] word = f"<{word}>" # 添加边界标记 for n in range(self.ngram_min, self.ngram_max + 1): for i in range(len(word) - n + 1): ngram = word[i:i+n] ngrams.append(ngram) return ngrams def get_word_vector(self, word): """获取词语的完整向量表示""" if word not in self.word_vectors: # 计算n-gram向量和 ngrams = self.generate_ngrams(word) word_vector = np.zeros(self.vector_size) for ngram in ngrams: if ngram in self.ngram_vectors: word_vector += self.ngram_vectors[ngram] self.word_vectors[word] = word_vector return self.word_vectors[word]

BERT与Transformer-based Embedding

BERT的革命性突破

BERT(Bidirectional Encoder Representations from Transformers)是Google在2018年提出的双向Transformer模型,代表了NLP领域的重大突破。

核心特点

  1. 双向注意力:同时考虑左右上下文信息
  2. 预训练+微调:在大规模无标注数据上预训练,在下游任务上微调
  3. 深层架构:使用12层或24层的Transformer编码器
  4. 上下文感知:同一词语在不同上下文中具有不同的表示

BERT的架构设计

import torch import torch.nn as nn class BERTEmbeddings(nn.Module): def __init__(self, vocab_size, hidden_size, max_position_embeddings, type_vocab_size): super().__init__() self.word_embeddings = nn.Embedding(vocab_size, hidden_size) self.position_embeddings = nn.Embedding(max_position_embeddings, hidden_size) self.token_type_embeddings = nn.Embedding(type_vocab_size, hidden_size) self.LayerNorm = nn.LayerNorm(hidden_size, eps=1e-12) self.dropout = nn.Dropout(0.1) def forward(self, input_ids, token_type_ids=None): seq_length = input_ids.size(1) position_ids = torch.arange(seq_length, dtype=torch.long, device=input_ids.device) position_ids = position_ids.unsqueeze(0).expand_as(input_ids) words_embeddings = self.word_embeddings(input_ids) position_embeddings = self.position_embeddings(position_ids) token_type_embeddings = self.token_type_embeddings(token_type_ids) embeddings = words_embeddings + position_embeddings + token_type_embeddings embeddings = self.LayerNorm(embeddings) embeddings = self.dropout(embeddings) return embeddings

BERT在搜索中的应用

  1. 查询理解:理解用户查询的真实意图
  2. 文档向量化:将文档转换为高质量的语义向量
  3. 上下文感知:支持对话和多轮查询
  4. 多语言支持:支持中文、英文等多种语言

词嵌入技术的选择指南

不同场景的适用模型

应用场景 推荐模型 理由
通用语义搜索 Word2Vec 简单高效,语义效果良好
学术研究 GloVe 数学理论基础扎实
形态复杂语言 FastText 处理OOV和形态变化
高级语义理解 BERT 上下文感知,深度语义
实时搜索 DistilBERT 轻量级,推理速度快
长文档 Longformer 处理长文本序列

性能对比分析

训练性能

  • Word2Vec:训练速度快,内存占用小
  • GloVe:训练速度中等,需要大量内存
  • FastText:训练速度慢,但支持大规模词汇
  • BERT:训练非常耗时,需要GPU资源

推理性能

  • Word2Vec/GloVe:毫秒级响应,适合实时搜索
  • FastText:微秒级响应,适合高频查询
  • BERT:秒级响应,适合离线处理
  • DistilBERT:百毫秒级,平衡速度和质量

模型选择决策树

开始 ├── 是否需要处理OOV词汇? │ ├── 是 → FastText │ └── 否 → 继续判断 ├── 是否需要上下文感知? │ ├── 是 → BERT/DistilBERT │ └── 否 → 继续判断 ├── 训练数据规模如何? │ ├── 小 → Word2Vec │ └── 大 → GloVe ├── 推理延迟要求? │ ├── 严格 → Word2Vec │ └── 宽松 → 可选择高级模型 └── 计算资源? ├── 充足 → BERT └── 有限 → Word2Vec/FastText

词嵌入技术的实际应用案例

案例1:电商搜索优化

场景:用户搜索"苹果手机",需要包含"iPhone"相关商品。

解决方案

# 使用Word2Vec构建同义词映射 synonyms = { "苹果": ["苹果", "Apple", "iphone", "iPhone"], "手机": ["手机", "手机", "phone", "Phone"] } def expand_query(query): expanded = [query] for word in query.split(): if word in synonyms: expanded.extend(synonyms[word]) return expanded

效果

  • 召回率提升35%
  • 用户满意度提升28%

案例2:智能客服问答

场景:用户提问"怎么重置密码",需要匹配相关问题。

解决方案

# 使用BERT计算语义相似度 def semantic_similarity(query, faq_questions): query_vector = get_bert_embedding(query) similarities = [] for question in faq_questions: question_vector = get_bert_embedding(question) similarity = cosine_similarity(query_vector, question_vector) similarities.append((question, similarity)) return sorted(similarities, key=lambda x: x[1], reverse=True)

效果

  • 匹配准确率提升60%
  • 用户等待时间减少45%

案例3:学术文献检索

场景:研究人员查找特定技术领域的论文。

解决方案

# 使用GloVe处理技术术语 def build_tech_domain_embedding(domain_terms): domain_vector = np.zeros(vector_size) for term in domain_terms: if term in vocabulary: domain_vector += word_vectors[term] return domain_vector / len(domain_terms) # 计算文献相关性 def calculate_paper_relevance(paper_text, domain_vector): paper_vector = average_embedding(paper_text.split()) return cosine_similarity(paper_vector, domain_vector)

效果

  • 相关性提升50%
  • 检索时间减少30%

发布者: 作者: 转发
评论区 (0)
U