命名实体识别的两种方法

一 、什么是命名实体识别?

命名实体识别(Named Entity Recognition,简称NER),又称作“专名识别”,是指识别文本中具有特定意义的实体,主要包括人名、地名、机构名、专有名词等。通常包括两部分:(1)实体边界识别;(2) 确定实体类别(人名、地名、机构名或其他)。

二 、基于NLTK的命名实体识别:

NLTK:由宾夕法尼亚大学计算机和信息科学使用python语言实现的一种自然语言工具包,其收集的大量公开数据集、模型上提供了全面、易用的口,涵盖了分词、

词性标注(Part-Of-Speech tag, POS-tag)、命名实体识别(Named Entity Recognition, NER)、句法分析(Syntactic Parse)等各项NLP领域的功能。使用前需要先

下载NLTK,下载地址为:http://pypi.python.org/pypi/nltk,安装完成后,在python环境下输入import nltk测试是否安装成功,然后输入nltk.download()下载nltk所

需要的数据包,完成安装。

Python代码实现(注意文件的编码格式为utf-8无BOM格式):

[python]  view plain  copy
  1. # -*- coding: utf-8 -*-  
  2. import sys  
  3. reload(sys)  
  4. sys.setdefaultencoding('utf8')    #让cmd识别正确的编码  
  5. import nltk  
  6. newfile = open('news.txt')  
  7. text = newfile.read()  #读取文件  
  8. tokens = nltk.word_tokenize(text)  #分词  
  9. tagged = nltk.pos_tag(tokens)  #词性标注  
  10. entities = nltk.chunk.ne_chunk(tagged)  #命名实体识别  
  11. a1=str(entities) #将文件转换为字符串  
  12. file_object = open('out.txt''w')    
  13. file_object.write(a1)   #写入到文件中  
  14. file_object.close( )  
  15. print entities  

具体的方法可参考NLTK官网介绍:http://www.nltk.org/,输出的结果为:

[python]  view plain  copy
  1. >>> entities = nltk.chunk.ne_chunk(tagged)  
  2. >>> entities  
  3. Tree('S', [('At''IN'), ('eight''CD'), ("o'clock", 'JJ'),  
  4.            ('on''IN'), ('Thursday''NNP'), ('morning''NN'),  
  5.        Tree('PERSON', [('Arthur''NNP')]),  
  6.            ('did''VBD'), ("n't", 'RB'), ('feel', 'VB'),  
  7.            ('very''RB'), ('good''JJ'), ('.''.')])  
当然为了方便查看,我们可以以树结构的形式把结果绘制出来:
[python]  view plain  copy
  1. >>> from nltk.corpus import treebank  
  2. >>> t = treebank.parsed_sents('wsj_0001.mrg')[0]  
  3. >>> t.draw()  

此外,关于标注词性的解释,我们可以参考以下文章:http://blog.csdn.net/john159151/article/details/50255101

三 、基于Stanford的NER:

Stanford Named Entity Recognizer (NER)是斯坦福大学自然语言研究小组发布的成果之一,主页是:http://nlp.stanford.edu/software/CRF-NER.shtml。Stanford NER 是一个Java实现的命名实体识别(以下简称NER))程序。NER将文本中的实体按类标记出来,例如人名,公司名,地区,基因和蛋白质的名字等。

NER基于一个训练而得的Model(模型可识别出 Time, Location, Organization, Person, Money, Percent, Date)七类属性,其用于训练的数据即大量人工标记好的文本,理论上用于训练的数据量越大,NER的识别效果就越好。

因为原始的NER是基于java实现的,所以在使用Python编程之前,要确保自己电脑上已经安装了jar1.8的环境(否则会报关于Socket的错误)。

然后我们使用Pyner使用python语言实现命名实体识别。下载地址为:https://github.com/dat/pyner

安装Pyner:解压下载的Pyner,命令行中将工作目录切换到Pyner文件夹下, 输入命令 :python setup.py install 完成安装.

接下来,还需要下载StanfordNER工具包,下载地址为:http://nlp.stanford.edu/software/stanford-ner-2014-01-04.zip,然后在解压后的目录打开cmd命令窗体,执行,java -mx1000m -cp stanford-ner.jar edu.stanford.nlp.ie.NERServer -loadClassifier classifiers/english.muc.7class.distsim.crf.ser.gz -port 8080 -outputFormat inlineXML,直到结果为:Loading classifier from classifiers/english.muc.7class.distsim.crf.ser.gz ... done [1.2 sec].

        以上操作是因为斯坦福的命名实体识别是基于java的socket写的,所以必要保证有一个窗题与我们执行的命令通信。关于java的socket编程,可以参考以下文章:http://www.cnblogs.com/rond/p/3565113.html

最后,我们终于可以使用python编程实现NER了:

[python]  view plain  copy
  1. import ner  
  2. import sys  
  3. import nltk  
  4. reload(sys)  
  5. sys.setdefaultencoding('utf8')  
  6. newfile = open('news.txt')  
  7. text = newfile.read()  
  8. tagger = ner.SocketNER(host='localhost', port=8080)#socket编程  
  9. result=tagger.get_entities(text)   #stanford实现NER  
  10. a1=str(result)  
  11. file_object = open('outfile.txt''w')  
  12. file_object.write(a1)  
  13. file_object.close( )  
  14. print result  

以上是我对文本文件进行的测试,官网的案例https://github.com/dat/pyner运行结果为:

[python]  view plain  copy
  1. >>> import ner  
  2. >>> tagger = ner.SocketNER(host='localhost', port=8080)  
  3. >>> tagger.get_entities("University of California is located in California, United States")  
  4. {'LOCATION': ['California''United States'],  
  5.  'ORGANIZATION': ['University of California']}  
由此可见,stanford的命名实体识别可以更好的把地名,人名,机构名等标注出来。

四 、两种方法的比较:

我拿同一个文本文件用两种方法进行命名实体识别,结果如下:

NLTK:

Stanford:

比较两种方式,我们可以发现,NLTK下的命名实体识别更加倾向于分词和词性标准,虽然它也会将组织名,人名,地名等标注出来,但由于它把文件中的谓语,宾语等成分也标注了出来,造成了输出文本的冗余性,不利于读者很好的识别命名实体,需要我们对文本做进一步处理。NLTK下的命名实体识别的有点时,可以使用NLTK下的treebank包将文本绘制为树形,使结果更加清晰易读。相较而言,我更加倾向于Stanford的命名实体识别,它可以把Time, Location, Organization, Person, Money, Percent, Date七类实体很清晰的标注出来,而没有多余的词性。但由于NER是基于java开发的,所以在用python实现时可能由于jar包或是路径问题出现很多bug。

以上就是关于NLTK和stanford对英文文本的命名实体识别,关于自然语言处理中文文件,我们可以考虑jieba分词:https://www.oschina.net/p/jieba

转自 https://blog.csdn.net/babydx/article/details/77836810

猜你喜欢

转载自blog.csdn.net/qr457535344/article/details/79817610
今日推荐