目錄
一.什麼是命名實體識别
二.基于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
以上是我對文本檔案進行的測試,官網的案例
運作結果為:
>>> 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。
【總結】:命名實體識别是建構知識圖譜、進行自然語言處理問題的第一步,本文總結了現有的處理命名實體識别問題的兩種方法,你掌握了嗎?
原文釋出時間為:2018-07-20
本文作者:Walker
本文來自雲栖社群合作夥伴“
磐創AI”,了解相關資訊可以關注“
”。