当前位置:   article > 正文

自然语言处理知识抽取(pkuseg、DDParser安装及使用)

pkuseg

一、分词简介

1.基本概念

分词是自然语言处理中的一个重要步骤,它可以帮助我们将文本分成一个个词语,以便更好地理解和分析文本。在计算机视觉、语音识别、机器翻译等领域,分词都扮演着重要的角色。

目前,常用的分词库包括 jieba、pyjieba、wordcloud、pkuseg(本次使用)等。这些库提供了丰富的功能,例如可以对文本进行分词、词性标注、命名实体识别等,可以方便地集成到其他自然语言处理任务中。

2.pkuseg介绍

pkuseg 是一个基于 Python 的自然语言处理库,主要用于情感分析、文本分类、命名实体识别等任务。该库由日本庆应大学开发,并于 2018 年公开发布。

pkuseg 库采用了深度学习技术,使用了预训练的神经网络模型,可以自动从大量的文本数据中学习到正确的分词模式和特征。因此,相对于传统的分词库,pkuseg 库的分词精度更高,并且可以处理更长的文本。

pkuseg 库提供了多种情感分析算法,包括基于规则、基于机器学习和基于深度学习的方法。同时,该库还支持文本分类和命名实体识别等任务,可以使用单分类、多分类、支持向量机、朴素贝叶斯等算法进行训练和预测。

pkuseg 库的优点是速度快、精度高,并且可以处理多种语言。此外,该库还提供了易于使用的 API,使用户可以更加方便地集成到自己的项目中。

二、依赖安装

1、pkuseg安装

在安装之前如果pip版本过低可能也会照成安装错误,所以在安装前可以更新一下pip:

 python.exe -m pip install --upgrade pip

python.exe为你的解释器路径

注意

安装pkuseg库需要使用python3.8。

第一次运行 会下载相关模型文件。若下载失败可到提示的github网址自行下载,或使用外网运行。

 2、ddparser安装

本次安装的依赖有:

LAC==2.1.2 是一个用于自然语言处理的库,提供了多种自然语言处理任务的解决方案,例如文本分类、情感分析、命名实体识别等。该库使用深度学习技术,支持使用预训练模型和自定义模型,支持多种自然语言处理任务,并且提供了易于使用的 API。

paddlepaddle==2.4.0 是一个基于 Python 的自然语言处理库,提供了丰富的自然语言处理算法和模型,包括文本分类、情感分析、命名实体识别、机器翻译等。该库采用了深度学习技术,支持使用预训练模型和自定义模型,并提供了易于使用的 API 和工具。

protobuf==3.20.0 是一个用于数据结构和二进制数据的交换格式的库,通常用于ddparser==1.0.8 是一个用于解析 XML 和 HTML 数据的库,通常用于数据可视化和 Web 应用程序。该库提供了多种解析算法和数据结构,例如 DOM、SAX、HTML parser 等,并且支持多种编程语言。

在安装相关依赖我们一般是选择从源镜像下载 这次我们选择的源为清华镜像相关指令为:

pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

安装LAC:

pip install --upgrade LAC==2.1.2

安装paddlepaddle:

pip install --upgrade paddlepaddle==2.4.0

安装protobuf:

pip install --upgrade protobuf==3.20.0

安装ddparser:

pip install --upgrade ddparser==1.0.8

三、代码运行

1、pkuseg基本使用

运行分词

词性标注

