Word2Vec

概述

  1. NLP 中,在文本预处理后,进行特征提取,涉及到将词语转化成数值的形式,方便计算机理解
  2. Word2Vec 的目的 - 将词语转换成向量形式,使得计算机能够理解
  3. 通过学习大量文本数据,捕捉到词语之间的上下文关系,进而生成词的高维表示 - 即词向量

架构

Word2Vec 有 2 种主要的模型 - Skip-Gram + CBOW

Model Desc
CBOW 根据周围的上下文词汇来预测目标词
Skip-Gram 根据目标词预测其周围的上下文词汇

优劣

Key Value
优点 揭示之间的相似性 - 通过计算向量之间的距离来找到语义相近的词
缺点 无法处理多义词,每个词被赋予一个向量,不考虑上下文中的多种含义

模型架构

连续词袋 - Continuous Bag of Words, CBOW
跳字模型 - Skip-Gram

word2vec-model

连续词袋

  1. CBOW 模型是一种通过上下文预测目标词的神经网络架构
  2. 上下文由目标词周围的一个词或多个词组成,这个数目由窗口大小决定
  3. 窗口是指上下文词语的范围 - 如果窗口为 10,那么模型将使用目标词前后各 10 个词

跳字模型

  1. Skip-Gram 模型是一种通过一个给定的目标词来预测其上下文词的神经网络
  2. CBOW 模型相反,Skip-Gram 每次接收一个词作为输入,并预测它周围的词
  3. 适用场景 - 处理较大数据集 + 捕获罕见词

构建模型

数据收集

微博内容数据集 - http://www.nlpir.org/wordpress/download/weibo_content_corpus.rar

1
2
3
4
5
6
7
8
9
10
11
12
<RECORDS>
<RECORD>
<id>423</id>
<article>@小艳子kiki @光影魔术师之择日而栖 @就是爱黑巧克力 尝试新的外景风格,亲们,我有木有拍婚纱照的潜质?</article>
<discuss>5</discuss>
<insertTime>2011/11/18 11:08:16</insertTime>
<origin>新浪微博</origin>
<person_id>1043652517</person_id>
<time>2011/11/13 14:38:32</time>
<transmit>0</transmit>
</RECORD>
</RECORDS>

数据预处理

加载数据 -> 分词 -> 去除停用词

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import jieba
import xml.etree.ElementTree as ElementTree

# 读取XML文件并解析
file_path = 'data.xml'
tree = ElementTree.parse(file_path)
root = tree.getroot()

# 获取所有<article>标签的内容
texts = [record.find('article').text for record in root.findall('RECORD')]
print("texts: ", len(texts)) # 227532

# 停用词列表,实际应用中需要根据实际情况扩展
stop_words = {"的", "了", "在", "是", "我", "有", "和", "就"}

# 分词和去除停用词
processed_texts = []
for text in texts:
if text is not None:
words = jieba.cut(text) # 使用jieba分词
processed_text = [word for word in words if word not in stop_words] # 去除停用词
processed_texts.append(processed_text)

# 打印预处理后的文本
print("processed_text: ", len(processed_texts))
for text in processed_texts[0:1]:
print(text)

输出

1
2
3
4
5
6
7
texts:  227532
Building prefix dict from the default dictionary ...
Loading model from cache /var/folders/mf/yq4wcqc961b_wt11zlchrpr40000gn/T/jieba.cache
Loading model cost 0.317 seconds.
Prefix dict has been built successfully.
processed_text: 227333
['@', '小艳子', 'kiki', ' ', '@', '光影', '魔术师', '之', '择日', '而', '栖', ' ', '@', '就是', '爱黑', '巧克力', ' ', '尝试', '新', '外景', '风格', ',', '亲们', ',', '木有', '拍', '婚纱照', '潜质', '?']

训练模型

1
2
3
4
5
6
7
from gensim.models import Word2Vec

# 训练Word2Vec模型
model = Word2Vec(sentences=processed_texts, vector_size=100, window=5, min_count=1, workers=4, sg=0)

# 保存模型
model.save("word2vec.model")

使用 gensim 库来训练 Word2Vec 模型

Parameter Desc
vector_size 词向量的维度
window 上下文窗口的大小
min_count 词频的最小阈值
workers 训练的线程数
sg Training algorithm: 1 for skip-gram; otherwise CBOW.

