命名實體識別的兩種方法
來自專欄 TensorFlowNews5 人贊了文章
作者 | Walker
【磐創AI導讀】:本文主要介紹自然語言處理中的經典問題——命名實體識別的兩種方法。
目錄
一.什麼是命名實體識別
二.基於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 sysreload(sys)sys.setdefaultencoding(utf8) #讓cmd識別正確的編碼import nltknewfile = 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)>>> entitiesTree(S, [(At, IN), (eight, CD), ("oclock", JJ), (on, IN), (Thursday, NNP), (morning, NN), Tree(PERSON, [(Arthur, NNP)]), (did, VBD), ("nt", 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 nerimport sysimport nltkreload(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實現NERa1=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。
【總結】:命名實體識別是構建知識圖譜、進行自然語言處理問題的第一步,本文總結了現有的處理命名實體識別問題的兩種方法,你掌握了嗎?
最後,對深度學習感興趣,熱愛Tensorflow的小夥伴,歡迎關注我們的網站!http://www.tensorflownews.com。我們的公眾號:磐創AI。
推薦閱讀: