当前位置:   article > 正文

自然语言处理(NLP)之pyltp的介绍与使用(中文分词、词性标注、命名实体识别、依存句法分析、语义角色标注)

pyltp

pyltp的简介

  语言技术平台(LTP)经过哈工大社会计算与信息检索研究中心 11 年的持续研发和推广, 是国内外最具影响力的中文处理基础平台。它提供的功能包括中文分词、词性标注、命名实体识别、依存句法分析、语义角色标注等。

pyltp 是 LTP 的 Python 封装,同时支持Python2和Python3版本。Python3的安装方法为:

pip3 install pyltp
  • 官网下载网址:https://pypi.org/project/pyltp/0.1.7/
  • 官方使用说明文档:https://pyltp.readthedocs.io/zh_CN/develop/api.html

若pyltp安装失败,可以参考博文:pyltp安装教程及简单使用 - 大明王 - 博客园

        在使用该模块前,需要下载完整的模型文件,文件下载地址为:https://pan.baidu.com/share/link?shareid=1988562907&uk=2738088569#list/path=%2F 。pyltp 的所有输入的分析文本和输出的结果的编码均为 UTF-8。模型的数据文件如下:

        其中,cws.model用于分词模型,lexicon.txt为分词时添加的用户字典,ner.model为命名实体识别模型,parser.model为依存句法分析模型,pisrl.model为语义角色标注模型,pos为词性标注模型。

pyltp的使用

  pyltp的使用示例项目结构如下:

分句

  分句指的是将一段话或一片文章中的文字按句子分开,按句子形成独立的单元。示例的Python代码sentenct_split.py如下:

  1. from pyltp import SentenceSplitter
  2. # 分句
  3. doc = '据韩联社12月28日反映,美国防部发言人杰夫·莫莱尔27日表示,美国防部长盖茨将于2011年1月14日访问韩国。' \
  4. '盖茨原计划从明年1月9日至14日陆续访问中国和日本,目前,他决定在行程中增加对韩国的访问。莫莱尔表示,' \
  5. '盖茨在访韩期间将会晤韩国国防部长官金宽镇,就朝鲜近日的行动交换意见,同时商讨加强韩美两军同盟关系等问题,' \
  6. '拟定共同应对朝鲜挑衅和核计划的方案。'
  7. # 分句
  8. sents = SentenceSplitter.split(doc)
  9. for i, sent in enumerate(sents):
  10. print(i, sent)

运行结果:

  1. 0 据韩联社1228日反映,美国防部发言人杰夫·莫莱尔27日表示,美国防部长盖茨将于2011114日访问韩国。
  2. 1 盖茨原计划从明年19日至14日陆续访问中国和日本,目前,他决定在行程中增加对韩国的访问。
  3. 2 莫莱尔表示,盖茨在访韩期间将会晤韩国国防部长官金宽镇,就朝鲜近日的行动交换意见,同时商讨加强韩美两军同盟关系等问题,拟定共同应对朝鲜挑衅和核计划的方案。

分词

  分词指的是将一句话按词语分开,按词语形成独立的单元。示例的Python代码words_split.py如下:

  1. import os
  2. from pyltp import Segmentor
  3. cws_model_path = os.path.join(os.path.dirname(__file__), 'data/cws.model') # 分词模型路径,模型名称为`cws.model`
  4. lexicon_path = os.path.join(os.path.dirname(__file__), 'data/lexicon.txt') # 参数lexicon是自定义词典的文件路径
  5. segmentor = Segmentor()
  6. segmentor.load_with_lexicon(cws_model_path, lexicon_path)
  7. sent = '据韩联社12月28日反映,美国防部发言人杰夫·莫莱尔27日表示,美国防部长盖茨将于2011年1月14日访问韩国。'
  8. words = segmentor.segment(sent) # 分词
  9. print(type(words)) # type:是对象
  10. print('/'.join(words))
  11. segmentor.release()

运行结果:

  1. <class 'pyltp.VectorOfString'>
  2. 据/韩联社/12月/28日/反映/,/美/国防部/发言人/杰夫·莫莱尔/27日/表示/,/美/国防部长/盖茨/将/于/2011年/1月/14日/访问/韩国/。

