小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

中文分詞入門之字標(biāo)注法4 – 我愛自然語言處理

 Clay*more 2022-08-05 發(fā)布于北京

https://www./%E4%B8%AD%E6%96%87%E5%88%86%E8%AF%8D%E5%85%A5%E9%97%A8%E4%B9%8B%E5%AD%97%E6%A0%87%E6%B3%A8%E6%B3%954#

上一節(jié)主要介紹的是利用最大熵工具包來做字標(biāo)注中文分詞,這一節(jié)我們直奔主題,借用條件隨機場工具“CRF++: Yet Another CRF toolkit”來完成字標(biāo)注中文分詞的全過程。

關(guān)于條件隨機場(CRF)的背景知識,推薦參考閱讀一些經(jīng)典的文獻:《條件隨機場文獻閱讀指南》,另外再額外推薦一個tutorial:《Classical Probabilistic Models and Conditional Random Fields》, 這份關(guān)于CRF的文檔分別從概率模型(NB,HMM,ME, CRF)之間的關(guān)系以及概率圖模型背景來介紹條件隨機場,比較清晰:

While a Hidden Markov Model is a sequential extension to the Nave Bayes Model, Conditional Random Fields can be understood as a sequential extension to the Maximum Entropy Model.

如果這些還不夠過癮,推薦課程圖譜上收錄的Coursera創(chuàng)始人之一Daphne Koller的概率圖模型公開課,相信拿下這門課之后,對于上述概率模型,會有一種“一覽眾山小”的感覺。

不過我們還是要從安裝CRF++工具包說起,在Linux或者Mac OS系統(tǒng)下,下載C++源代碼安裝包(這里用的是 CRF++-0.58.tar.gz )之后,依然是 “configure & make & (sudo) make install",安裝完畢之后,可以cd python進入到其同樣用SWIG生成的Python工具包下,安裝python包:python setup.py build & (sudo) python setup.py install。安裝完畢之后,可以在python解釋器下測試,是否能成功import CRFPP,如果ok,則準(zhǔn)備工作就緒。

上一節(jié)我們利用最大熵模型工具包里自帶的詞性標(biāo)注工具進行的中文分詞,稍微有些曲折,這一節(jié)我們依然利用CRF++ example里的樣例進行測試,不過好處是,CRF++ example里有個seg目錄,這個seg目錄對應(yīng)的是一個日文分詞的樣例,正好可以套用到我們的中文分詞中來。在安裝包目錄下,cd example, cd seg目錄后,有4個文件:

exec.sh(執(zhí)行腳本)
template(特征模板)
test.data(測試集)
train.data(訓(xùn)練集)

有了這4個文件,我們可以做得事情就比較簡單,只要按測試集,訓(xùn)練集的格式準(zhǔn)備數(shù)據(jù)就可以了,特征模板和執(zhí)行腳本可以套用,不過這里簡單解讀一下這幾個CRF++文件。首先來看訓(xùn)練集:

毎 k B
日 k I
新 k I
聞 k I
社 k I
特 k B
別 k I
顧 k B
問 k I
4 n B

這里第一列是待分詞的日文字,第二列暫且認(rèn)為其是詞性標(biāo)記,第三列是字標(biāo)注中的2-tag(B, I)標(biāo)記,這個很重要,對于我們需要準(zhǔn)備的訓(xùn)練集,主要是把這一列的標(biāo)記做好,不過需要注意的是,其斷句是靠空行來完成的。

再來看測試集的格式:

よ h I
っ h I
て h I
私 k B
た h B
ち h I
の h B
世 k B
代 k I
が h B

同樣也有3列,第一列是日文字,第二列第三列與上面是相似的,不過在測試集里第三列主要是占位作用。事實上,CRF++對于訓(xùn)練集和測試集文件格式的要求是比較靈活的,首先需要多列,但不能不一致,既在一個文件里有的行是兩列,有的行是三列;其次第一列代表的是需要標(biāo)注的“字或詞”,最后一列是輸出位"標(biāo)記tag",如果有額外的特征,例如詞性什么的,可以加到中間列里,所以訓(xùn)練集或者測試集的文件最少要有兩列。

接下里我們再來詳細的分析一下特征模板文件:

