NLP入門(六)pyltp的介紹與使用


pyltp的簡介

  語言技術平台(LTP)經過哈工大社會計算與信息檢索研究中心 11 年的持續研發和推廣, 是國內外最具影響力的中文處理基礎平台。它提供的功能包括中文分詞、詞性標注、命名實體識別、依存句法分析、語義角色標注等。

語言技術平台架構

  pyltp 是 LTP 的 Python 封裝,同時支持Python2和Python3版本。Python3的安裝方法為:

pip3 install pyltp

  在使用該模塊前,需要下載完整的模型文件,文件下載地址為:https://pan.baidu.com/share/link?shareid=1988562907&uk=2738088569#list/path=%2F 。pyltp 的所有輸入的分析文本和輸出的結果的編碼均為 UTF-8。模型的數據文件如下:

模型數據

其中,cws.model用於分詞模型,lexicon.txt為分詞時添加的用戶字典,ner.model為命名實體識別模型,parser.model為依存句法分析模型,pisrl.model為語義角色標注模型,pos為詞性標注模型。

pyltp的使用

  pyltp的使用示例項目結構如下:

示例項目

分句

  分句指的是將一段話或一片文章中的文字按句子分開,按句子形成獨立的單元。示例的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如下:

# -*- 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如下:

# -*- 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_CN/latest/appendix.html

命名實體識別

  命名實體識別(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_CN/latest/appendix.html

依存句法分析

  依存語法 (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_CN/latest/appendix.html

語義角色標注

  語義角色標注是實現淺層語義分析的一種方式。在一個句子中,謂詞是對主語的陳述或說明,指出“做什么”、“是什么”或“怎么樣,代表了一個事件的核心,跟謂詞搭配的名詞稱為論元。語義角色是指論元在動詞所指事件中擔任的角色。主要有:施事者(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), 歡迎大家關注哦~~


免責聲明!

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



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