词性标注

  词性标注指的是一句话分完词后,制定每个词语的词性。示例的Python代码postagger.py如下:

  1. import os
  2. from pyltp import Segmentor, Postagger
  3. # 分词
  4. cws_model_path = os.path.join(os.path.dirname(__file__), 'data/cws.model') # 分词模型路径,模型名称为`cws.model`
  5. lexicon_path = os.path.join(os.path.dirname(__file__), 'data/lexicon.txt') # 参数lexicon是自定义词典的文件路径
  6. segmentor = Segmentor()
  7. segmentor.load_with_lexicon(cws_model_path, lexicon_path)
  8. sent = '据韩联社12月28日反映,美国防部发言人杰夫·莫莱尔27日表示,美国防部长盖茨将于2011年1月14日访问韩国。'
  9. words = segmentor.segment(sent) # 分词
  10. print(words) # type: object
  11. # 词性标注
  12. pos_model_path = os.path.join(os.path.dirname(__file__), 'data/pos.model') # 词性标注模型路径,模型名称为`pos.model`
  13. postagger = Postagger() # 初始化实例
  14. postagger.load(pos_model_path) # 加载模型
  15. postags = postagger.postag(words) # 词性标注
  16. for word, postag in zip(words, postags):
  17. print(word, postag)
  18. # 释放模型
  19. segmentor.release()
  20. postagger.release()
  21. '''
  22. 词性标注结果说明
  23. https://ltp.readthedocs.io/zh_CN/latest/appendix.html#id3
  24. '''

运行结果:

  1. <pyltp.VectorOfString object at 0x000001B4139C9CF0>
  2. 据 p
  3. 韩联社 ni
  4. 12月 nt
  5. 28日 nt
  6. 反映 v
  7. , wp
  8. 美 j
  9. 国防部 n
  10. 发言人 n
  11. 杰夫·莫莱尔 nh
  12. 27日 nt
  13. 表示 v
  14. , wp
  15. 美 j
  16. 国防部长 n
  17. 盖茨 nh
  18. 将 d
  19. 于 p
  20. 2011年 nt
  21. 1月 nt
  22. 14日 nt
  23. 访问 v
  24. 韩国 ns
  25. 。 wp

词性标注结果可参考网址:https://ltp.readthedocs.io/zh_CN/latest/appendix.html 。

命名实体识别

  命名实体识别(NER)指的是识别出一句话或一段话或一片文章中的命名实体,比如人名,地名,组织机构名。示例的Python代码ner.py如下:

  1. import os
  2. from pyltp import Segmentor, Postagger
  3. from pyltp import NamedEntityRecognizer
  4. # 分词
  5. cws_model_path = os.path.join(os.path.dirname(__file__), 'data/cws.model') # 分词模型路径,模型名称为`cws.model`
  6. lexicon_path = os.path.join(os.path.dirname(__file__), 'data/lexicon.txt') # 参数lexicon是自定义词典的文件路径
  7. segmentor = Segmentor()
  8. segmentor.load_with_lexicon(cws_model_path, lexicon_path)
  9. sent = '据韩联社12月28日反映,美国防部发言人杰夫·莫莱尔27日表示,美国防部长盖茨将于2011年1月14日访问韩国。'
  10. words = segmentor.segment(sent) # 分词
  11. print(list(words))
  12. # 词性标注
  13. pos_model_path = os.path.join(os.path.dirname(__file__), 'data/pos.model') # 词性标注模型路径,模型名称为`pos.model`
  14. postagger = Postagger() # 初始化实例
  15. postagger.load(pos_model_path) # 加载模型
  16. postags = postagger.postag(words) # 词性标注
  17. print(list(postags))
  18. # 命名实体识别
  19. ner_model_path = os.path.join(os.path.dirname(__file__), 'data/ner.model') # 命名实体识别模型路径,模型名称为`pos.model`
  20. recognizer = NamedEntityRecognizer() # 初始化实例
  21. recognizer.load(ner_model_path) # 加载模型
  22. # netags = recognizer.recognize(words, postags) # 命名实体识别
  23. # print(type(netags)) # type: object
  24. # 提取识别结果中的人名,地名,组织机构名
  25. persons, places, orgs = set(), set(), set()
  26. netags = list(recognizer.recognize(words, postags)) # 命名实体识别
  27. print(netags)
  28. i = 0
  29. for tag, word in zip(netags, words):
  30. j = i
  31. # 人名
  32. if 'Nh' in tag:
  33. if str(tag).startswith('S'):
  34. persons.add(word)
  35. elif str(tag).startswith('B'):
  36. union_person = word
  37. while netags[j] != 'E-Nh':
  38. j += 1
  39. if j < len(words):
  40. union_person += words[j]
  41. persons.add(union_person)
  42. # 地名
  43. if 'Ns' in tag:
  44. if str(tag).startswith('S'):
  45. places.add(word)
  46. elif str(tag).startswith('B'):
  47. union_place = word
  48. while netags[j] != 'E-Ns':
  49. j += 1
  50. if j < len(words):
  51. union_place += words[j]
  52. places.add(union_place)
  53. # 机构名
  54. if 'Ni' in tag:
  55. if str(tag).startswith('S'):
  56. orgs.add(word)
  57. elif str(tag).startswith('B'):
  58. union_org = word
  59. while netags[j] != 'E-Ni':
  60. j += 1
  61. if j < len(words):
  62. union_org += words[j]
  63. orgs.add(union_org)
  64. i += 1
  65. print('人名:', ','.join(persons))
  66. print('地名:', ','.join(places))
  67. print('组织机构:', ','.join(orgs))
  68. # 释放模型
  69. segmentor.release()
  70. postagger.release()
  71. recognizer.release()

