深度学习课程中的词向量操作实践指南
前言
在自然语言处理(NLP)领域,词向量(word embeddings)已成为表示词语意义的重要工具。本文将基于深度学习课程中的词向量操作实践内容,深入探讨词向量的核心概念、应用场景以及实际操作方法。
词向量基础
词向量是将词语映射到高维空间中的向量表示,这种表示能够捕捉词语之间的语义关系。与传统的one-hot编码相比,词向量具有以下优势:
- 语义信息丰富:相似的词在向量空间中距离相近
- 维度效率高:通常使用50-300维,而非词汇表大小的维度
- 计算友好:支持各种向量运算
预训练词向量加载
在实际应用中,训练词向量计算成本很高,因此通常会使用预训练好的词向量。GloVe(Global Vectors for Word Representation)是一种常用的预训练词向量模型。
import numpy as np
from w2v_utils import *
# 加载50维GloVe词向量
words, word_to_vec_map = read_glove_vecs('data/glove.6B.50d.txt')
加载后会得到:
words
:词汇表中的所有词语集合word_to_vec_map
:词语到对应GloVe向量的映射字典
余弦相似度计算
余弦相似度是衡量两个向量相似度的常用方法,其计算公式为:
$$\text{CosineSimilarity}(u, v) = \frac{u \cdot v}{|u|_2 |v|_2} = \cos(\theta)$$
其中:
- $u \cdot v$ 表示向量的点积
- $|u|_2$ 表示向量的L2范数
- $\theta$ 是两个向量之间的夹角
实现代码如下:
def cosine_similarity(u, v):
"""
计算两个词向量之间的余弦相似度
参数:
u -- 形状为(n,)的词向量
v -- 形状为(n,)的词向量
返回:
cosine_similarity -- 根据上述公式计算的余弦相似度
"""
# 计算点积
dot = np.dot(u, v)
# 计算L2范数
norm_u = np.sqrt(np.sum(u * u))
norm_v = np.sqrt(np.sum(v * v))
# 计算余弦相似度
cosine_similarity = dot / (norm_u * norm_v)
return cosine_similarity
相似度计算示例
father = word_to_vec_map["father"]
mother = word_to_vec_map["mother"]
print("cosine_similarity(father, mother) = ", cosine_similarity(father, mother))
输出示例:
cosine_similarity(father, mother) = 0.890903844289
词语类比任务
词语类比任务是NLP中常见的测试词向量质量的基准任务,形式为"a is to b as c is to ____"。例如:"man is to woman as king is to queen"。
解决思路是找到词d,使得向量关系满足:$e_b - e_a \approx e_d - e_c$。
实现代码如下:
def complete_analogy(word_a, word_b, word_c, word_to_vec_map):
"""
完成词语类比任务
参数:
word_a -- 词语a,字符串
word_b -- 词语b,字符串
word_c -- 词语c,字符串
word_to_vec_map -- 词语到向量的映射字典
返回:
best_word -- 最佳匹配词语
"""
# 转换为小写
word_a, word_b, word_c = word_a.lower(), word_b.lower(), word_c.lower()
# 获取词向量
e_a, e_b, e_c = word_to_vec_map[word_a], word_to_vec_map[word_b], word_to_vec_map[word_c]
words = word_to_vec_map.keys()
max_cosine_sim = -100
best_word = None
# 遍历所有词语
for w in words:
# 跳过输入词语
if w in [word_a, word_b, word_c]:
continue
# 计算余弦相似度
cosine_sim = cosine_similarity(e_b - e_a, word_to_vec_map[w] - e_c)
# 更新最佳匹配
if cosine_sim > max_cosine_sim:
max_cosine_sim = cosine_sim
best_word = w
return best_word
类比任务示例
triads_to_try = [('italy', 'italian', 'spain'), ('man', 'woman', 'boy')]
for triad in triads_to_try:
print('{} -> {} :: {} -> {}'.format(*triad, complete_analogy(*triad, word_to_vec_map)))
输出示例:
italy -> italian :: spain -> spanish
man -> woman :: boy -> girl
词向量中的性别偏见问题(可选)
研究发现词向量可能反映社会中的性别偏见。例如:
g = word_to_vec_map['woman'] - word_to_vec_map['man']
print('Other words and their similarities:')
word_list = ['doctor', 'nurse', 'engineer', 'teacher']
for w in word_list:
print(w, cosine_similarity(word_to_vec_map[w], g))
输出可能显示:
doctor -0.15
nurse 0.35
engineer -0.25
teacher 0.20
这表明词向量中可能存在"医生更男性化"、"护士更女性化"等社会偏见。
偏见消除方法
可以通过以下步骤减少词向量中的性别偏见:
- 识别偏见方向:计算$g = e_{woman} - e_{man}$
- 中性化处理:对非性别特定词语,消除其在g方向上的分量
- 均衡处理:对性别特定词语对,使其在g方向上对称
总结
本文介绍了词向量的核心概念和操作,包括:
- 加载和使用预训练词向量
- 计算词语之间的余弦相似度
- 完成词语类比任务
- 识别和减少词向量中的性别偏见(可选)
词向量是NLP的基础组件,理解其特性和操作方法对后续的深度学习模型构建至关重要。通过实践这些操作,可以更深入地理解词语在向量空间中的表示方式及其语义关系。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考