NLTK學習筆記 七 文字資訊提取

2021-08-22 19:31:04 字數 4351 閱讀 2263

目錄

開發和評估分塊器

命名實體識別和資訊提取

如何構建乙個系統,用於從非結構化的文字中提取結構化的資訊和資料?哪些方法使用這類行為?哪些語料庫適合這項工作?是否可以訓練和評估模型?

資訊提取,特別是結構化資訊提取,可以模擬資料庫的記錄。對應的關係繫結了對應的資料資訊。針對自然語言這類非結構化的資料,為了獲取對應關係,應該搜尋實體對應的特殊關係,並且用字串、元素等一些資料結構記錄。

比如:we saw the yellow dog ,按照分塊的思想,會將後三個詞語分到np中,而裡面的三個詞又分別對應 dt/jj/nn;saw 分到vbd中;we 分到np中。對於最後三個詞語來說,np就是組塊(較大的集合)。為了做到這點,可以借助nltk自帶的分塊語法,類似於正規表示式,來實現句子分塊。

注意三點即可:

import nltk

sentence = [('the','dt'),('little','jj'),('yellow','jj'),('dog','nn'),('brak','vbd')]

grammer = "np: "

cp = nltk.regexpparser(grammer) #生成規則

result = cp.parse(sentence) #進行分塊

print(result)

result.draw() #呼叫matplotlib庫畫出來

import nltk

sentence = [('the','dt'),('little','jj'),('yellow','jj'),('dog','nn'),('bark','vbd'),('at','in'),('the','dt'),('cat','nn')]

grammer = """np:

}+{""" #加縫隙,必須儲存換行符

cp = nltk.regexpparser(grammer) #生成規則

result = cp.parse(sentence) #進行分塊

print(result)

如果呼叫print(type(result))檢視型別就會發現,是nltk.tree.tree。從名字看出來這是一種樹狀結構。nltk.tree可以實現樹狀結構,並且支援拼接技術,提供結點的查詢和樹的繪製。

tree1 = nltk.tree('np',['alick'])

print(tree1)

tree2 = nltk.tree('n',['alick','rabbit'])

print(tree2)

tree3 = nltk.tree('s',[tree1,tree2])

print(tree3.label()) #檢視樹的結點

tree3.draw()

分別代表內部,外部,開始(就是英語單詞的首字母)。對於上面講的 np,nn這樣的分類,只需要在前面加上 i-/b-/o-即可。這樣就能使規則外的集合被顯式出來,類似上面的加縫隙。

nltk已經為我們提供了分塊器,減少了手動構建規則。同時,也提供了已經分塊好的內容,供我們自己構建規則時候進行參考。

#這段**在python2下執行

from nltk.corpus import conll2000

print conll2000.chunked_sents('train.txt')[99] #檢視已經分塊的乙個句子

text = """

he /prp/ b-np

accepted /vbd/ b-vp

the dt b-np

position nn i-np

of in b-pp

vice nn b-np

chairman nn i-np

of in b-pp

carlyle nnp b-np

group nnp i-np

, , o

a dt b-np

merchant nn i-np

banking nn i-np

concern nn i-np

. . o

"""result = nltk.chunk.conllstr2tree(text,chunk_types=['np'])

對於之前自己定義的規則cp,可以使用cp.evaluate(conll2000.chunked_sents('train.txt')[99])來測試正確率。利用之前學過的unigram標註器,可以進行名詞短語分塊,並且測試準確度

class unigramchunker(nltk.chunkparseri):

"""一元分塊器,

該分塊器可以從訓練句子集中找出每個詞性標註最有可能的分塊標記,

然後使用這些資訊進行分塊

"""def __init__(self, train_sents):

"""建構函式

:param train_sents: tree物件列表

"""train_data =

for sent in train_sents:

# 將tree物件轉換為iob標記列表[(word, tag, iob-tag), ...]

conlltags = nltk.chunk.tree2conlltags(sent)

# 找出每個詞性標註對應的iob標記

ti_list = [(t, i) for w, t, i in conlltags]

# 使用一元標註器進行訓練

self.__tagger = nltk.unigramtagger(train_data)

def parse(self, tokens):

"""對句子進行分塊

:param tokens: 標註詞性的單詞列表

:return: tree物件

"""# 取出詞性標註

tags = [tag for (word, tag) in tokens]

# 對詞性標註進行分塊標記

ti_list = self.__tagger.tag(tags)

# 取出iob標記

iob_tags = [iob_tag for (tag, iob_tag) in ti_list]

# 組合成conll標記

conlltags = [(word, pos, iob_tag) for ((word, pos), iob_tag) in zip(tokens, iob_tags)]

return nltk.chunk.conlltags2tree(conlltags)

test_sents = conll2000.chunked_sents("test.txt", chunk_types=["np"])

train_sents = conll2000.chunked_sents("train.txt", chunk_types=["np"])

unigram_chunker = unigramchunker(train_sents)

print(unigram_chunker.evaluate(test_sents))

命名實體:確切的名詞短語,指特定型別的個體,如日期、人、組織等。如果自己去許槤分類器肯定頭大(ˉ▽ ̄~)~~。nltk提供了乙個訓練好的分類器--nltk.ne_chunk(tagged_sent[,binary=false])。如果binary被設定為true,那麼命名實體就只被標註為ne;否則標籤會有點複雜。

sent = nltk.corpus.treebank.tagged_sents()[22]

print(nltk.ne_chunk(sent,binary=true))

如果命名實體被確定後,就可以實現關係抽取來提取資訊。一種方法是:尋找所有的三元組(x,a,y)。其中x和y是命名實體,a是表示兩者關係的字串,示例如下:

#請在python2下執行

import re

in = re.compile(r'.*\bin\b(?!\b.+ing)')

for doc in nltk.corpus.ieer.parsed_docs('nyt_19980315'):

for rel in nltk.sem.extract_rels('org','loc',doc,corpus='ieer',pattern = in):

print nltk.sem.show_raw_rtuple(rel)

NLTK學習筆記 七 文字資訊提取

開發和評估分塊器 命名實體識別和資訊提取 如何構建乙個系統,用於從非結構化的文字中提取結構化的資訊和資料?哪些方法使用這類行為?哪些語料庫適合這項工作?是否可以訓練和評估模型?資訊提取,特別是結構化資訊提取,可以模擬資料庫的記錄。對應的關係繫結了對應的資料資訊。針對自然語言這類非結構化的資料,為了獲...

NLTK學習筆記 七 文字資訊提取

目錄開發和評估分塊器 命名實體識別和資訊提取 如何構建乙個系統,用於從非結構化的文字中提取結構化的資訊和資料?哪些方法使用這類行為?哪些語料庫適合這項工作?是否可以訓練和評估模型?資訊提取,特別是結構化資訊提取,可以模擬資料庫的記錄。對應的關係繫結了對應的資料資訊。針對自然語言這類非結構化的資料,為...

二 文字提取 機器學習

英文提取步驟 準備句子 例項化countvectorizer 講分詞結果變成字串當做fit transform的輸入值 示例 from sklearn.feature extraction import dictvectorizer from sklearn.feature extraction.t...