运行结果:

  1. ['据', '韩联社', '12月', '28日', '反映', ',', '美', '国防部', '发言人', '杰夫·莫莱尔', '27日', '表示', ',', '美', '国防部长', '盖茨', '将', '于', '2011年', '1月', '14日', '访问', '韩国', '。']
  2. ['p', 'ni', 'nt', 'nt', 'v', 'wp', 'j', 'n', 'n', 'nh', 'nt', 'v', 'wp', 'j', 'n', 'nh', 'd', 'p', 'nt', 'nt', 'nt', 'v', 'ns', 'wp']
  3. ['O', 'S-Ni', 'O', 'O', 'O', 'O', 'B-Ni', 'E-Ni', 'O', 'S-Nh', 'O', 'O', 'O', 'S-Ns', 'O', 'S-Nh', 'O', 'O', 'O', 'O', 'O', 'O', 'S-Ns', 'O']
  4. 人名: 盖茨,杰夫·莫莱尔
  5. 地名: 韩国,美
  6. 组织机构: 美国防部,韩联社

命名实体识别结果可参考网址:https://ltp.readthedocs.io/zh_CN/latest/appendix.html 。

依存句法分析

  依存语法 (Dependency Parsing, DP) 通过分析语言单位内成分之间的依存关系揭示其句法结构。 直观来讲,依存句法分析识别句子中的“主谓宾”、“定状补”这些语法成分,并分析各成分之间的关系。示例的Python代码parser.py代码如下:

  1. import os
  2. from pyltp import Segmentor, Postagger, Parser
  3. # 分词
  4. cws_model_path = os.path.join(os.path.dirname(__file__), 'data/cws.model') # 分词模型路径,模型名称为`cws.model`
  5. lexicon_path = os.path.join(os.path.dirname(__file__), 'data/lexicon.txt') # 参数lexicon是自定义词典的文件路径
  6. segmentor = Segmentor()
  7. segmentor.load_with_lexicon(cws_model_path, lexicon_path)
  8. sent = '据韩联社12月28日反映,美国防部发言人杰夫·莫莱尔27日表示,美国防部长盖茨将于2011年1月14日访问韩国。'
  9. words = segmentor.segment(sent) # 分词
  10. print(list(words))
  11. # 词性标注
  12. pos_model_path = os.path.join(os.path.dirname(__file__), 'data/pos.model') # 词性标注模型路径,模型名称为`pos.model`
  13. postagger = Postagger() # 初始化实例
  14. postagger.load(pos_model_path) # 加载模型
  15. postags = postagger.postag(words) # 词性标注
  16. print(list(postags))
  17. # 依存句法分析
  18. par_model_path = os.path.join(os.path.dirname(__file__), 'data/parser.model') # 模型路径,模型名称为`parser.model`
  19. parser = Parser() # 初始化实例
  20. parser.load(par_model_path) # 加载模型
  21. arcs = parser.parse(words, postags) # 句法分析
  22. print(arcs) # type: object
  23. rely_id = [arc.head for arc in arcs] # 提取依存父节点id
  24. print(rely_id)
  25. relation = [arc.relation for arc in arcs] # 提取依存关系
  26. print(relation)
  27. heads = ['Root' if id == 0 else words[id - 1] for id in rely_id] # 匹配依存父节点词语
  28. print(heads)
  29. for i in range(len(words)):
  30. print(relation[i] + '(' + words[i] + ', ' + heads[i] + ')')
  31. # 释放模型
  32. segmentor.release()
  33. postagger.release()
  34. parser.release()

