同义词工具

引入

同义词工具在NLP一般在数据预处理, 或者数据增强时使用, 词用同义词代替, 可以增加可用于训练的语料, 也能增强模型的鲁棒性.

目前我找到的可用来做同义词替换的方法工具有以下几个.

同义词词林

哈工大的同义词词林(扩展版)是一个同义词词典, 以.txt文件的形式记录. 文件中数据的格式如下:

Aa01A01= 人 士 人物 人士 人氏 人选
Aa01A02= 人类 生人 全人类
Aa01A03= 人手 人员 人口 人丁 口 食指
Aa01A04= 劳力 劳动力 工作者
Aa01A05= 匹夫 个人
Aa01A06= 家伙 东西 货色 厮 崽子 兔崽子 狗崽子 小子 杂种 畜生 混蛋 王八蛋 竖子 鼠辈 小崽子
Aa01A07= 者 手 匠 客 主 子 家 夫 翁 汉 员 分子 鬼 货 棍 徒
Aa01A08= 每人 各人 每位
Aa01A09= 该人 此人
Aa01B01= 人民 民 国民 公民 平民 黎民 庶 庶民 老百姓 苍生 生灵 生人 布衣 白丁 赤子 氓 群氓 黔首 黎民百姓 庶人 百姓 全民 全员 萌

每行代表一组同义词, 两两之间做同义词, 可以相互替换. 但除了同义词, 还包含在句子中作用近似, 但直观来看词义不同的词:

Ad02B03# 西人 意大利人 缅甸人 西方人 阿拉伯人 日本人 美国人 犹太人 捷克人 芬兰人 德国人 比利时人 ...
Ae02A21# 机工 铣工 刨工 锻工 铸工 钳工 电工 焊工 装配工 保全工 电焊工 ...

上面一组其实都是代表外国人的词汇, 只是国家的区别, 在句子中都扮演着同样的角色, 在很多情况下都是可以作为同义词替换的(除了一些推导或信息抽取的任务吧).

可以看到每行的开始都有一串编码, 编码的意义参考同义替换:哈工大同义词词林扩展版. 这里关注编码的最后一个字符. 观察上面两大组可以看到他们的编码结尾分别是=#, 这分别代表着相等同类的意思, 在整理同义词典时, 选择使用. 编码的详情意义参考上面的链接.

整个文件共包含17817组同义词汇, 每组包含的词的数量不同, 也会出现同一个词汇被包含在不同组中, 显然是一词多义的原因. 在使用处理时, 需要注意这一点.

如何使用, 这里有使用的例子, 其中包含代码, 可以参考:

其中使用到了哈工大的pyplt, 是一款提供了分词, 词性标注, NER等功能的工具, 官方文档为: 使用 pyltp

Synonyms

Synonyms是一个专门做中文近义词的Python工具包. 与词林使用字典记录固定的近似词不同, Synonyms在得到某个词的相似时, 是通过word2vec中的词向量计算得到的, 利用了上下文中词之间的关系, 根据词向量的距离得到的.

这种方法有以下缺点:

  • 得到的词有可能不是词义相近的严格意义的近义词, 而是经常以成对出现在上下文窗口中的单词, 统计上有着密切的关系. 例如:

      synonyms.nearby("人脸")

    得到的结果为:

      (['人脸', '图片', '通过观察', '几何图形', '图象', '放大镜', '面孔', '貌似', '奇特', '十分相似'],
      [1.0,
      0.5972838,
      0.56848586,
      0.5318347,
      0.52534395,
      0.52400935,
      0.52310055,
      0.50064117,
      0.4851142,
      0.39761642])

    可以看到这里得到的词汇都不是近义词, 而是经常在同一个上下文窗口中成对出现的组合.

所幸, 由于synonyms计算近义词是通过词向量的距离得到的, 而且求近义词的方法nearby也返回了结果中每个单词的相似度衡量. 我们可以简单地通过阈值, 做进一步的筛选. 例如上式中最大的近义词图片对应的相似度为0.597, 可以认为太低, 从而人脸没有近义词.

synonyms.nearby("问题")
(['问题', '难题', '原因', '疑虑', '情况', '缺陷', '疑问', '关键问题', '解决办法', '弊端'],
 [1.0,
  0.74893767,
  0.688038,
  0.6788217,
  0.6591137,
  0.65887266,
  0.6470331,
  0.63049304,
  0.62929237,
  0.62681234])

问题的近义词列表返回的结果, 相似度就高出不少.

总之, 在使用时, 如果想要比较高质量的近义词, 阈值设置高一点. 低阈值会引入更多的近义词词汇, 用来做数据增强时, 可能会提高模型的鲁棒性, 但也可能引入过多的噪声, 造成模型无法收敛或质量较差.

总结就是, synonyms包使用synonyms.nearby(WORD)方法获取近义词, 返回的是一个二元list, 形式为[[nearby_words], [nearby_words_score]], 每个list的长度都为10. nearby_words是近义词列表, nearby_words_score是对应的每个近义词的相似度, 越高越好.

因为是使用word2vec, 所以本身是有一个字典的, 输入只能是字典中的单词, 才能转换为词向量, 进而才能得到与其他单词的距离, 产生近义词列表. 如果输入的单词是OOV, 则没有近义词列表, 返回([], []).

项目地址为: huyingxi/Synonyms.

另外需要注意的是, 由于使用的是word2vec, 所以一些开源的训练好的word2vec文件也是可以使用的. 更换模型的方法参考项目主页. 推荐使用腾讯AI Lab的word2vec embedding.

详细的使用方法参考项目的主页说明, 也可以参考Synonyms: 中文近义词工具包.

最后更新于