机器之心整理

参与:蒋思源

近日,HaiLiangWang和胡小夕在GitHub开放了一个中文近义词工具包Synonyms,它可用于如文本对齐、推荐算法、相似度计算、语义偏移、关键字提取、概念提取、自动摘要、搜索引擎等很多NLP任务。该工具包目前能搜索近义词和比较语句相似度等任务,且词汇量达到了125,792。机器之心也尝试使用Synonyms搜索一段中文的近义词,并有非常不错的反馈。

项目地址:

该中文近义词工具包采用的基本技术是Word2vec,因此在介绍该工具的同时我们会简要介绍词嵌入方法。此外,Synonyms的安装十分便捷,我们可以直接使用命令pipinstall-Usynonyms完成。该工具包兼容Python2和Python3,且目前的稳定版为v2.0,以下是使用Synonyms工具的效果:

提取近义词_子模提取软件提取图片_愉快的近义词有趣的近义词依然的近义词

如果我们想把单词输入机器学习模型,除非使用基于树的方法,否则需要把单词转换成一些数值向量。一种直接的方法是使用「one-hotencoding」方法将单词转换为稀疏表示,如下所示向量中只有一个元素设置为1,其余为0。

提取近义词_子模提取软件提取图片_愉快的近义词有趣的近义词依然的近义词

这种方法的缺点在于一个词的向量长度等于词汇表的大小,且非常稀疏。不仅如此,这种方法剥离了单词的所有局部语境,我们不能通过向量表示这个词的概念。因此,我们需要使用更高效的方法表示文本数据,而这种方法可以保存单词的上下文的信息。这是Word2Vec方法的初衷。

一般来说,Word2Vec方法由两部分组成。首先是将高维one-hot形式表示的单词映射成低维向量。例如将10,000列的矩阵转换为300列的矩阵,这一过程被称为词嵌入。第二个目标是在保留单词上下文的同时,从一定程度上保留其意义。Word2Vec实现这两个目标的方法有skip-gram和CBOW等,skip-gram会输入一个词,然后尝试估计其它词出现在该词附近的概率。还有一种与此相反的被称为连续词袋模型(ContinuousBagOfWords,CBOW),它将一些上下文词语作为输入,并通过评估概率找出最适合(概率最大)该上下文的词。

对于连续词袋模型而言,Mikolov等人运用目标词前面和后面的n个词来同时预测这个词。他们称这个模型为连续的词袋(CBOW),因为它用连续空间来表示词,而且这些词的先后顺序并不重要。

提取近义词_愉快的近义词有趣的近义词依然的近义词_子模提取软件提取图片

连续的词袋(Mikolov等人,2013年)

CBOW可以看作一个具有先知的语言模型,而skip-gram模型则完全改变将语言模型的目标:它不像CBOW一样从周围的词预测中间的词;恰恰相反,它用中心语去预测周围的词:

愉快的近义词有趣的近义词依然的近义词_提取近义词_子模提取软件提取图片

Skip-gram(Mikolov等人提取近义词,2013)

在加载Synonyms中,我们可以看到会打印出「loaded(125796,100)matrixfrom…」,因此Synonyms采用的词向量维度为100。

用法

输出近义词向量:

  1. import synonyms

  2. print("人脸: %s" % (synonyms.nearby("人脸")))

  3. print("识别: %s" % (synonyms.nearby("识别")))

  4. print("NOT_EXIST: %s" % (synonyms.nearby("NOT_EXIST")))

synonyms.nearby(WORD)会返回一个包含两项的列表:

[[nearby_words],[nearby_words_score]],nearby_words是WORD的近义词向量,也以列表的方式存储,并且按照距离的长度由近及远排列,nearby_words_score是nearby_words中对应词的距离分数,分数在(0-1)区间内,越接近于1,代表越相近。比如:

  1. synonyms.nearby(人脸) = [

  2.    ["图片", "图像", "通过观察", "数字图像", "几何图形", "脸部", "图象", "放大镜", "面孔", "Mii"],

  3.    [0.597284, 0.580373, 0.568486, 0.535674, 0.531835, 0.530

  4. 095, 0.525344, 0.524009, 0.523101, 0.516046]]

在出现集外词的情况下,返回[[],[]],目前的字典大小:125,792。

