当前位置:   article > 正文

Python实现同义词替换(哈工大pyltp分词)_python 同义词替换

python 同义词替换

问答系统慢慢的成为非常流行且非常实用的应用,成为越来越多的研究者的研究方向。当前问答系统有基于知识库的问答系统,对话系统以及聊天机器人。

在问答系统中,当用户想要利用问答系统搜索到与自己提出 query相同或相似的问题及其答案时,由于用户输入 query都是自己描述的,比较口语化,且有错别字,歧义等,其结构复杂和句式冗长,使得从问句中提取重要关键词项会比较困难(提出的关键词质量不高,词不达意的现象)。因无法准确获取问句中的核心关键词,导致搜索的结果不够准确,故需要对其输入的 query中的关键词进行同义词扩展。

当用户在使用问答系统搜索时,为了能够将与用户所输入 query 的关键词进行同义词相匹配,使其能够得到较好的搜索结果,采用基于同义词的搜索请求 (query) 扩展,即在利用 query 进行搜索的同时也利用 query 的同义词进行搜索,提高搜索结果召回的质量。

以上说明同义词替换在检索系统中的基础性和必要性。

最近有接触到基于知识库的问答系统的项目,需要对关键词进行同义词扩展,提高搜索效率。

同义词的扩展,这里不详述展开。

程序中设计到分词技术和同义词表,分词采用了哈工大的pyltp,其官方文档链接为http://pyltp.readthedocs.io/zh_CN/latest/。同义词表是利用哈工大的同义词词林(扩展版)进行预处理保留每个词的前两项得来的,原版下载链接为https://www.ltp-cloud.com/download/(但好像网页不存在了)。

同义词替换代码如下:

这里用的是哈工大的pyltp分词包,加载了自定义词典。发现一处免费下载的地址:LTP模型

哈工大pyltp分词:

  1. # -*- coding: utf-8 -*-
  2. import os
  3. LTP_DATA_DIR = 'ltp_data_v3.4.0' # ltp模型目录的路径
  4. cws_model_path = os.path.join(LTP_DATA_DIR, 'cws.model') # 分词模型路径,模型名称为`cws.model`
  5. from pyltp import Segmentor
  6. segmentor = Segmentor() # 初始化实例
  7. segmentor.load(cws_model_path) # 加载模型
  8. words = segmentor.segment('元芳你怎么看') # 分词
  9. print ('\t'.join(words))
  10. segmentor.release() # 释放模型

结果:

  1. 元芳 你 怎么 看
  2. Process finished with exit code 0

同义词替换程序: 

  1. # -*- coding: utf-8 -*-
  2. #加载自定义词典
  3. from pyltp import Segmentor
  4. class SynonymsReplacer:
  5. def __init__(self, synonyms_file_path, cws_model_path,userdict_file_path):
  6. self.synonyms = self.load_synonyms(synonyms_file_path)
  7. self.segmentor = self.load_segmentor(cws_model_path,userdict_file_path)
  8. def __del__(self):
  9. """对象销毁时要释放pyltp分词模型"""
  10. self.segmentor.release()
  11. def load_segmentor(self, cws_model_path,userdict_file_path):
  12. """
  13. 加载ltp分词模型
  14. :param cws_model_path: 分词模型路径
  15. :return: 分词器对象
  16. """
  17. segmentor = Segmentor()
  18. segmentor.load_with_lexicon(cws_model_path,userdict_file_path)
  19. return segmentor
  20. def segment(self, sentence):
  21. """调用pyltp的分词方法将str类型的句子分词并以list形式返回"""
  22. return list(self.segmentor.segment(sentence))
  23. def load_synonyms(self, file_path):
  24. """
  25. 加载同义词表
  26. :param file_path: 同义词表路径
  27. :return: 同义词列表[[xx,xx],[xx,xx]...]
  28. """
  29. synonyms = []
  30. with open(file_path, 'r', encoding='utf-8') as file:
  31. for line in file:
  32. synonyms.append(line.strip().split(' '))
  33. return synonyms
  34. def permutation(self, data):
  35. """
  36. 排列函数
  37. :param data: 需要进行排列的数据,列表形式
  38. :return:
  39. """
  40. assert len(data) >= 1, "Length of data must greater than 0."
  41. if len(data) == 1: # 当data中只剩(有)一个词及其同义词的列表时,程序返回
  42. return data[0]
  43. else:
  44. head = data[0]
  45. tail = data[1:] # 不断切分到只剩一个词的同义词列表
  46. tail = self.permutation(tail)
  47. permt = []
  48. for h in head: # 构建两个词列表的同义词组合
  49. for t in tail:
  50. if isinstance(t, str): # 传入的整个data的最后一个元素是一个一维列表,其中每个元素为str
  51. permt.extend([[h] + [t]])
  52. elif isinstance(t, list):
  53. permt.extend([[h] + t])
  54. return permt
  55. def get_syno_sents_list(self, input_sentence):
  56. """
  57. 产生同义句,并返回同义句列表,返回的同义句列表没有包含该句本身
  58. :param input_sentence: 需要制造同义句的原始句子
  59. :return:
  60. """
  61. assert len(input_sentence) > 0, "Length of sentence must greater than 0."
  62. seged_sentence = self.segment(input_sentence)
  63. candidate_synonym_list = [] # 每个元素为句子中每个词及其同义词构成的列表
  64. for word in seged_sentence:
  65. word_synonyms = [word] # 初始化一个词的同义词列表
  66. for syn in self.synonyms: # 遍历同义词表,syn为其中的一条
  67. if word in syn: # 如果句子中的词在同义词表某一条目中,将该条目中它的同义词添加到该词的同义词列表中
  68. syn.remove(word)
  69. word_synonyms.extend(syn)
  70. candidate_synonym_list.append(word_synonyms) # 添加一个词语的同义词列表
  71. perm_sent = self.permutation(candidate_synonym_list) # 将候选同义词列表们排列组合产生同义句
  72. syno_sent_list = [seged_sentence]
  73. for p in perm_sent:
  74. if p != seged_sentence:
  75. syno_sent_list.append(p)
  76. return syno_sent_list
  77. if __name__ == '__main__':
  78. replacer = SynonymsReplacer(synonyms_file_path='tongyici.txt', cws_model_path='ltp_data_v3.4.0/cws.model',userdict_file_path = 'userdict.txt')
  79. test_sentence = '欠债不还犯法吗'
  80. _syn = replacer.get_syno_sents_list(test_sentence)
  81. for s in _syn:
  82. print(s)

测试例子的替换结果:

           

参考:https://blog.csdn.net/hfutdog/article/details/81107170

ltp工具包下载:https://download.csdn.net/download/weixin_40547993/11141737

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/292009
推荐阅读
相关标签
  

闽ICP备14008679号