运行结果:

  1. ['据', '韩联社', '12月', '28日', '反映', ',', '美', '国防部', '发言人', '杰夫·莫莱尔', '27日', '表示', ',', '美', '国防部长', '盖茨', '将', '于', '2011年', '1月', '14日', '访问', '韩国', '。']
  2. ['p', 'ni', 'nt', 'nt', 'v', 'wp', 'j', 'n', 'n', 'nh', 'nt', 'v', 'wp', 'j', 'n', 'nh', 'd', 'p', 'nt', 'nt', 'nt', 'v', 'ns', 'wp']
  3. <pyltp.VectorOfParseResult object at 0x000001DDF2F797B0>
  4. [12, 5, 4, 5, 1, 1, 8, 9, 10, 12, 12, 0, 12, 15, 16, 22, 22, 22, 21, 21, 18, 12, 22, 12]
  5. ['ADV', 'SBV', 'ATT', 'ADV', 'POB', 'WP', 'ATT', 'ATT', 'ATT', 'SBV', 'ADV', 'HED', 'WP', 'ATT', 'ATT', 'SBV', 'ADV', 'ADV', 'ATT', 'ATT', 'POB', 'VOB', 'VOB', 'WP']
  6. ['表示', '反映', '28日', '反映', '据', '据', '国防部', '发言人', '杰夫·莫莱尔', '表示', '表示', 'Root', '表示', '国防部长', '盖茨', '访问', '访问', '访问', '14日', '14日', '于', '表示', '访问', '表示']
  7. ADV(据, 表示)
  8. SBV(韩联社, 反映)
  9. ATT(12月, 28日)
  10. ADV(28日, 反映)
  11. POB(反映, 据)
  12. WP(,, 据)
  13. ATT(美, 国防部)
  14. ATT(国防部, 发言人)
  15. ATT(发言人, 杰夫·莫莱尔)
  16. SBV(杰夫·莫莱尔, 表示)
  17. ADV(27日, 表示)
  18. HED(表示, Root)
  19. WP(,, 表示)
  20. ATT(美, 国防部长)
  21. ATT(国防部长, 盖茨)
  22. SBV(盖茨, 访问)
  23. ADV(将, 访问)
  24. ADV(于, 访问)
  25. ATT(2011年, 14日)
  26. ATT(1月, 14日)
  27. POB(14日, 于)
  28. VOB(访问, 表示)
  29. VOB(韩国, 访问)
  30. WP(。, 表示)

依存句法关系:

关系类型TagDescriptionExample
主谓关系SBVsubject-verb我送她一束花 (我 <– 送)
动宾关系VOB直接宾语,verb-object我送她一束花 (送 –> 花)
间宾关系IOB间接宾语,indirect-object我送她一束花 (送 –> 她)
前置宾语FOB前置宾语,fronting-object他什么书都读 (书 <– 读)
兼语DBLdouble他请我吃饭 (请 –> 我)
定中关系ATTattribute红苹果 (红 <– 苹果)
状中结构ADVadverbial非常美丽 (非常 <– 美丽)
动补结构CMPcomplement做完了作业 (做 –> 完)
并列关系COOcoordinate大山和大海 (大山 –> 大海)
介宾关系POBpreposition-object在贸易区内 (在 –> 内)
左附加关系LADleft adjunct大山和大海 (和 <– 大海)
右附加关系RADright adjunct孩子们 (孩子 –> 们)
独立结构ISindependent structure两个单句在结构上彼此独立
核心关系HEDhead指整个句子的核心