执行完成后,本地会生成 3 个文件

  1. word2vec.model
    • 主模型文件,包含了模型的参数词汇表等信息
    • 存储了模型的架构信息,还包括词汇频率模型训练状态等信息
    • 该文件是加载完整模型必需
  2. word2vec.model.wv.vectors.npy
    • 存储了模型中所有词汇词向量
    • Word2Vec 模型通过学习这些词向量来捕捉词语之间的关系
    • .npy 是 NumPy 数组的文件格式
      • 意味着词向量是以 NumPy 数组的形式存储的,可以高效加载处理
  3. word2vec.model.syn1neg.npy
    • 存储训练过程中使用的负采样权重
    • 当设置 Word2Vec 模型的 negative 参数大于 0 时,启用负采样优化模型的训练过程
    • 该文件中的权重是模型训练中用于负采样的部分,对于模型的学习生成词向量至关重要

评估应用

相似词

1
2
3
4
5
6
7
8
9
10
11
12
13
# 加载模型
from gensim.models import Word2Vec

model = Word2Vec.load("word2vec.model")
print("模型加载完成")

# 使用模型
# 获取一个词的向量
print(model.wv['科技'])

# 找到最相似的词
similar_words = model.wv.most_similar('科技', topn=5)
print(similar_words)

输出 - IT / 产业 / 创新 / 雪旭 / 影响力

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
模型加载完成
[-0.6348176 0.980737 1.3416016 -1.0943173 0.48774573 -0.11640034
-1.1861979 0.20502706 -0.8404337 -0.20358181 -1.2326834 3.0182338
0.47568646 -0.79827523 -1.4702528 -2.394634 -1.0629824 -2.0688376
1.027351 0.37530035 -0.3730972 -3.559652 4.2347307 -0.87267554
-1.1799742 -0.9208792 0.0861944 1.6402626 -0.53943187 1.1883249
2.41559 -0.2823076 -3.535211 -1.1645912 0.94778156 -0.4898642
0.4626486 2.5746973 -2.647992 -1.5699443 -0.4694093 0.8799693
-1.8221594 1.7643374 1.1880299 1.5864822 -0.17073062 -0.17437774
-1.640661 -1.0365794 2.4317803 -0.05093269 -0.13435775 0.54337716
1.5975007 0.45699328 0.03663439 -0.3113667 0.9799479 0.6356506
0.05430077 2.5633545 1.5153742 0.4160873 -1.0201625 1.658083
-0.34198096 1.6939774 0.5338615 -1.074114 1.8961443 0.69968593
-0.09772874 0.3093397 0.81288207 -2.2023287 0.21640573 2.1103783
1.3334064 -1.5603698 1.5838771 0.7338234 -2.969703 -1.2002374
0.9270903 0.12712173 -1.3719993 0.8439459 -1.5193253 -2.1521263
0.48004547 0.18645923 -2.7400064 -0.81356317 -0.01708121 1.6114978
-1.203191 -1.6334691 0.6092569 -2.7504272 ]
[('IT', 0.6385517716407776), ('产业', 0.6334002614021301), ('创新', 0.6308589577674866), ('雪旭', 0.6188406944274902), ('影响力', 0.6094681024551392)]

评估方式

  1. 相似度计算
    • 通过比较模型生成的词与人工标注的词的相似度来评估模型,一致性越高,说明效果越好
    • 常用的数据集 - WordSim-353 / SimLex-999
  2. 类比计算
    • 评估模型在解决类比问题的能力 - 词 A 之于词 B如同词 C 之于什么
    • 例如 - 北京之于中国如同巴黎之于什么?
  3. OOV 词比率 - Out of vision
    • 评估数据集中有多少词对包含未知词(模型词汇表外的词)而被排除在评估之外的比率
    • 理想情况下,OOV 率应该尽可能低,以确保评估结果更全面地代表模型的性能
  4. 定性分析
    • 对于给定的词汇,查看模型认为与其最相似的其它词汇,判定这些词汇是否符合预期
  5. 实际应用
    • 将 Word2Vec 模型应用到具体的下游任务,观察模型表现的提升
    • 通过比较使用 Word2Vec 词向量前后的任务表现,可以间接评估 Word2Vec 模型的有效性

手动创建评估集 - 实际评估过程中,评估数据集可以基于偏好进行人工打分

