命名實體識別的兩種方法


作者:Walker

目錄

    一.什么是命名實體識別

    二.基於NLTK的命名實體識別

    三.基於Stanford的NER

    四.總結

一 、什么是命名實體識別?

命名實體識別(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格式):

-- coding: utf-8 --

import sys

reload(sys)

sys.setdefaultencoding(‘utf8’)    #讓cmd識別正確的編碼

import nltk

newfile = open(‘news.txt’)

text = newfile.read()  #讀取文件

tokens = nltk.word_tokenize(text)  #分詞

tagged = nltk.pos_tag(tokens)  #詞性標注

entities = nltk.chunk.ne_chunk(tagged)  #命名實體識別

a1=str(entities) #將文件轉換為字符串

file_object = open(‘out.txt’, ‘w’)

file_object.write(a1)   #寫入到文件中

file_object.close( )

print entities

 

具體的方法可參考NLTK官網介紹:http://www.nltk.org/,輸出的結果為:

>>> entities = nltk.chunk.ne_chunk(tagged)

>>> entities

Tree(‘S’, [(‘At’, ‘IN’), (‘eight’, ‘CD’), (“o’clock”, ‘JJ’),

(‘on’, ‘IN’), (‘Thursday’, ‘NNP’), (‘morning’, ‘NN’),

Tree(‘PERSON’, [(‘Arthur’, ‘NNP’)]),

(‘did’, ‘VBD’), (“n’t”, ‘RB’), (‘feel’, ‘VB’),

(‘very’, ‘RB’), (‘good’, ‘JJ’), (‘.’, ‘.’)])

 

當然為了方便查看,我們可以以樹結構的形式把結果繪制出來:

>>> from nltk.corpus import treebank

>>> t = treebank.parsed_sents(‘wsj_0001.mrg’)[0]

>>> t.draw()

 

三 、基於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了:

import ner

import sys

import nltk

reload(sys)

sys.setdefaultencoding(‘utf8’)

newfile = open(‘news.txt’)

text = newfile.read()

tagger = ner.SocketNER(host=’localhost’, port=8080)#socket編程

result=tagger.get_entities(text)   #stanford實現NER

a1=str(result)

file_object = open(‘outfile.txt’, ‘w’)

file_object.write(a1)

file_object.close( )

print result

 

以上是我對文本文件進行的測試,官網的案例https://github.com/dat/pyner運行結果為:

>>> import ner

>>> tagger = ner.SocketNER(host=’localhost’, port=8080)

>>> tagger.get_entities(“University of California is located in California, United States”)

{‘LOCATION’: [‘California’, ‘United States’],

‘ORGANIZATION’: [‘University of California’]}

四 、兩種方法的比較:

我拿同一個文本文件用兩種方法進行命名實體識別,結果如下:

圖1 NLTK運行結果

圖2 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

【總結】:命名實體識別是構建知識圖譜、進行自然語言處理問題的第一步,本文總結了現有的處理命名實體識別問題的兩種方法,你掌握了嗎?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM