1 WordNet使用
1.1 简介
wordnet:一个词典
调用wordnet:
from nltk.corpus import wordnet as wn
- lemma 词根
- synonym 同义词
- hypernym 上位词
- hyponym 下位词
1.2 使用
poses = {'n':'noun','v':'verb','s':'adj(s)', 'a':'adj', 'r':'adv'}
for synset in wn.synsets('good'):
print('{}:{}'.format(poses[synset.pos()], ','.join([l.name() for l in synset.lemmas()])))
-
synsets()
查看一个单词的同义词集合,synonym sets -
pos()
查看单词的词性,可以为(n|v|s|a|r),分别表示(名词|动词|形容词|副词) -
hypernyms()
查看单词的上位词 -
一个 synset 被一个三元组描述:(单词.词性.序号)。
如 ’dog.n.01’ 指:dog 的第一个名词意思;’chase.v.01’ 指:chase 的第一个动词意思。
2 词向量前期发展
2.1 one-hot
用 R ∣ V ∣ × 1 \mathbb{R}^{|V| \times 1} R∣V∣×1 维度的词向量代表每个单词,词向量只由 0 和 1 表示,给出一个很大的词汇表 V,词汇表中的单词是排序的,然后用这个词汇表中的序号代表每个单词中 1 出现的位置。
缺点:
- 所有词向量都是正交的,无法表示单词之间的相似度关系
- 词汇表一般很大,这样表示的词向量的维度也很大
2.2 SVD Based Methods
2.2.1 Word-Document Matrix
词-文档矩阵,X 是按照以下方式构建:遍历数亿的文档和当词 i 出现在文档 j,我们对 Xij 加一。这是一个很大的矩阵( R ∣ V ∣ × M \mathbb{R}^{|V| \times M} R∣V∣×M),它的规模是和文档(M)成正比关系。
2.2.2 Window based Co-occurrence Matrix共现矩阵
计算每个单词在我们感兴趣单词的附近特定大小的窗口中出现的次数。按照这个方法对语料库中的所有单词进行统计。
打个栗子:
有三句话
- I enjoy flying。
- I like NLP。
- I like deep learning。
计数矩阵的结果如下所示:
通过这两种方法得到的矩阵,通过奇异值分解,选择前 K 个行向量作为词向量。
这两种方法都给我们提供了足够的词向量来编码语义和句法(part of speech)信息,但伴随许多其他问题
- 矩阵的维度会经常发生改变(经常增加新的单词和语料库的大小会改变)。
- 矩阵会非常的稀疏,因为很多词不会共现。
- 矩阵维度一般会非常高
- 基于 SVD 的方法的计算复杂度很高 ( m×n 矩阵的计算成本是 O({mn}^2) ),并且很难合并新单词或文档
- 需要在 X 上加入一些技巧处理来解决词频的急剧不平衡(比如某个单词在文档中出现的概率为0,并不表示这个单词不存在)
对上述讨论中存在的问题存在以下的解决方法:
- 忽略功能词,例如 “the”,“he”,“has” 等等。
- 根据文档中单词之间的距离对共现计数进行加权
- 使用皮尔逊相关系数并将负计数设置为0,而不是只使用原始计数
3 Word2vec
两个算法:CBOW 和 skip-gram
- CBOW:由上下文单词预测中心单词
- skip-gram:由中心单词预测上下文单词
两种训练方法:negative sampling 和 hierarchical softmax
3.1 n-gram
一个单词出现的概率依赖于它从第一个单词w1到它之前一个单词 w i − 1 w_{i−1} wi−1的影响:
p(S)=p(w1w2⋯wn)=p(w1)p(w2∣w1)⋯p(wn∣wn−1⋯w2w1)
问题:参数空间过大;数据稀疏严重;
引入:马尔科夫假设,这个单词出现的概率只与他前 n 个单词出现的概率有关,这就是 n-gram
3.2 skip-gram
skip-gram:由中心单词预测上下文单词
在skip-gram模型中,每个词被表示成两个 d 维向量,用来计算条件概率。假设这个词在词典中索引为 i,当它为中心词时向量表示为 Vi,而为背景词时向量表示为 Ui 。设中心词 Wc 在词典中索引为 C,背景词 Wo 在词典中索引为 O,我们假设给定中心词生成背景词的条件概率满足下式:
3.3 CBOW(Continuous bag-of-words)
CBOW:由上下文单词预测中心单词
问题:skip-gram 和 CBOW 的梯度计算的开销与词典 V 的大小相关。词典很大时,计算开销很大,因此采用「负采样」或者「hierarchical softmax」来解决这个问题。
3.4 负采样(negative sampling)
词典 V 大小之所以会在目标函数中出现,是因为中心词 Wc 生成背景词 Wo 的概率 P(Wo | Wc ) 使用了 softmax,而softmax正是考虑了背景词可能是词典中的任一词, 并体现在softmax的分母上。
我们不妨换个角度,假设中心词 Wc 生成背景词 Wo 由以下两个相互独立事件联合组成来近似:
- 中心词 Wc 和背景词 Wo 同时出现在该训练数据窗口
- 中心词 Wc 和第 1 个噪声词 W1 不同时出现在该训练数据窗口(噪声词 W1 按噪声词分布 P(w) 随机生成)
- … …
- 中心词 Wc 和第 K 个噪声词 Wk 不同时出现在该训练数据窗口(噪声词 Wk 按噪声词分布 P(w) 随机生成)
其中,k 是采样个数,P(w)是一个unigram分布
。此处的采样是基于词出现频率的采样,具体实现时,对词频取了0.75次幂
:
len
(
w
)
=
[
counter
(
w
)
]
0.75
∑
u
∈
D
[
counter
(
u
)
]
0.75
\operatorname{len}(w)=\frac{[\text { counter }(w)]^{0.75}}{\sum_{u \in D}[\operatorname{counter}(u)]^{0.75}}
len(w)=∑u∈D[counter(u)]0.75[ counter (w)]0.75
负采样的公式为(以skip-gram为例):
对于CBOW,最后的公式为:
对于一对中心词和背景词,我们从词典中随机采样 K 个噪声词(实验中设 K=5)。根据 Word2Vec 论文的建议,噪声词采样概率 P(w) 设为 W 词频与总词频之比的 0.75 次方。
3.5 代码
在建立词语索引时:
counter = collections.Counter([tk for st in raw_dataset for tk in st]) # tk是token的缩写
counter = dict(filter(lambda x: x[1] >= 5, counter.items())) # 只保留在数据集中至少出现5次的词
idx_to_token = [tk for tk, _ in counter.items()]
token_to_idx = {tk: idx for idx, tk in enumerate(idx_to_token)}
dataset = [[token_to_idx[tk] for tk in st if tk in token_to_idx]
for st in raw_dataset] # raw_dataset中的单词在这一步被转换为对应的idx
num_tokens = sum([len(st) for st in dataset])
'# tokens: %d' % num_tokens
3.5.1 collections.Counter() 用法
参考链接:https://blog.csdn.net/qwe1257/article/details/83272340
- 可以直接 Counter() 为空,之后在空的Counter上进行操作
- 也可以在创建的时候传进一个迭代器(list,string,dict等)
c = Counter('gallahad') # 传进字符串
c = Counter({'red': 4, 'blue': 2}) # 传进字典
c = Counter(cats=4, dogs=8) # 传进元组
3.5.2 filter() 用法
filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用 list() 来转换。
该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。
语法
以下是 filter() 方法的语法:
filter(function, iterable)
参数
- function – 判断函数。
- iterable – 可迭代对象。
返回值
返回一个迭代器对象
4 其他
4.1 分布式表示(distributional semantics)
distributional semantics:一个单词的意思由它上下文的单词来决定
4.2 TF-IDF
TF-IDF(term frequency–inverse document frequency,词频-逆向文件频率)是一种用于信息检索(information retrieval)与文本挖掘(text mining)的常用加权技术。
TF-IDF是一种统计方法,用以评估一个字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。
TF-IDF的主要思想是:如果某个单词在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。
其公式为 TF * IDF ,其中,
-
TF是词频(Term Frequency)
T F = 某 文 档 中 该 词 出 现 的 频 数 该 文 档 的 总 词 数 TF= \frac{某文档中该词出现的频数}{该文档的总词数} TF=该文档的总词数某文档中该词出现的频数
-
IDF是逆向文件频率(Inverse Document Frequency):某一特定词语的IDF,可以由总文件数目除以包含该词语的文件的数目,再将得到的商取对数得到。
I D F = log ( 语 料 库 的 总 文 档 数 包 含 该 词 的 文 档 数 + 1 ) IDF=\log (\frac{语料库的总文档数}{包含该词的文档数+1}) IDF=log(包含该词的文档数+1语料库的总文档数)