同义词词典
特点
- NLP中常用的不是《新华字典》,而是一种被称为同义词词典的词典
- 在同义词词典中,具有相同含义或者类似含义的单词被归类到同一个组别中
- NLP中会定义单词之间的粒度更细的关系,比如“上位-下位”“整体-部分”
WordNet
WordNet是NLP中常用的同义词词典,普林斯顿大学在1985年开发的;在NLTK模块中已经存在这个同义词词典
同义词词典问题
- 难以顺应时代变化:新词不断出现;旧词也可能有了新意
- 制作字典需要巨大的人力成本
- 无法表示单词的微妙关系
为了解决人工定义单词含义的方法存在的问题,提出两种方案:
- 基于计数的方法
- 基于神经网络的推理的方法
基于计数方法
基于python的语料库的预处理
NLP依赖于大量的语料库corpus;语料库就是大量的文本数据。著名的语料库:
- Wikipedia
- Google News
- 莎士比亚等伟大作家的作品集也会被用作语料库
文本切割
1 | text = "You say goodbye and I say hello." |
1 | text = text.lower() # 小写 |
'you say goodbye and i say hello .'
1 | words = text.split(' ') |
['you', 'say', 'goodbye', 'and', 'i', 'say', 'hello', '.']
1 | import re |
['you',
' ',
'say',
' ',
'goodbye',
' ',
'and',
' ',
'i',
' ',
'say',
' ',
'hello',
' .',
'']
单词和单词ID对应关系
1 | word_to_id = {} |
1 | word_to_id |
{'you': 0, 'say': 1, 'goodbye': 2, 'and': 3, 'i': 4, 'hello': 5, '.': 6}
1 | id_to_word |
{0: 'you', 1: 'say', 2: 'goodbye', 3: 'and', 4: 'i', 5: 'hello', 6: '.'}
1 | id_to_word[1] |
'say'
1 | word_to_id["hello"] |
5
单词;列表转成单词ID列表
1 | # 使用列表解析式 |
array([0, 1, 2, 3, 4, 1, 5, 6])
函数封装功能
1 | # 这个函数会经常使用 |
1 | text = "You say goodbye and I say hello." |
1 | corpus |
array([0, 1, 2, 3, 4, 1, 5, 6])
1 | word_to_id |
{'you': 0, 'say': 1, 'goodbye': 2, 'and': 3, 'i': 4, 'hello': 5, '.': 6}
1 | id_to_word |
{0: 'you', 1: 'say', 2: 'goodbye', 3: 'and', 4: 'i', 5: 'hello', 6: '.'}
单词的分布式表示
单词的分布式表示将单词表示为固定长度的向量。
这种向量是密集向量,即向量的大多数元素是非0实数表示。相对应的是稀疏向量,大多数都是0。
分布式假设:某个单词的含义由它周围的单词(上下文,语境)形成的。
窗口大小:周围的单词由多少个,window size
共现矩阵
生成原理
基于计数的方法:在关注某个单词的情况下,对它的周围出现了多少次什么单词进行计数,然后再汇总
1 | import numpy as np |
{0: 'you', 1: 'say', 2: 'goodbye', 3: 'and', 4: 'i', 5: 'hello', 6: '.'}
下面统计每个单词的上下文所包含的单词的词频数,比如单词you:上下文就只有say这个单词。
那么单词you用向量可以表示为: [0,1,0,0,0,0,0]
。
在比如单词say用向量可以表示为:[1,0,1,0,1,1,0]
结果汇总(图2-7)
上图的表格呈矩阵状,所以称之为共现矩阵co-occurence matrix
手动生成共现矩阵
1 | C = np.array([ |
array([[0, 1, 0, 0, 0, 0, 0],
[1, 0, 1, 0, 1, 1, 0],
[0, 1, 0, 1, 0, 0, 0],
[0, 0, 1, 0, 1, 0, 0],
[0, 1, 0, 1, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 1, 0]], dtype=int32)
1 | C[0] |
array([0, 1, 0, 0, 0, 0, 0], dtype=int32)
1 | C[4] |
array([0, 1, 0, 1, 0, 0, 0], dtype=int32)
1 | C[word_to_id["goodbye"]] |
array([0, 1, 0, 1, 0, 0, 0], dtype=int32)
自动生成共现矩阵
1 | def create_to_matrix(corpus, vocab_size,window_size=1): |
向量间的相似度
代码实现
常用来表示向量间相似度的方法:
- 向量内积
- 欧氏距离
- 余弦相似度(单词向量的相似度用)
下面是具体的计算过程:
1 | def cos_similarity(x, y): |
上面的代码有一个问题:全0向量被赋值给参数时,会出现"除数为0"的错误。解决办法:在执行除法时,加上一个微小值eps
1 | def cos_similarity(x, y, eps=1e-8): |
案例演示
求余弦相似度的案例:
1 | import numpy as np |
0.7071067691154799
余弦相似度的值在-1到1之间,这个值说明you和i之间的相似度挺高的;实际也是如此。
相似单词的降序排列
代码实现
和某个查询词相似的单词按照降序显示出来
1 | def most_similar(query, word_to_id, id_to_word,word_matrix, top=5): |
1 | # argsort的使用说明:排序的数组的元素的原索引值 |
array([1, 2, 0])
对k数组进行升序排列:[-20,40,100]
;-20
在原数组中的位置是1
,40
的索引是2
,100
的位置0
如果是降序排列:
1 | (-k).argsort() # 降序 [-100,20,-40] ----> [-100,-40, 20] 在原数组中的位置 [0,2,1] |
array([0, 2, 1])
案例演示
1 | import numpy as np |
you
goodbye: 0.7071067691154799
i: 0.7071067691154799
hello: 0.7071067691154799
say: 0.0
and: 0.0