首頁 > 後端開發 > Python教學 > 如何建構一個系統?

如何建構一個系統?

PHP中文网
發布: 2017-06-20 11:00:18
原創
2402 人瀏覽過

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

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

實體辨識:分塊技術

例如:We saw the yellow dog ,依照分塊的思想,會將後三個字分到NP中,裡面的三個字又分別對應DT/JJ/NN;saw 分到VBD中;We 分到NP中。對最後三個字來說,NP就是組塊(較大的集合)。為了做到這一點,可以借助NLTK自帶的分塊語法,類似於正規表示式,來實現句子分塊。

分塊語法的建構

注意三點即可:

  • #基本的分塊:組塊:{群組區塊下的子群組區塊}(類似:"NP: {<DT>?<JJ>*<NN>}"這樣的字串)。而?*+保存了正規表示式的意義。

import nltk
sentence = [(&#39;the&#39;,&#39;DT&#39;),(&#39;little&#39;,&#39;JJ&#39;),(&#39;yellow&#39;,&#39;JJ&#39;),(&#39;dog&#39;,&#39;NN&#39;),(&#39;brak&#39;,&#39;VBD&#39;)]
grammer = "NP: {<DT>?<JJ>*<NN>}"cp = nltk.RegexpParser(grammer) #生成规则result = cp.parse(sentence) #进行分块print(result)

result.draw() #调用matplotlib库画出来
登入後複製


  • #可以為不包含再大塊中的識別碼序列定義一個縫隙}<VBD|IN>+{

#
import nltk
sentence = [(&#39;the&#39;,&#39;DT&#39;),(&#39;little&#39;,&#39;JJ&#39;),(&#39;yellow&#39;,&#39;JJ&#39;),(&#39;dog&#39;,&#39;NN&#39;),(&#39;bark&#39;,&#39;VBD&#39;),(&#39;at&#39;,&#39;IN&#39;),(&#39;the&#39;,&#39;DT&#39;),(&#39;cat&#39;,&#39;NN&#39;)]
grammer = """NP:             {<DT>?<JJ>*<NN>}            }<VBD|NN>+{            """  #加缝隙,必须保存换行符cp = nltk.RegexpParser(grammer) #生成规则result = cp.parse(sentence) #进行分块print(result)
登入後複製



##可以遞歸式的調用,這符合語言結構中的遞歸嵌套。例如:
VP: {*} PP:{}

。此時,

RegexpParser

函數的參數

loop
即可設為2,多次循環,來防止遺漏。


樹狀圖

如果呼叫print(type(result))檢視型別就會發現,是nltk.tree. Tree

。從名字看出來這是一種樹狀結構。
nltk.Tree
可以實現樹狀結構,並且支援拼接技術,提供結點的查詢和樹的繪製。


tree1 = nltk.Tree(&#39;NP&#39;,[&#39;Alick&#39;])print(tree1)
tree2 = nltk.Tree(&#39;N&#39;,[&#39;Alick&#39;,&#39;Rabbit&#39;])print(tree2)
tree3 = nltk.Tree(&#39;S&#39;,[tree1,tree2])print(tree3.label()) #查看树的结点tree3.draw()
登入後複製

IOB標記#分別代表內部,外部,開始(就是英文單字的首字母)。對於上面講的 NP,NN這樣的分類,只需要在前面加上 I-/B-/O-即可。這樣就能使規則外的集合被顯式出來,類似上面的加縫隙。

開發和評估分塊器

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

#这段代码在python2下运行from nltk.corpus import conll2000print conll2000.chunked_sents(&#39;train.txt&#39;)[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=[&#39;NP&#39;])
登入後複製

對於先前自己定義的規則
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]
            train_data.append(ti_list)# 使用一元标注器进行训练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&#39;.*\bin\b(?!\b.+ing)&#39;)for doc in nltk.corpus.ieer.parsed_docs(&#39;NYT_19980315&#39;):for rel in nltk.sem.extract_rels(&#39;ORG&#39;,&#39;LOC&#39;,doc,corpus=&#39;ieer&#39;,pattern = IN):print nltk.sem.show_raw_rtuple(rel)
登入後複製
#########

以上是如何建構一個系統?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門推薦
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板