依存句法分析结果可参考网址:https://ltp.readthedocs.io/zh_CN/latest/appendix.html 。

语义角色标注

        语义角色标注是实现浅层语义分析的一种方式。在一个句子中,谓词是对主语的陈述或说明,指出“做什么”、“是什么”或“怎么样,代表了一个事件的核心,跟谓词搭配的名词称为论元。语义角色是指论元在动词所指事件中担任的角色。主要有:施事者(Agent)、受事者(Patient)、客体(Theme)、经验者(Experiencer)、受益者(Beneficiary)、工具(Instrument)、处所(Location)、目标(Goal)和来源(Source)等。示例的Python代码rolelabel.py如下:

  1. import os
  2. from pyltp import Segmentor, Postagger, Parser, SementicRoleLabeller
  3. # 分词
  4. cws_model_path = os.path.join(os.path.dirname(__file__), 'data/cws.model') # 分词模型路径,模型名称为`cws.model`
  5. lexicon_path = os.path.join(os.path.dirname(__file__), 'data/lexicon.txt') # 参数lexicon是自定义词典的文件路径
  6. segmentor = Segmentor()
  7. segmentor.load_with_lexicon(cws_model_path, lexicon_path)
  8. sent = '据韩联社12月28日反映,美国防部发言人杰夫·莫莱尔27日表示,美国防部长盖茨将于2011年1月14日访问韩国。'
  9. words = segmentor.segment(sent) # 分词
  10. print(list(words))
  11. # 词性标注
  12. pos_model_path = os.path.join(os.path.dirname(__file__), 'data/pos.model') # 词性标注模型路径,模型名称为`pos.model`
  13. postagger = Postagger() # 初始化实例
  14. postagger.load(pos_model_path) # 加载模型
  15. postags = postagger.postag(words) # 词性标注
  16. print(list(postags))
  17. # 依存句法分析
  18. par_model_path = os.path.join(os.path.dirname(__file__), 'data/parser.model') # 模型路径,模型名称为`parser.model`
  19. parser = Parser() # 初始化实例
  20. parser.load(par_model_path) # 加载模型
  21. arcs = parser.parse(words, postags) # 句法分析
  22. print(arcs)
  23. # 语义角色标注
  24. srl_model_path = os.path.join(os.path.dirname(__file__), 'data/pisrl_win.model') # 语义角色标注模型目录路径
  25. labeller = SementicRoleLabeller() # 初始化实例
  26. labeller.load(srl_model_path) # 加载模型
  27. roles = labeller.label(words, postags, arcs) # 语义角色标注
  28. print(roles) # type: object
  29. # 打印结果
  30. for role in roles:
  31. print(words[role.index], end=' ')
  32. print(role.index, "".join(["%s:(%d,%d) " % (arg.name, arg.range.start, arg.range.end) for arg in role.arguments]))
  33. # 释放模型
  34. segmentor.release()
  35. postagger.release()
  36. parser.release()
  37. labeller.release()

运行结果:

  1. ['据', '韩联社', '12月', '28日', '反映', ',', '美', '国防部', '发言人', '杰夫·莫莱尔', '27日', '表示', ',', '美', '国防部长', '盖茨', '将', '于', '2011年', '1月', '14日', '访问', '韩国', '。']
  2. ['p', 'ni', 'nt', 'nt', 'v', 'wp', 'j', 'n', 'n', 'nh', 'nt', 'v', 'wp', 'j', 'n', 'nh', 'd', 'p', 'nt', 'nt', 'nt', 'v', 'ns', 'wp']
  3. <pyltp.VectorOfParseResult object at 0x0000014214F89750>
  4. [dynet] random seed: 1145443137
  5. [dynet] allocating memory: 2000MB
  6. [dynet] memory allocation done.
  7. <pyltp.SementicRoles object at 0x0000014214F89870>
  8. 反映 4 A0:(1,1) A0:(2,3)
  9. 表示 11 MNR:(0,5) A0:(6,9) TMP:(10,10) A1:(13,22)
  10. 访问 21 A0:(13,15) ADV:(16,16) TMP:(17,20) A1:(22,22)

如果windows下使用模型pisrl.model会报错,解决办法:

下载这个把pisrl.model替换掉

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

闽ICP备14008679号