語言技術平臺(LTP)通過哈工大社會計算與信息檢索研究中心 11 年的持續研發和推廣, 是國內外最具影響力的中文處理基礎平臺。它提供的功能包括中文分詞、詞性標註、命名實體識別、依存句法分析、語義角色標註等。html
pyltp 是 LTP 的 Python 封裝,同時支持Python2和Python3版本。Python3的安裝方法爲:python
pip3 install pyltp
在使用該模塊前,須要下載完整的模型文件,文件下載地址爲:https://pan.baidu.com/share/l... 。pyltp 的全部輸入的分析文本和輸出的結果的編碼均爲 UTF-8。模型的數據文件以下:web
其中,cws.model用於分詞模型,lexicon.txt爲分詞時添加的用戶字典,ner.model爲命名實體識別模型,parser.model爲依存句法分析模型,pisrl.model爲語義角色標註模型,pos爲詞性標註模型。算法
pyltp的使用示例項目結構以下:api
分句指的是將一段話或一片文章中的文字按句子分開,按句子造成獨立的單元。示例的Python代碼sentenct_split.py以下:微信
# -*- coding: utf-8 -*- from pyltp import SentenceSplitter # 分句 doc = '據韓聯社12月28日反映,美國防部發言人傑夫·莫萊爾27日表示,美國防部長蓋茨將於2011年1月14日訪問韓國。' \ '蓋茨原計劃從明年1月9日至14日陸續訪問中國和日本,目前,他決定在行程中增長對韓國的訪問。莫萊爾表示,' \ '蓋茨在訪韓期間將會晤韓國國防部長官金寬鎮,就朝鮮近日的行動交換意見,同時商討增強韓美兩軍同盟關係等問題,' \ '擬定共同應對朝鮮挑釁和核計劃的方案。' sents = SentenceSplitter.split(doc) # 分句 for sent in sents: print(sent)
輸出結果以下:架構
據韓聯社12月28日反映,美國防部發言人傑夫·莫萊爾27日表示,美國防部長蓋茨將於2011年1月14日訪問韓國。 蓋茨原計劃從明年1月9日至14日陸續訪問中國和日本,目前,他決定在行程中增長對韓國的訪問。 莫萊爾表示,蓋茨在訪韓期間將會晤韓國國防部長官金寬鎮,就朝鮮近日的行動交換意見,同時商討增強韓美兩軍同盟關係等問題,擬定共同應對朝鮮挑釁和核計劃的方案。
分詞指的是將一句話按詞語分開,按詞語造成獨立的單元。示例的Python代碼words_split.py以下:app
# -*- coding: utf-8 -*- import os from pyltp import Segmentor cws_model_path = os.path.join(os.path.dirname(__file__), 'data/cws.model') # 分詞模型路徑,模型名稱爲`cws.model` lexicon_path = os.path.join(os.path.dirname(__file__), 'data/lexicon.txt') # 參數lexicon是自定義詞典的文件路徑 segmentor = Segmentor() segmentor.load_with_lexicon(cws_model_path, lexicon_path) sent = '據韓聯社12月28日反映,美國防部發言人傑夫·莫萊爾27日表示,美國防部長蓋茨將於2011年1月14日訪問韓國。' words = segmentor.segment(sent) # 分詞 print('/'.join(words)) segmentor.release()
輸出的結果以下:工具
據/韓聯社/12月/28日/反映/,/美/國防部/發言人/傑夫·莫萊爾/27日/表示/,/美/國防部長/蓋茨/將/於/2011年/1月/14日/訪問/韓國/。
詞性標註指的是一句話分完詞後,制定每一個詞語的詞性。示例的Python代碼postagger.py以下:post
# -*- coding: utf-8 -*- import os from pyltp import Segmentor, Postagger # 分詞 cws_model_path = os.path.join(os.path.dirname(__file__), 'data/cws.model') # 分詞模型路徑,模型名稱爲`cws.model` lexicon_path = os.path.join(os.path.dirname(__file__), 'data/lexicon.txt') # 參數lexicon是自定義詞典的文件路徑 segmentor = Segmentor() segmentor.load_with_lexicon(cws_model_path, lexicon_path) sent = '據韓聯社12月28日反映,美國防部發言人傑夫·莫萊爾27日表示,美國防部長蓋茨將於2011年1月14日訪問韓國。' words = segmentor.segment(sent) # 分詞 # 詞性標註 pos_model_path = os.path.join(os.path.dirname(__file__), 'data/pos.model') # 詞性標註模型路徑,模型名稱爲`pos.model` postagger = Postagger() # 初始化實例 postagger.load(pos_model_path) # 加載模型 postags = postagger.postag(words) # 詞性標註 for word, postag in zip(words, postags): print(word, postag) # 釋放模型 segmentor.release() postagger.release() ''' 詞性標註結果說明 https://ltp.readthedocs.io/zh_CN/latest/appendix.html#id3 '''
輸出結果以下:
據 p 韓聯社 ni 12月 nt 28日 nt 反映 v , wp 美 j 國防部 n 發言人 n 傑夫·莫萊爾 nh 27日 nt 表示 v , wp 美 j 國防部長 n 蓋茨 nh 將 d 於 p 2011年 nt 1月 nt 14日 nt 訪問 v 韓國 ns 。 wp
詞性標註結果可參考網址:https://ltp.readthedocs.io/zh... 。
命名實體識別(NER)指的是識別出一句話或一段話或一片文章中的命名實體,好比人名,地名,組織機構名。示例的Python代碼ner.py以下:
# -*- coding: utf-8 -*- import os from pyltp import Segmentor, Postagger # 分詞 cws_model_path = os.path.join(os.path.dirname(__file__), 'data/cws.model') # 分詞模型路徑,模型名稱爲`cws.model` lexicon_path = os.path.join(os.path.dirname(__file__), 'data/lexicon.txt') # 參數lexicon是自定義詞典的文件路徑 segmentor = Segmentor() segmentor.load_with_lexicon(cws_model_path, lexicon_path) sent = '據韓聯社12月28日反映,美國防部發言人傑夫·莫萊爾27日表示,美國防部長蓋茨將於2011年1月14日訪問韓國。' words = segmentor.segment(sent) # 分詞 # 詞性標註 pos_model_path = os.path.join(os.path.dirname(__file__), 'data/pos.model') # 詞性標註模型路徑,模型名稱爲`pos.model` postagger = Postagger() # 初始化實例 postagger.load(pos_model_path) # 加載模型 postags = postagger.postag(words) # 詞性標註 ner_model_path = os.path.join(os.path.dirname(__file__), 'data/ner.model') # 命名實體識別模型路徑,模型名稱爲`pos.model` from pyltp import NamedEntityRecognizer recognizer = NamedEntityRecognizer() # 初始化實例 recognizer.load(ner_model_path) # 加載模型 # netags = recognizer.recognize(words, postags) # 命名實體識別 # 提取識別結果中的人名,地名,組織機構名 persons, places, orgs = set(), set(), set() netags = list(recognizer.recognize(words, postags)) # 命名實體識別 print(netags) # print(netags) i = 0 for tag, word in zip(netags, words): j = i # 人名 if 'Nh' in tag: if str(tag).startswith('S'): persons.add(word) elif str(tag).startswith('B'): union_person = word while netags[j] != 'E-Nh': j += 1 if j < len(words): union_person += words[j] persons.add(union_person) # 地名 if 'Ns' in tag: if str(tag).startswith('S'): places.add(word) elif str(tag).startswith('B'): union_place = word while netags[j] != 'E-Ns': j += 1 if j < len(words): union_place += words[j] places.add(union_place) # 機構名 if 'Ni' in tag: if str(tag).startswith('S'): orgs.add(word) elif str(tag).startswith('B'): union_org = word while netags[j] != 'E-Ni': j += 1 if j < len(words): union_org += words[j] orgs.add(union_org) i += 1 print('人名:', ','.join(persons)) print('地名:', ','.join(places)) print('組織機構:', ','.join(orgs)) # 釋放模型 segmentor.release() postagger.release() recognizer.release()
輸出的結果以下:
['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'] 人名: 傑夫·莫萊爾,蓋茨 地名: 美,韓國 組織機構: 韓聯社,美國防部
命名實體識別結果可參考網址:https://ltp.readthedocs.io/zh... 。
依存語法 (Dependency Parsing, DP) 經過分析語言單位內成分之間的依存關係揭示其句法結構。 直觀來說,依存句法分析識別句子中的「主謂賓」、「定狀補」這些語法成分,並分析各成分之間的關係。示例的Python代碼parser.py代碼以下:
# -*- coding: utf-8 -*- import os from pyltp import Segmentor, Postagger, Parser # 分詞 cws_model_path = os.path.join(os.path.dirname(__file__), 'data/cws.model') # 分詞模型路徑,模型名稱爲`cws.model` lexicon_path = os.path.join(os.path.dirname(__file__), 'data/lexicon.txt') # 參數lexicon是自定義詞典的文件路徑 segmentor = Segmentor() segmentor.load_with_lexicon(cws_model_path, lexicon_path) sent = '據韓聯社12月28日反映,美國防部發言人傑夫·莫萊爾27日表示,美國防部長蓋茨將於2011年1月14日訪問韓國。' words = segmentor.segment(sent) # 分詞 # 詞性標註 pos_model_path = os.path.join(os.path.dirname(__file__), 'data/pos.model') # 詞性標註模型路徑,模型名稱爲`pos.model` postagger = Postagger() # 初始化實例 postagger.load(pos_model_path) # 加載模型 postags = postagger.postag(words) # 詞性標註 # 依存句法分析 par_model_path = os.path.join(os.path.dirname(__file__), 'data/parser.model') # 模型路徑,模型名稱爲`parser.model` parser = Parser() # 初始化實例 parser.load(par_model_path) # 加載模型 arcs = parser.parse(words, postags) # 句法分析 rely_id = [arc.head for arc in arcs] # 提取依存父節點id relation = [arc.relation for arc in arcs] # 提取依存關係 heads = ['Root' if id == 0 else words[id-1] for id in rely_id] # 匹配依存父節點詞語 for i in range(len(words)): print(relation[i] + '(' + words[i] + ', ' + heads[i] + ')') # 釋放模型 segmentor.release() postagger.release() parser.release()
輸出結果以下:
ADV(據, 表示) SBV(韓聯社, 反映) ATT(12月, 28日) ADV(28日, 反映) POB(反映, 據) WP(,, 據) ATT(美, 國防部) ATT(國防部, 發言人) ATT(發言人, 傑夫·莫萊爾) SBV(傑夫·莫萊爾, 表示) ADV(27日, 表示) HED(表示, Root) WP(,, 表示) ATT(美, 國防部長) ATT(國防部長, 蓋茨) SBV(蓋茨, 訪問) ADV(將, 訪問) ADV(於, 訪問) ATT(2011年, 14日) ATT(1月, 14日) POB(14日, 於) VOB(訪問, 表示) VOB(韓國, 訪問) WP(。, 表示)
依存句法分析結果可參考網址:https://ltp.readthedocs.io/zh... 。
語義角色標註是實現淺層語義分析的一種方式。在一個句子中,謂詞是對主語的陳述或說明,指出「作什麼」、「是什麼」或「怎麼樣,表明了一個事件的核心,跟謂詞搭配的名詞稱爲論元。語義角色是指論元在動詞所指事件中擔任的角色。主要有:施事者(Agent)、受事者(Patient)、客體(Theme)、經驗者(Experiencer)、受益者(Beneficiary)、工具(Instrument)、處所(Location)、目標(Goal)和來源(Source)等。示例的Python代碼rolelabel.py以下:
# -*- coding: utf-8 -*- import os from pyltp import Segmentor, Postagger, Parser, SementicRoleLabeller # 分詞 cws_model_path = os.path.join(os.path.dirname(__file__), 'data/cws.model') # 分詞模型路徑,模型名稱爲`cws.model` lexicon_path = os.path.join(os.path.dirname(__file__), 'data/lexicon.txt') # 參數lexicon是自定義詞典的文件路徑 segmentor = Segmentor() segmentor.load_with_lexicon(cws_model_path, lexicon_path) sent = '據韓聯社12月28日反映,美國防部發言人傑夫·莫萊爾27日表示,美國防部長蓋茨將於2011年1月14日訪問韓國。' words = segmentor.segment(sent) # 分詞 # 詞性標註 pos_model_path = os.path.join(os.path.dirname(__file__), 'data/pos.model') # 詞性標註模型路徑,模型名稱爲`pos.model` postagger = Postagger() # 初始化實例 postagger.load(pos_model_path) # 加載模型 postags = postagger.postag(words) # 詞性標註 # 依存句法分析 par_model_path = os.path.join(os.path.dirname(__file__), 'data/parser.model') # 模型路徑,模型名稱爲`parser.model` parser = Parser() # 初始化實例 parser.load(par_model_path) # 加載模型 arcs = parser.parse(words, postags) # 句法分析 # 語義角色標註 srl_model_path = os.path.join(os.path.dirname(__file__), 'data/pisrl.model') # 語義角色標註模型目錄路徑 labeller = SementicRoleLabeller() # 初始化實例 labeller.load(srl_model_path) # 加載模型 roles = labeller.label(words, postags, arcs) # 語義角色標註 # 打印結果 for role in roles: print(words[role.index], end=' ') print(role.index, "".join(["%s:(%d,%d)" % (arg.name, arg.range.start, arg.range.end) for arg in role.arguments])) # 釋放模型 segmentor.release() postagger.release() parser.release() labeller.release()
輸出結果以下:
反映 4 A0:(1,1)A0:(2,3) 表示 11 MNR:(0,5)A0:(6,9)TMP:(10,10)A1:(13,22) 訪問 21 A0:(13,15)ADV:(16,16)TMP:(17,20)A1:(22,22)
本文介紹了中文NLP的一個傑出工具pyltp,並給出了該模塊的各個功能的一個示例,但願能給讀者一些思考與啓示。本文到此結束,感謝你們閱讀~
注意:本人現已開通微信公衆號: Python爬蟲與算法(微信號爲:easy_web_scrape), 歡迎你們關注哦~~