相似词 1 相似词 2 人工评分
没有 还有 1.1
腐败 媒体 6
微博 工作 2
北京 世界 7
可以 9
不是 0
问题 情况 8
他们 网友 7.3
今天 明天 6.9
美国 社会 3
政府 国家 7.2
大家 城管 3.0
公司 企业 9
孩子 朋友 6.1
经济 全国 7
时间 出现 2.1
分享 转发 8
记者 认为 5
你们 学生 6

评估方式 - 词类比计算

1
2
3
4
5
6
7
8
9
# 加载模型
from gensim.models import Word2Vec

model = Word2Vec.load("word2vec.model")
print("模型加载完成")

# 类比
result = model.wv.evaluate_word_pairs("valid.tsv")
print(result)

输出 - Pearson / Spearman 相关性系数

1
2
模型加载完成
(PearsonRResult(statistic=0.5439840080013675, pvalue=0.02398644828373347), SignificanceResult(statistic=0.47695369660310627, pvalue=0.052886954016578384), 10.526315789473683)

Pearson 系数

  1. statistic=0.5439840080013675
    • 范围 -1 ~ 1,其中 1 表示完全正相关,而 -1 表示完全负相关,而 0 表示无相关
    • 54 意味着模型的词向量人工评分之间存在中等程度正相关
  2. pvalue=0.02398644828373347
    • 用于检验相关性统计显著性,一个常用的显著性水平阈值0.05
    • 值为 0.02,小于 0.05,意味着这个相关性是统计显著
      • 可以认为模型的词向量人工评分之间的相关性不是偶然出现的 - 很有说服力

Spearman 系数

  1. statistic=0.47695369660310627
    • 范围 -1 ~ 1,Spearman 系数考虑的是变量之间等级关系,而不是直接的数值大小
    • 0.47 同样意味着中等程度正相关
  2. pvalue=0.052886954016578384
    • 小于 0.05 ≈ 相关性是统计显著

OOV 率 - 评估数据集中出现的词汇不在模型词汇表里的概率 - Out of vision

  1. 10.526315789473683 - 大约有 10.53% 的词对包含至少一个不在模型词汇表中的词
  2. 该部分词对在评估过程中被忽略不参与相关性计算

小结

  1. 一个好的 Word2Vec 模型应该在相关性测试中展现出与人类判断一致趋势
  2. 指标
    • 比较PearsonSpearman 相关性系数(>0.5
    • 具有统计显著性,即较p 值(< 0.05
    • 并具有可接受OOV

模型优劣

容易理解 + 上手简单 + 应用广泛

优点

Advantage Desc
词嵌入质量高 能够学习到富含语义信息高质量词向量,使得语义上相近的词在向量空间上也相近
捕捉多种语言规律 能够捕捉到一定的语法和语义规律,如词类比 - 男人之于女人如同国王之于王后
效率高 相比于早期的基于矩阵分解的词嵌入方法,Word2Vec 训练效率更高 - 适用于大规模语料库
可解释性 学习到词向量具有一定的可解释性,可以通过向量运算进行词之间的关系探索

缺点

只认识见过的词 + 无法处理多义词 + 依赖大量文本 + 上下文独立 + 词汇级别

Disadvantage Desc
OOV 问题 只能对其训练期间见过的词汇生成词向量,对于新出现或者罕见的词汇,无法直接提供词向量
语义多样性 每个词生成一个唯一的词向量,无法直接处理一个词多种含义的情况,即多义词问题
依赖大量文本数据 为了训练出高质量的词向量,需要大量的文本数据,在数据量教小的情况下,模型效果可能会受损
上下文独立 生成的词向量静态的,不考虑词在特定句子中的上下文
ELMoBERT上下文相关的词嵌入模型
缺乏层次化表示 提供的是词汇级别的向量表示,缺乏更细致语法语义结构,在复杂的 NLP 任务中是必须的

应用场景

能够捕捉到词语之间复杂语义语法关系,因此在 NLP 任务广泛使用

Task Desc
计算文本相似度 比较文本中词向量平均值加权平均值
文档分类、推荐系统中相似项目的检索、在法律文档中查找相关内容
情感分析 识别用户评论、帖子中的情绪态度
机器翻译 用来生成源语言目标语言词向量,通过这些向量来改进翻译模型的性能 - 罕见词或短语
搜索引擎优化 理解用户的查询意图,提高搜索结果的相关性
分析查询文档内容词向量相似度,提供更准确、更贴近用户意图的搜索结果
内容推荐系统 分析用户的阅读或者购买历史,并推荐语义上相近的产品或内容