机器之心尝试将一整段关于Word2vec的中文分割为一个个单词,再使用Synonyms工具对分词的结果取近义词,以下是试验结果:

  1. Word2Vec : [[], []]

  2. 方法 : [['方式', '手段', '新方法', '原理', '工具', '步骤', '算法', '分析方法', '演算法', '方法有'], [0.770168, 0.698663, 0.696657, 0.693642, 0.690686, 0.687199, 0.675024, 0.673502, 0.657432, 0.656965]]

  3. : [[], []]

  4. : [[], []]

  5. 部分 : [['部份', '大部分', '一小', '其余部分', '外', '大多', '之外', '大部份', '以外', '均'], [0.819274, 0.77532, 0.696557, 0.630384, 0.625031, 0.617763, 0.609703, 0.600958, 0.599957, 0.592684]]

  6. 组成 : [['构成', '分成', '组合成', '组合而成', '都由', '组建', '分为', '都是由', '成员', '合组'], [0.672614, 0.633627, 0.622906, 0.601468, 0.579645, 0.576105, 0.56926, 0.558928, 0.555657, 0.55275]]

  7. : [[], []]

  8. 首先 : [[], []]

  9. : [[], []]

  10. : [[], []]

  11. 高维 : [['萧士达', '浦罗哥', '希尔伯特', '庞加莱', '欧拉', '几何', '群论', '图论', '高斯', '线性代数'], [0.585315, 0.570614, 0.52954, 0.507108, 0.503025, 0.501703, 0.49944, 0.496649, 0.495397, 0.488994]]

  12. 独热 : [[], []]

  13. 形式 : [['方式', '型式', '性质', '表现形式', '表达方式', '概念', '媒介', '内容', '规则', '简单'], [0.748891, 0.621915, 0.6181, 0.617813, 0.617308, 0.611825, 0.583548, 0.578797, 0.574129, 0.569158]]

  14. 表示 : [['回应', '指出', '透露', '表达', '声称', '对此', '暗示', '否认', '说明', '问到'], [0.733619, 0.718644, 0.700614, 0.69215, 0.669181, 0.663752, 0.65325, 0.648804, 0.64028, 0.632011]]

  15. : [[], []]

  16. 单词 : [['单字', '词语', '短语', '字词', '词根', '词组', '句子', '音节', '词汇', '前缀'], [0.819558, 0.793184, 0.779852, 0.775173, 0.771767, 0.767386, 0.747697, 0.733435, 0.722758, 0.715587]]

  17. 映射 : [['同构', '拓扑', '等价', '同态', '算子', '流形', '给定', '子集', '函数', '向量'], [0.751925, 0.737796, 0.736626, 0.723419, 0.72286, 0.717205, 0.70084, 0.699233, 0.698332, 0.682505]]

  18. : [['出', '变成', '成为', '演变成', '变为', '起来', '转成', '形成', '已成', '转变成'], [0.626685, 0.597042, 0.578111, 0.554632, 0.55223, 0.538277, 0.498342, 0.482658, 0.480671, 0.479747]]

  19. : [['较低', '较高', '高', '更高', '极低', '很低', '低于', '高于', '偏高', '较差'], [0.880493, 0.829336, 0.814844, 0.751234, 0.744953, 0.73976, 0.715566, 0.715089, 0.709287, 0.686807]]

  20. 维向量 : [[], []]

  21. : [[], []]

  22. 例如 : [[], []]

  23. : [[], []]

  24.  : [[], []]

  25. 10 : [[], []]

  26. : [[], []]

  27. 000 : [[], []]

  28. : [[], []]

  29. : [[], []]

  30. 矩阵 : [['行列式', '乘积', '向量', '乘法', '算子', '特征值', '线性', '函数', 'formula_', '实数'], [0.78328, 0.743294, 0.7416, 0.735933, 0.705292, 0.697315, 0.697315, 0.690086, 0.689624, 0.683013]]

  31. 转换 : [['切换', '变换', '转换成', '叠加', '匹配', '类比', '传输', '交换', '操作', '简化'], [0.733128, 0.718899, 0.715552, 0.628927, 0.621122, 0.612286, 0.611997, 0.609811, 0.604056, 0.603366]]

  32. : [[], []]

  33.  : [[], []]

  34. 300 : [[], []]

  35. : [[], []]

  36. : [[], []]

  37. 矩阵 : [['行列式', '乘积', '向量', '乘法', '算子', '特征值', '线性', '函数', 'formula_', '实数'], [0.78328, 0.743294, 0.7416, 0.735933, 0.705292, 0.697315, 0.697315, 0.690086, 0.689624, 0.683013]]

  38. : [[], []]

  39. 这个 : [[], []]

  40. 过程 : [['步骤', '流程', '处理过程', '操作过程', '现实生活', '程序', '机制', '方法', '方式', '每一次'], [0.654057, 0.627095, 0.612206, 0.588535, 0.587763, 0.584512, 0.570078, 0.56342, 0.556587, 0.555285]]

  41. : [[], []]

  42. 称为 : [['称作', '称之为', '被称作', '称做', '专指', '统称', '叫作', '叫做', '称呼', '特指'], [0.931905, 0.888719, 0.883803, 0.833798, 0.741266, 0.73327, 0.725112, 0.720903, 0.714699, 0.695307]]

  43. : [['词语', '该词', '名词', '用法', '词汇', '用语', '含义', '辞汇', '字词', '术语'], [0.865391, 0.833362, 0.817649, 0.810989, 0.79878, 0.752893, 0.741603, 0.730943, 0.727771, 0.725913]]

  44. 嵌入 : [['映射', '内嵌', '填充', '封装', '插入', '存储', '链接', '浸入', '粘贴', '构造'], [0.640392, 0.630447, 0.618274, 0.60825, 0.604815, 0.59937, 0.566457, 0.55673, 0.554925, 0.554157]]

  45. : [[], []]

  46. 第二 : [[], []]

  47. : [[], []]

  48. 目标 : [['目的', '最终目标', '能够', '尽可能', '战略目标', '策略', '能力', '远距离', '任务', '必须'], [0.743574, 0.66224, 0.652209, 0.625992, 0.595744, 0.595451, 0.586327, 0.585261, 0.582277, 0.579012]]

  49. : [[], []]

  50. : [[], []]

  51. 保留 : [['保有', '保存', '留存', '沿用', '原有', '延续', '存留', '更改', '恢复', '维持'], [0.741621, 0.70751, 0.695012, 0.667181, 0.644165, 0.609553, 0.57785, 0.558837, 0.55696, 0.554073]]

  52. 单词 : [['单字', '词语', '短语', '字词', '词根', '词组', '句子', '音节', '词汇', '前缀'], [0.819558, 0.793184, 0.779852, 0.775173, 0.771767, 0.767386, 0.747697, 0.733435, 0.722758, 0.715587]]

  53. 上下文 : [['语义', '语句', '字符串', 'codice_', '句子', '正则表达式', '变量', '表达式', '子句', '自然语言'], [0.777081, 0.745407, 0.737112, 0.710487, 0.706909, 0.700924, 0.693529, 0.688357, 0.682883, 0.678303]]

  54. : [[], []]

  55. 同时 : [[], []]

  56. : [[], []]

  57. : [[], []]

  58. 一定 : [[], []]

  59. 程度 : [['水平', '因素', '高度', '素质', '层面', '能力', '状况', '相对', '情况', '原因'], [0.643124, 0.635219, 0.627448, 0.624889, 0.619942, 0.602435, 0.599929, 0.598476, 0.596007, 0.594679]]

  60. : [[], []]

  61. 保留 : [['保有', '保存', '留存', '沿用', '原有', '延续', '存留', '更改', '恢复', '维持'], [0.741621, 0.70751, 0.695012, 0.667181, 0.644165, 0.609553, 0.57785, 0.558837, 0.55696, 0.554073]]

  62. : [[], []]

  63. 意义 : [['涵义', '含义', '意涵', '内涵', '象征意义', '本质', '含意', '意味', '概念', '性质'], [0.784661, 0.767263, 0.758177, 0.749875, 0.734564, 0.730683, 0.671735, 0.670497, 0.666011, 0.658259]]

  64. : [[], []]