# Unigram
U00:%x[-2,0]
U01:%x[-1,0]
U02:%x[0,0]
U03:%x[1,0]
U04:%x[2,0]
U05:%x[-2,0]/%x[-1,0]/%x[0,0]
U06:%x[-1,0]/%x[0,0]/%x[1,0]
U07:%x[0,0]/%x[1,0]/%x[2,0]
U08:%x[-1,0]/%x[0,0]
U09:%x[0,0]/%x[1,0]

# Bigram
B

關(guān)于CRF++中特征模板的說明和舉例,請大家參考官方文檔上的“Preparing feature templates”這一節(jié),而以下部分的說明拿上述日文分詞數(shù)據(jù)舉例。在特征模板文件中,每一行(如U00:%x[-2,0])代表一個特征,而宏“%x[行位置,列位置]”則代表了相對于當(dāng)前指向的token的行偏移和列的絕對位置,以上述訓(xùn)練集為例,如果當(dāng)前掃描到“新 k I”這一行,

毎 k B
日 k I
新 k I <== 掃描到這一行,代表當(dāng)前位置 聞 k I 社 k I 特 k B 別 k I 顧 k B 問 k I 4 n B

那么依據(jù)特征模板文件抽取的特征如下:

# Unigram
U00:%x[-2,0] ==> 毎
U01:%x[-1,0] ==> 日
U02:%x[0,0] ==> 新
U03:%x[1,0] ==> 聞
U04:%x[2,0] ==> 社
U05:%x[-2,0]/%x[-1,0]/%x[0,0] ==> 每/日/新
U06:%x[-1,0]/%x[0,0]/%x[1,0] ==> 日/新/聞
U07:%x[0,0]/%x[1,0]/%x[2,0] ==> 新/聞/社
U08:%x[-1,0]/%x[0,0] ==> 日/新
U09:%x[0,0]/%x[1,0] ==> 新/聞

# Bigram
B

CRF++里將特征分成兩種類型,一種是Unigram的,“U”起頭,另外一種是Bigram的,“B”起頭。對于Unigram的特征,假如一個特征模板是"U01:%x[-1,0]", CRF++會自動的生成一組特征函數(shù)(func1 ... funcN) 集合:

func1 = if (output = B and feature="U01:日") return 1 else return 0
func2 = if (output = I and feature="U01:日") return 1 else return 0
....
funcXX = if (output = B and feature="U01:問") return 1 else return 0
funcXY = if (output = I and feature="U01:問") return 1 else return 0

生成的特征函數(shù)的數(shù)目 = (L * N),其中L是輸出的類型的個數(shù),這里是B,I這兩個tag,N是通過模板擴展出來的所有單個字符串(特征)的個數(shù),這里指的是在掃描所有訓(xùn)練集的過程中找到的日文字(特征)。

而Bigram特征主要是當(dāng)前的token和前面一個位置token的自動組合生成的bigram特征集合。最后需要注意的是U01和U02這些標(biāo)志位,與特征token組合到一起主要是區(qū)分“U01:問”和“U02:問”這類特征,雖然抽取的日文"字"特征是一樣的,但是在CRF++中這是有區(qū)別的特征。

最后我們再來看一下執(zhí)行腳本:

#!/bin/sh
../../crf_learn -f 3 -c 4.0 template train.data model
../../crf_test -m model test.data

../../crf_learn -a MIRA -f 3 template train.data model
../../crf_test -m model test.data
rm -f model

執(zhí)行腳本告訴了我們?nèi)绾斡?xùn)練一個CRF模型,以及如何利用這個模型來進行測試,執(zhí)行這個腳本之后,對于輸入的測試集,輸出結(jié)果多了一列:

よ h I B
っ h I I
て h I B
私 k B B
た h B B
ち h I I
の h B B
世 k B B
代 k I I
が h B B

而這一列才是模型預(yù)測的改字的標(biāo)記tag,也正是我們所需要的結(jié)果。到此為止,關(guān)于日文分詞樣例的介紹已經(jīng)完畢,讀者應(yīng)該可以猜測到接下來我們會如何做中文分詞吧?

和上一節(jié)利用最大熵模型進行中文分詞相似,第一步仍然是將backoff2005里的訓(xùn)練數(shù)據(jù)轉(zhuǎn)化為CRF++所需的訓(xùn)練數(shù)據(jù)格式,還是以微軟亞洲研究院提供的中文分詞語料為例,依然采用4-tag(B(Begin,詞首), E(End,詞尾), M(Middle,詞中), S(Single,單字詞))標(biāo)記集,只處理utf-8編碼文本。原始訓(xùn)練集./icwb2-data/training/msr_training.utf8的形式是人工分好詞的中文句子形式,如:

