奮戰聊天機械人(三)自動化對語料做詞性標註

2021-08-07 14:02:47 字數 3146 閱讀 2463

import nltk

porter = nltk.porterstemmer()

porter.stem('lying')

import nltk

text = nltk.word_tokenize("and now for something completely different")

nltk.pos_tag(text)

其中cc是連線詞,rb是副詞,in是介詞,nn是名次,jj是形容詞

這是一句完整的話,實際上pos_tag是處理乙個詞序列,會根據句子來動態判斷,比如:

i love you ————love識別為名詞

love and hate —————love識別為名詞

nltk中多數都是英文的詞性標註語料庫,如果我們想自己標註一批語料庫該怎麼辦呢?

nltk提供了比較方便的方法:

tagged_token = nltk,tag

.str2truple('fly/nn')

這裡的nltk.tag.str2tuple可以把fly/nn這種字串轉成乙個二元組,事實上nltk的語料庫中都是這種字串形式的標註,那麼我們如果把語料庫標記成:

sent = '我/nn 是/in 乙個/at 大/jj 傻x/nn'

[nltk.tag.str2tuple(t) for t in sent.split()]

如此一看,也是支援中文的

我們看看布朗語料庫中的標註:

nltk.corpus

.brown

.tagged_words()

step 1: 檢視這個中文語料庫中有什麼內容
# coding:utf-8

import nltk

forword

in nltk.corpus.sinica_treebank.tagged_words():

print(word[0], word[1])

第一列是中文的詞彙,第二列是標註好的詞性

我們發現這裡面都是繁體,因為是基於台灣的語料生成的,想要簡體中文還得自己想辦法。不過有人已經幫我們做了這部分工作,那就是jieba分詞,強烈推薦,可以自己載入自己的語料,進行中文切詞,並且能夠自動做詞性標註

面對一片新的語料庫(比如我們從未處理過中文,只有中文語料),怎麼實現詞性自動標註呢?

不管什麼詞,都標註為頻率最高的一種詞性。比如經過分析,所有中文語料裡的詞是名詞的概率是13%最大,那麼我們的預設標註器就全部標註為名詞。

這種標註器一般作為其他標註器處理之後的最後一道門,既不知道是什麼詞?那麼他是名詞。預設標註器用defaulttagger來實現:

# encoding:utf-8

import nltk

default_tagger = nltk.defaulttagger

('nn')

raw = '我 累 個 去'

tokens = nltk.word_tokenize(raw)

tags = default_tagger.tag(tokens)

print(tags)

正規表示式標註器:

滿足特定正規表示式的認為是某種詞性,比如凡是帶「們」的都認為是代詞(pro)。正規表示式標註器通regexptagge實現,用法如下:

pattern = [(r'.*們$', 'pro')]

tagger = nltk.regexptagger(pattern)

print(tagger.tag(nltk.word_tokenize('我們 累 個 去 你們 和 他們 啊')))

查詢標註器:

找出最頻繁的n個詞以及它的詞性,然後用這個資訊去查詢語料庫,匹配的就標記上,剩餘的詞使用預設標註器(回退)。這一般使用一元標註的方式,見下面。

一元標註:基於已經標註的語料庫做訓練,然後用訓練好的模型來標註新的語料,使用方法如下:

tagged_sents = [[(u'我', u'pro'), (u'小兔', u'nn')]]

unigram_tagger = nltk.unigramtagger(tagged_sents)

sents = brown.sents(categories='news')

sents = [[u'我', u'你', u'小兔']]

tags = unigram_tagger.tag(sents[0])

print(tags)

這裡的tagged_sents是用於訓練的語料庫,我們也可以直接用已有的標註好的語料庫,比如:

brown_tagged_sents = brown.tagged_sents(categories='news')
二元標註和多元標註:一元標註指的是只考慮當前這個詞,不考慮上下文。二元標註器指的是考慮它前面的詞的標註,用法只需要把上面的unigramtagger換成bigramtagger。同理三元標註換成trigramtagger

組合標註器:

為了提高精度和覆蓋率,我們對多種標註器組合,比如組合二元標註器、一元標註器和預設標註器,如下:

t0 = nltk.defaulttagger('nn')

t1 = nltk.unigramtagger(train_sents, backoff=t0)

t2 = nltk.bigramtagger(train_sents, backoff=t1)

標註器的儲存:

訓練好的標註器為了持久化,可以儲存到硬碟,具體方法如下:

from cpickle import dump

output = open('t2.pkl', 'wb')

dump(t2, output, -1)

output.close()

使用時載入

from cpickle import load

input = open('t2.pkl', 'rb')

tagger = load(input)

input.close()

奮戰聊天機械人(二)語料和詞彙資源

當代自然語言處理都是基於統計的,統計自然需要很多樣本,因此語料和詞彙資源是必不可少的 nltk包含多種語料庫,比如 gutenberg語料庫 nltk.corpus gutenberg fileids 類似的語料庫還有 語料庫的幾種組織結構 散養式 孤立的多篇文章 分類式 按照類別組織 相互之間沒有...

微信自動聊天機械人

背景 操作步驟 操作過程 import requests import itchat 圖靈機人人的apikey key d7b92b1df4ef4ba6a6c649200208f103 defget response msg 這個位址在此處給出,一看就懂 apiurl data的本質是乙個地點,要想...

自動化與機械人

曾經在知乎上看到這樣一篇文章,乙個俄羅斯程式設計師,生活在終端裡,只要任何事情花費時間超過了90秒,他一定會寫乙個指令碼自動化實現。比如工作日晚上九點之後這名程式設計師的運維伺服器中還有正在執行的ssh程序,就會給妻子發乙個今天加班的簡訊,並從文字庫中隨機選取一句加班理由。早上8點45分伺服器中依然...