细领域分词

 2、ddparser基本使用(代码为学校课程案例)

  1. # encoding:utf-8
  2. # 基于百度ddparser实现文本关系抽取
  3. import os, re
  4. from ddparser import DDParser
  5. class SVOParser:
  6. def __init__(self):
  7. self.parser = DDParser(use_pos=True)
  8. print('loaded model')
  9. '''文章分句处理, 切分长句,冒号,分号,感叹号等做切分标识'''
  10. def split_sents(self, content):
  11. return [sentence for sentence in re.split(r'[??!!。;;::\n\r]', content) if sentence]
  12. '''句法分析---为句子中的每个词语维护一个保存句法依存儿子节点的字典'''
  13. def build_parse_child_dict(self, words, postags, rel_id, relation):
  14. child_dict_list = []
  15. format_parse_list = []
  16. for index in range(len(words)):
  17. child_dict = dict()
  18. for arc_index in range(len(rel_id)):
  19. if rel_id[arc_index] == index+1: #arcs的索引从1开始
  20. if rel_id[arc_index] in child_dict:
  21. child_dict[relation[arc_index]].append(arc_index)
  22. else:
  23. child_dict[relation[arc_index]] = []
  24. child_dict[relation[arc_index]].append(arc_index)
  25. child_dict_list.append(child_dict)
  26. heads = ['Root' if id == 0 else words[id - 1] for id in rel_id] # 匹配依存父节点词语
  27. for i in range(len(words)):
  28. # ['ATT', '李克强', 0, 'nh', '总理', 1, 'n']
  29. a = [relation[i], words[i], i, postags[i], heads[i], rel_id[i]-1, postags[rel_id[i]-1]]
  30. format_parse_list.append(a)
  31. return child_dict_list, format_parse_list
  32. '''parser主函数'''
  33. def parser_main(self, sentence):
  34. res = self.parser.parse(sentence, )[0]
  35. words = res["word"]
  36. postags = res["postag"]
  37. rel_id = res["head"]
  38. relation = res["deprel"]
  39. child_dict_list, format_parse_list = self.build_parse_child_dict(words, postags, rel_id, relation)
  40. return words, postags, child_dict_list, format_parse_list
  41. """将所有的ATT进行合并"""
  42. def merge_ATT(self, words, postags, format_parse_list):
  43. words_ = words
  44. retain_nodes = set()
  45. ATTs = []
  46. ATT = []
  47. format_parse_list_ = []
  48. for parse in format_parse_list:
  49. dep = parse[0]
  50. if dep in ['ATT', 'ADV']:
  51. ATT += [parse[2], parse[5]]
  52. else:
  53. if ATT:
  54. body = ''.join([words[i] for i in sorted(set(ATT))])
  55. ATTs.append(body)
  56. retain_nodes.add(sorted(set(ATT))[-1])
  57. words_[sorted(set(ATT))[-1]] = body
  58. else:
  59. retain_nodes.add(parse[2])
  60. ATT = []
  61. for indx, parse in enumerate(format_parse_list):
  62. if indx in retain_nodes:
  63. parse_ = [parse[0], words_[indx], indx, postags[indx], words_[parse[5]], parse[5], postags[parse[5]]]
  64. format_parse_list_.append(parse_)
  65. return words_, postags, format_parse_list_, retain_nodes
  66. """基于该结果,提取三元组"""
  67. def extract(self, words, postags, child_dict_list, arcs, retain_nodes):
  68. svos = []
  69. for index in range(len(postags)):
  70. if index not in retain_nodes:
  71. continue
  72. tmp = 1
  73. # 如果语义角色标记为空,则使用依存句法进行抽取
  74. if postags[index]:
  75. # 抽取以谓词为中心的事实三元组
  76. child_dict = child_dict_list[index]
  77. # 主谓宾
  78. if 'SBV' in child_dict and 'VOB' in child_dict:
  79. # e1s = self.expand_e(words, postags, child_dict_list, child_dict['SBV'][0])
  80. # e2s = self.expand_e(words, postags, child_dict_list, child_dict['VOB'][0])
  81. r = words[index]
  82. e1 = words[child_dict['SBV'][0]]
  83. e2 = words[child_dict['VOB'][0]]
  84. if e1.replace(' ', '') and e2.replace(' ', ''):
  85. svos.append([e1, r, e2])
  86. # 含有介宾关系的主谓动补关系
  87. if 'SBV' in child_dict and 'CMP' in child_dict:
  88. e1 = words[child_dict['SBV'][0]]
  89. cmp_index = child_dict['CMP'][0]
  90. r = words[index] + words[cmp_index]
  91. if 'POB' in child_dict_list[cmp_index]:
  92. e2 = words[child_dict_list[cmp_index]['POB'][0]]
  93. if e1.replace(' ', '') and e2.replace(' ', ''):
  94. svos.append([e1, r, e2])
  95. return svos
  96. '''三元组抽取主函数'''
  97. def ruler2(self, words, postags, child_dict_list, arcs):
  98. svos = []
  99. for index in range(len(postags)):
  100. tmp = 1
  101. # 先借助语义角色标注的结果,进行三元组抽取
  102. if tmp == 1:
  103. # 如果语义角色标记为空,则使用依存句法进行抽取
  104. # if postags[index] == 'v':
  105. if postags[index]:
  106. # 抽取以谓词为中心的事实三元组
  107. child_dict = child_dict_list[index]
  108. # 主谓宾
  109. if 'SBV' in child_dict and 'VOB' in child_dict:
  110. r = words[index]
  111. e1 = self.complete_e(words, postags, child_dict_list, child_dict['SBV'][0])
  112. e2 = self.complete_e(words, postags, child_dict_list, child_dict['VOB'][0])
  113. if e1.replace(' ', '') and e2.replace(' ', ''):
  114. svos.append([e1, r, e2])
  115. # 定语后置,动宾关系
  116. relation = arcs[index][0]
  117. head = arcs[index][2]
  118. if relation == 'ATT':
  119. if 'VOB' in child_dict:
  120. e1 = self.complete_e(words, postags, child_dict_list, head - 1)
  121. r = words[index]
  122. e2 = self.complete_e(words, postags, child_dict_list, child_dict['VOB'][0])
  123. temp_string = r + e2
  124. if temp_string == e1[:len(temp_string)]:
  125. e1 = e1[len(temp_string):]
  126. if temp_string not in e1:
  127. if e1.replace(' ', '') and e2.replace(' ', ''):
  128. svos.append([e1, r, e2])
  129. # 含有介宾关系的主谓动补关系
  130. if 'SBV' in child_dict and 'CMP' in child_dict:
  131. e1 = self.complete_e(words, postags, child_dict_list, child_dict['SBV'][0])
  132. cmp_index = child_dict['CMP'][0]
  133. r = words[index] + words[cmp_index]
  134. if 'POB' in child_dict_list[cmp_index]:
  135. e2 = self.complete_e(words, postags, child_dict_list, child_dict_list[cmp_index]['POB'][0])
  136. if e1.replace(' ', '') and e2.replace(' ', ''):
  137. svos.append([e1, r, e2])
  138. return svos
  139. '''对找出的主语或者宾语进行扩展'''
  140. def complete_e(self, words, postags, child_dict_list, word_index):
  141. child_dict = child_dict_list[word_index]
  142. prefix = ''
  143. if 'ATT' in child_dict:
  144. for i in range(len(child_dict['ATT'])):
  145. prefix += self.complete_e(words, postags, child_dict_list, child_dict['ATT'][i])
  146. postfix = ''
  147. if postags[word_index] == 'v':
  148. if 'VOB' in child_dict:
  149. postfix += self.complete_e(words, postags, child_dict_list, child_dict['VOB'][0])
  150. if 'SBV' in child_dict:
  151. prefix = self.complete_e(words, postags, child_dict_list, child_dict['SBV'][0]) + prefix
  152. return prefix + words[word_index] + postfix
  153. '''程序主控函数'''
  154. def triples_main(self, content):
  155. sentences = self.split_sents(content)
  156. svos = []
  157. for sentence in sentences:
  158. print(sentence)
  159. words, postags, child_dict_list, arcs = self.parser_main(sentence)
  160. svo = self.ruler2(words, postags, child_dict_list, arcs)
  161. svos += svo
  162. return svos
  163. '''测试'''
  164. def test():
  165. content1 = """环境很好,位置独立性很强,比较安静很切合店名,半闲居,偷得半日闲。点了比较经典的菜品,味道果然不错!烤乳鸽,超级赞赞赞,脆皮焦香,肉质细嫩,超好吃。艇仔粥料很足,香葱自己添加,很贴心。金钱肚味道不错,不过没有在广州吃的烂,牙口不好的慎点。凤爪很火候很好,推荐。最惊艳的是长寿菜,菜料十足,很新鲜,清淡又不乏味道,而且没有添加调料的味道,搭配的非常不错!"""
  166. content2 = """近日,一条男子高铁吃泡面被女乘客怒怼的视频引发热议。女子情绪激动,言辞激烈,大声斥责该乘客,称高铁上有规定不能吃泡面,质问其“有公德心吗”“没素质”。视频曝光后,该女子回应称,因自己的孩子对泡面过敏,曾跟这名男子沟通过,但对方执意不听,她才发泄不满,并称男子拍视频上传已侵犯了她的隐私权和名誉权,将采取法律手段。12306客服人员表示,高铁、动车上一般不卖泡面,但没有规定高铁、动车上不能吃泡面。
  167. 高铁属于密封性较强的空间,每名乘客都有维护高铁内秩序,不破坏该空间内空气质量的义务。这也是乘客作为公民应当具备的基本品质。但是,在高铁没有明确禁止食用泡面等食物的背景下,以影响自己或孩子为由阻挠他人食用某种食品并厉声斥责,恐怕也超出了权利边界。当人们在公共场所活动时,不宜过分干涉他人权利,这样才能构建和谐美好的公共秩序。
  168. 一般来说,个人的权利便是他人的义务,任何人不得随意侵犯他人权利,这是每个公民得以正常工作、生活的基本条件。如果权利可以被肆意侵犯而得不到救济,社会将无法运转,人们也没有幸福可言。如西谚所说,“你的权利止于我的鼻尖”,“你可以唱歌,但不能在午夜破坏我的美梦”。无论何种权利,其能够得以行使的前提是不影响他人正常生活,不违反公共利益和公序良俗。超越了这个边界,权利便不再为权利,也就不再受到保护。
  169. 在“男子高铁吃泡面被怒怼”事件中,初一看,吃泡面男子可能侵犯公共场所秩序,被怒怼乃咎由自取,其实不尽然。虽然高铁属于封闭空间,但与禁止食用刺激性食品的地铁不同,高铁运营方虽然不建议食用泡面等刺激性食品,但并未作出禁止性规定。由此可见,即使食用泡面、榴莲、麻辣烫等食物可能产生刺激性味道,让他人不适,但是否食用该食品,依然取决于个人喜好,他人无权随意干涉乃至横加斥责。这也是此事件披露后,很多网友并未一边倒地批评食用泡面的男子,反而认为女乘客不该高声喧哗。
  170. 现代社会,公民的义务一般分为法律义务和道德义务。如果某个行为被确定为法律义务,行为人必须遵守,一旦违反,无论是受害人抑或旁观群众,均有权制止、投诉、举报。违法者既会受到应有惩戒,也会受到道德谴责,积极制止者则属于应受鼓励的见义勇为。如果有人违反道德义务,则应受到道德和舆论谴责,并有可能被追究法律责任。如在公共场所随地吐痰、乱扔垃圾、脱掉鞋子、随意插队等。此时,如果行为人对他人的劝阻置之不理甚至行凶报复,无疑要受到严厉惩戒。
  171. 当然,随着社会的发展,某些道德义务可能上升为法律义务。如之前,很多人对公共场所吸烟不以为然,烟民可以旁若无人地吞云吐雾。现在,要是还有人不识时务地在公共场所吸烟,必然将成为众矢之的。
  172. 再回到“高铁吃泡面”事件,要是随着人们观念的更新,在高铁上不得吃泡面等可能产生刺激性气味的食物逐渐成为共识,或者上升到道德义务或法律义务。斥责、制止他人吃泡面将理直气壮,否则很难摆脱“矫情”,“将自我权利凌驾于他人权利之上”的嫌疑。
  173. 在相关部门并未禁止在高铁上吃泡面的背景下,吃不吃泡面系个人权利或者个人私德,是不违反公共利益的个人正常生活的一部分。如果认为他人吃泡面让自己不适,最好是请求他人配合并加以感谢,而非站在道德制高点强制干预。只有每个人行使权利时不逾越边界,与他人沟通时好好说话,不过分自我地将幸福和舒适凌驾于他人之上,人与人之间才更趋于平等,公共生活才更趋向美好有序。"""
  174. content3 = '''(原标题:央视独家采访:陕西榆林产妇坠楼事件在场人员还原事情经过)
  175. 央视新闻客户端11月24日消息,2017年8月31日晚,在陕西省榆林市第一医院绥德院区,产妇马茸茸在待产时,从医院五楼坠亡。事发后,医院方面表示,由于家属多次拒绝剖宫产,最终导致产妇难忍疼痛跳楼。但是产妇家属却声称,曾向医生多次提出剖宫产被拒绝。
  176. 事情经过究竟如何,曾引起舆论纷纷,而随着时间的推移,更多的反思也留给了我们,只有解决了这起事件中暴露出的一些问题,比如患者的医疗选择权,人们对剖宫产和顺产的认识问题等,这样的悲剧才不会再次发生。央视记者找到了等待产妇的家属,主治医生,病区主任,以及当时的两位助产师,一位实习医生,希望通过他们的讲述,更准确地还原事情经过。
  177. 产妇待产时坠亡,事件有何疑点。公安机关经过调查,排除他杀可能,初步认定马茸茸为跳楼自杀身亡。马茸茸为何会在医院待产期间跳楼身亡,这让所有人的目光都聚焦到了榆林第一医院,这家在当地人心目中数一数二的大医院。
  178. 就这起事件来说,如何保障患者和家属的知情权,如何让患者和医生能够多一份实质化的沟通?这就需要与之相关的法律法规更加的细化、人性化并且充满温度。用这种温度来消除孕妇对未知的恐惧,来保障医患双方的权益,迎接新生儿平安健康地来到这个世界。'''
  179. content4 = '李克强总理今天来我家了,我感到非常荣幸'
  180. content5 = ''' 以色列国防军20日对加沙地带实施轰炸,造成3名巴勒斯坦武装人员死亡。此外,巴勒斯坦人与以色列士兵当天在加沙地带与以交界地区发生冲突,一名巴勒斯坦人被打死。当天的冲突还造成210名巴勒斯坦人受伤。
  181. 当天,数千名巴勒斯坦人在加沙地带边境地区继续“回归大游行”抗议活动。部分示威者燃烧轮胎,并向以军投掷石块、燃烧瓶等,驻守边境的以军士兵向示威人群发射催泪瓦斯并开枪射击。'''
  182. extractor = SVOParser()
  183. svos = extractor.triples_main(content5)
  184. print('svos', svos)
  185. for svo in svos:
  186. print(svo)
  187. if __name__ == '__main__':
  188. print("loading model...")
  189. test()

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

闽ICP备14008679号