“ 人們 常 說 生活 是 一 部 教科書 , 而 血 與 火 的 戰(zhàn)爭 > 更 是 不可多得 的 教科書 , 她 確實 是 名副其實 的 ' 我 的 > 大學(xué) ’ 。
“ 心 靜 漸 知 春 似 海 , 花 深 每 覺 影 生 香 。
“ 吃 屎 的 東西 , 連 一 捆 麥 也 鍘 不 動 呀 ?
他 “ 嚴(yán)格要求 自己 , 從 一個 科舉 出身 的 進士 成為 一個 偉> 大 的 民主主義 者 , 進而 成為 一 位 杰出 的 黨外 共產(chǎn)主義 戰(zhàn) 士 , 獻身 于 崇高 的 共產(chǎn)主義 事業(yè) 。
“ 征 而 未 用 的 耕地 和 有 收益 的 土地 , 不準(zhǔn) 荒蕪 。
“ 這 首先 是 個 民族 問題 , 民族 的 感情 問題 。
’ 我 扔 了 兩顆 手榴彈 , 他 一下子 出 溜 下去 。
“ 廢除 先前 存在 的 所有制 關(guān)系 , 并不是 共產(chǎn)主義 所 獨具 的 特征 。
“ 這個 案子 從 始 至今 我們 都 沒有 跟 法官 接觸 過 , 也 > 沒有 跟 原告 、 被告 接觸 過 。
“ 你 只有 把 事情 做好 , 大伙 才 服 你 。

這里同樣提供一個腳本 make_crf_train_data.py,將這個訓(xùn)練語料轉(zhuǎn)換為CRF++訓(xùn)練用的語料格式(2列,4-tag):

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: 52nlpcn@gmail.com
# Copyright 2014 @ YuZhen Technology
#
# 4 tags for character tagging: B(Begin), E(End), M(Middle), S(Single)

import codecs
import sys

def character_tagging(input_file, output_file):
input_data = codecs.open(input_file, 'r', 'utf-8')
output_data = codecs.open(output_file, 'w', 'utf-8')
for line in input_data.readlines():
word_list = line.strip().split()
for word in word_list:
if len(word) == 1:
output_data.write(word + "\tS\n")
else:
output_data.write(word[0] + "\tB\n")
for w in word[1:len(word)-1]:
output_data.write(w + "\tM\n")
output_data.write(word[len(word)-1] + "\tE\n")
output_data.write("\n")
input_data.close()
output_data.close()

if __name__ == '__main__':
if len(sys.argv) != 3:
print "pls use: python make_crf_train_data.py input output"
sys.exit()
input_file = sys.argv[1]
output_file = sys.argv[2]
character_tagging(input_file, output_file)

只需要執(zhí)行“python make_crf_train_data.py ./icwb2-data/training/msr_training.utf8 msr_training.tagging4crf.utf8” 即可得到CRF++要求的格式的訓(xùn)練文件msr_training.tagging4crf.utf8,樣例如下:

“ S
人 B
們 E
常 S
說 S
生 B
活 E
是 S
一 S
部 S
...

有了這份訓(xùn)練語料,就可以利用crf的訓(xùn)練工具crf_learn來訓(xùn)練模型了,執(zhí)行如下命令即可:

crf_learn -f 3 -c 4.0 template msr_training.tagging4crf.utf8 crf_model

這次訓(xùn)練的時間稍微有些長,在我的4G內(nèi)存的mac pro上跑了將近700輪,大約2個小時,最終訓(xùn)練的crf_model約51M。有了模型,現(xiàn)在我們需要做得還是準(zhǔn)備一份CRF++用的測試語料,然后利用CRF++的測試工具crf_test進行字標(biāo)注。原始的測試語料是icwb2-data/testing/msr_test.utf8 ,樣例如下:

揚帆遠東做與中國合作的先行
希臘的經(jīng)濟結(jié)構(gòu)較特殊。
海運業(yè)雄踞全球之首,按噸位計占世界總數(shù)的17%。
另外旅游、僑匯也是經(jīng)濟收入的重要組成部分,制造業(yè)規(guī)模相對較小。
多年來,中希貿(mào)易始終處于較低的水平,希臘幾乎沒有在中國投資。
十幾年來,改革開放的中國經(jīng)濟高速發(fā)展,遠東在崛起。
瓦西里斯的船只中有40%駛向遠東,每個月幾乎都有兩三條船停靠中國港口。
他感受到了中國經(jīng)濟發(fā)展的大潮。
他要與中國人合作。
他來到中國,成為第一個訪華的大船主。