两个句子的相似度比较:

  1.   sen1 = "发生历史性变革"

  2.   sen2 = "发生历史性变革"

  3.   r = synonyms.compare(sen1, sen2, seg=True)

其中提取近义词,参数seg表示synonyms.compare是否对sen1和sen2进行分词,默认为True。返回值:[0-1],并且越接近于1代表两个句子越相似。

  1. 旗帜引领方向 vs 道路决定命运: 0.429

  2. 旗帜引领方向 vs 旗帜指引道路: 0.93

  3. 发生历史性变革 vs 发生历史性变革: 1.0


句子相似度准确率

在SentenceSim上进行测试:

SentenceSim地址:

  1. 测试语料条数为:7516条.

  2. 设定阈值 0.5

  3.  相似度 > 0.5, 返回相似;

  4.  相似度 < 0.5, 返回不相似.


评测结果:

  1. 正确 : 6626,错误 : 890,准确度 : 88.15%


关于距离计算和阀值选取,参考Synonyms/issues/6。

以友好的方式打印近义词,方便调试,display调用了synonyms#nearby方法:

  1. >>> synonyms.display("飞机")

  2. '飞机'近义词:

  3.  1. 架飞机:0.837399

  4.  2. 客机:0.764609

  5.  3. 直升机:0.762116

  6.  4. 民航机:0.750519

  7.  5. 航机:0.750116

  8.  6. 起飞:0.735736

  9.  7. 战机:0.734975

  10.  8. 飞行中:0.732649

  11.  9. 航空器:0.723945

  12.  10. 运输机:0.720578


最后,Synonyms项目的作者胡小夕是北京邮电大学研究生,目前实习于今日头条AILAB。从事自然语言处理方向研究,在智能客服,知识图谱等领域都有相关研究开发经验。研发模型在文体分类权威数据集TREC上达到目前最优精度,申请深度学习与自然语言处理结合的国家发明专利5项。

提取近义词_愉快的近义词有趣的近义词依然的近义词_子模提取软件提取图片

@online{Synonyms:hain2017,  author = {Hai Liang Wang, Hu Ying Xi},  title = {中文近义词工具包Synonyms},  year = 2017,  url = {https://github.com/huyingxi/Synonyms},  urldate = {2017-09-27} }