這里我們同樣提供一個python腳本 make_crf_test_data.py 對測試語料進行處理,將其轉(zhuǎn)換為CRF++要求的格式(2列,B作為最后一列的占位符)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: 52nlpcn@gmail.com
# Copyright 2014 @ YuZhen Technology
#
# 4 tags for character tagging: B(Begin), E(End), M(Middle), S(Single)

import codecs
import sys

def character_split(input_file, output_file):
input_data = codecs.open(input_file, 'r', 'utf-8')
output_data = codecs.open(output_file, 'w', 'utf-8')
for line in input_data.readlines():
for word in line.strip():
word = word.strip()
if word:
output_data.write(word + "\tB\n")
output_data.write("\n")
input_data.close()
output_data.close()

if __name__ == '__main__':
if len(sys.argv) != 3:
print "pls use: python make_crf_test_data.py input output"
sys.exit()
input_file = sys.argv[1]
output_file = sys.argv[2]
character_split(input_file, output_file)

執(zhí)行“python make_crf_test_data.py ./icwb2-data/testing/msr_test.utf8 msr_test4crf.utf8”即可得到可用于CRF++測試的測試語料msr_test4crf.utf8,樣例如下:

揚 B
帆 B
遠 B
東 B
做 B
與 B
中 B
國 B
合 B
作 B
...

現(xiàn)在執(zhí)行crf_test即可得到字標(biāo)注結(jié)果:

crf_test -m crf_model msr_test4crf.utf8 > msr_test4crf.tag.utf8

msr_test4crf.tag.utf8即是標(biāo)注結(jié)果,樣例如下:

揚 B B
帆 B E
遠 B B
東 B E
做 B S
與 B S
中 B B
國 B E
合 B B
作 B E
...

最后我們還需要一個腳本,按標(biāo)注的詞位信息講這份結(jié)果再轉(zhuǎn)化為分詞結(jié)果,這里我們?nèi)匀惶峁┮粋€轉(zhuǎn)換腳本 crf_data_2_word.py :

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: 52nlpcn@gmail.com
# Copyright 2014 @ YuZhen Technology
#
# 4 tags for character tagging: B(Begin), E(End), M(Middle), S(Single)

import codecs
import sys

def character_2_word(input_file, output_file):
input_data = codecs.open(input_file, 'r', 'utf-8')
output_data = codecs.open(output_file, 'w', 'utf-8')
for line in input_data.readlines():
if line == "\n":
output_data.write("\n")
else:
char_tag_pair = line.strip().split('\t')
char = char_tag_pair[0]
tag = char_tag_pair[2]
if tag == 'B':
output_data.write(' ' + char)
elif tag == 'M':
output_data.write(char)
elif tag == 'E':
output_data.write(char + ' ')
else: # tag == 'S'
output_data.write(' ' + char + ' ')
input_data.close()
output_data.close()

if __name__ == '__main__':
if len(sys.argv) != 3:
print "pls use: python crf_data_2_word.py input output"
sys.exit()
input_file = sys.argv[1]
output_file = sys.argv[2]
character_2_word(input_file, output_file)

只需執(zhí)行“python crf_data_2_word.py msr_test4crf.tag.utf8 msr_test4crf.tag2word.utf8” 即可得到合并后的分詞結(jié)果文件 msr_test4crf.tag2word.utf8,樣例如下:

揚帆 遠東 做 與 中國 合作 的 先行
希臘 的 經(jīng)濟 結(jié)構(gòu) 較 特殊 。
海運 業(yè) 雄踞 全球 之 首 , 按 噸 位 計 占 世界 總數(shù) 的 17% 。
另外 旅游 、 僑匯 也是 經(jīng)濟 收入 的 重要 組成部分 , 制造業(yè) 規(guī)模 相對 較小 。
多年來 , 中 希 貿(mào)易 始終 處于 較低 的 水平 , 希臘 幾乎 沒有 在 中國 投資 。
十幾年 來 , 改革開放 的 中國 經(jīng)濟 高速 發(fā)展 , 遠東 在 崛起 。
瓦西里斯 的 船只 中 有 40% 駛 向 遠東 , 每個 月 幾乎 都 有 兩三條 船 停靠 中國 港口 。
他 感受 到 了 中國 經(jīng)濟 發(fā)展 的 大潮 。
他 要 與 中國人 合作 。
他 來到 中國 , 成為 第一個 訪 華 的 大船 主 。
...

有了這個CRF字標(biāo)注分詞結(jié)果,我們就可以利用backoff2005的測試腳本來測一下這次分詞的效果了:

./icwb2-data/scripts/score ./icwb2-data/gold/msr_training_words.utf8 ./icwb2-data/gold/msr_test_gold.utf8 msr_test4crf.tag2word.utf8 > msr_crf_segment.score

結(jié)果如下:

=== SUMMARY:
=== TOTAL INSERTIONS: 1412
=== TOTAL DELETIONS: 1305
=== TOTAL SUBSTITUTIONS: 2449
=== TOTAL NCHANGE: 5166
=== TOTAL TRUE WORD COUNT: 106873
=== TOTAL TEST WORD COUNT: 106980
=== TOTAL TRUE WORDS RECALL: 0.965
=== TOTAL TEST WORDS PRECISION: 0.964
=== F MEASURE: 0.964
=== OOV Rate: 0.026
=== OOV Recall Rate: 0.647
=== IV Recall Rate: 0.974
### msr_test4crf.tag2word.utf8 1412 1305 2449 5166 106873 106980 0.965 0.964 0.964 0.026 0.647 0.974

這次我們獲得了一個準(zhǔn)確率,召回率以及F值都在96%以上的結(jié)果,相對于前面幾節(jié)的測試結(jié)果,這個CRF字標(biāo)注分詞結(jié)果還相對不錯。不過是不是感覺上面的步驟有些繁瑣,有沒有一次到位的CRF分詞器,這里我們同樣提供一個CRF分詞腳本 crf_segmenter.py ,利用CRF++的python工具包,做到一次輸入,一次輸出:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: 52nlpcn@gmail.com
# Copyright 2014 @ YuZhen Technology
#
# CRF Segmenter based character tagging:
# 4 tags for character tagging: B(Begin), E(End), M(Middle), S(Single)

import codecs
import sys

import CRFPP

def crf_segmenter(input_file, output_file, tagger):
input_data = codecs.open(input_file, 'r', 'utf-8')
output_data = codecs.open(output_file, 'w', 'utf-8')
for line in input_data.readlines():
tagger.clear()
for word in line.strip():
word = word.strip()
if word:
tagger.add((word + "\to\tB").encode('utf-8'))
tagger.parse()
size = tagger.size()
xsize = tagger.xsize()
for i in range(0, size):
for j in range(0, xsize):
char = tagger.x(i, j).decode('utf-8')
tag = tagger.y2(i)
if tag == 'B':
output_data.write(' ' + char)
elif tag == 'M':
output_data.write(char)
elif tag == 'E':
output_data.write(char + ' ')
else: # tag == 'S'
output_data.write(' ' + char + ' ')
output_data.write('\n')
input_data.close()
output_data.close()

if __name__ == '__main__':
if len(sys.argv) != 4:
print "pls use: python crf_segmenter.py model input output"
sys.exit()
crf_model = sys.argv[1]
input_file = sys.argv[2]
output_file = sys.argv[3]
tagger = CRFPP.Tagger("-m " + crf_model)
crf_segmenter(input_file, output_file, tagger)

只需執(zhí)行“python crf_segmenter.py crf_model ./icwb2-data/testing/msr_test.utf8 msr_test.seg.utf8”即可得到與前面幾步得到的分詞結(jié)果完全一致的CRF分詞結(jié)果:msr_test.seg.utf8 。

好了,到此為止,關(guān)于字標(biāo)注中文分詞的系列終于可以畫上句號了,這個系列中所舉的例子以及所提供的腳本都是toy級別的中文分詞工具,距離一個真正實用的中文分詞器還有很多路要走,不過既然路已經(jīng)打開,歡迎大家和我們一起繼續(xù)探索中文分詞的奧秘。

注:原創(chuàng)文章,轉(zhuǎn)載請注明出處“我愛自然語言處理”:www.

本文鏈接地址:https://www./中文分詞入門之字標(biāo)注法4

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多