本節(jié)將介紹在自然語言處理分詞或序列標(biāo)注過程中應(yīng)用較廣泛的CRF條件隨機(jī)場模型利朵。
CRF算法是2001年提出律想,結(jié)合了最大熵模型和隱馬爾科夫模型,是一個(gè)典型的判別式模型哗咆。近年來在分詞蜘欲、詞性標(biāo)注和命名實(shí)體識(shí)別等序列標(biāo)注任務(wù)中取得了很好的效果益眉。其基本思路是把分詞轉(zhuǎn)換為分類問題晌柬,通過給漢字打標(biāo)簽實(shí)現(xiàn)分詞,不僅考慮文字詞語出現(xiàn)的頻率郭脂,同時(shí)考慮上下文語境年碘,對(duì)歧異詞和未登錄詞的識(shí)別效果較好,此外展鸡,對(duì)所有特征進(jìn)行全局歸一化屿衅,進(jìn)而求得全局最優(yōu)值。但是訓(xùn)練周期較長莹弊,計(jì)算量大涤久,性能不如詞典統(tǒng)計(jì)分詞。本文使用開源的條件隨機(jī)場工具包“CRF++:Yet Another CRF toolkit”實(shí)現(xiàn)中文分詞忍弛,選用的訓(xùn)練語料是微軟亞洲研究院提供的中文分詞語料(如下圖所示)响迂,測(cè)試語料來自backoff2005測(cè)試腳本。
CRF分詞原理:
1细疚、訓(xùn)練語料預(yù)處理蔗彤。原始訓(xùn)練語料是已經(jīng)分好詞的預(yù)料,詞與詞之間通過空格隔開疯兼。按照如下定義字對(duì)數(shù)據(jù)進(jìn)行格式化:①詞首——用B表示 ②詞中——用M表示 ③詞尾——用E表示 ④單子詞——用S表示然遏。數(shù)據(jù)格式化腳本如下:
import codecs
import sys
def character_tagging(input_file, output_file):
#這里的codecs庫保證了輸入文件為utf-8格式,輸出也為utf-8格式
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:
#注意這里的“\tS\n”一定不能漏寫吧彪,這是設(shè)置處理之后的數(shù)據(jù)的格式的重要部分
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 ####.py input output"
sys.exit(-1)
#這里的sys.argv[]是參數(shù)待侵,需要在liunx環(huán)境下運(yùn)行Python腳本時(shí),輸入的兩個(gè)參數(shù):輸入文件位置姨裸,輸出文件位置
input_file = sys.argv[1]
output_file = sys.argv[2]
character_tagging(input_file, output_file)
格式化之后的數(shù)據(jù)如圖所示:假設(shè)格式化后的文件為training_tag.utf8
2秧倾、訓(xùn)練模型。用格式化后的訓(xùn)練語料training_tag.utf8訓(xùn)練CRF模型啦扬。主要利用CRF工具中的crf_learn訓(xùn)練模型中狂,執(zhí)行如下命令:crf_learn -f 3 -c 4.0 template training_tag.utf8 crf_model。其中扑毡,crf_model即為訓(xùn)練過后的模型胃榕。
3、測(cè)試語料格式化。原始的測(cè)試語料是一個(gè)純文本文件勋又,沒有任何處理苦掘,如圖a所示。需要將其處理成CRF要求的輸入格式楔壤,處理腳本如下所示鹤啡。
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 ####.py input output"
sys.exit()
input_file = sys.argv[1]
output_file = sys.argv[2]
character_split(input_file, output_file)
格式化之后的數(shù)據(jù)如圖所示:假設(shè)格式化后的文件為test_format.utf8
4、測(cè)試模型蹲嚣。用格式化后的測(cè)試語料test_format.utf8測(cè)試CRF模型递瑰。主要利用CRF工具中的crf_test測(cè)試模型,執(zhí)行如下命令:crf_test -m crf_model test_format.utf8>test_tag.utf8 隙畜。其中抖部,crf_model即為訓(xùn)練過后的模型,test_format.utf8即為格式化后的測(cè)試文件,test_tag.utf8即為模型的標(biāo)注結(jié)果议惰。
5慎颗、分詞結(jié)果顯示。按照定義的分詞格式言询,將標(biāo)記結(jié)果轉(zhuǎn)換為分詞結(jié)果俯萎,即將B和E之間的字,以及S單字構(gòu)成分詞运杭。腳本如下:
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 ####.py input output"
sys.exit()
input_file = sys.argv[1]
output_file = sys.argv[2]
character_2_word(input_file, output_file)
得到分詞結(jié)果文件test_result.utf8夫啊,樣式如圖所示
6、分詞結(jié)果測(cè)試县习。利用backoff2005測(cè)試樣本對(duì)分詞結(jié)果test_result.utf8進(jìn)行測(cè)試涮母。
執(zhí)行./icwb2-data/scripts/score ./icwb2-data/gold/pku_training_words.utf8 ./icwb2-data/gold/pku_test_gold.utf8 test_result.utf8 > test_result.score
此處,pku_training_words.utf8 和pku_test_gold.utf8是測(cè)試文件中自帶的躁愿,test_result.utf8即為上步生成的文件叛本。test_result.score即為最后模型的評(píng)分。
上述步驟均可以復(fù)現(xiàn)彤钟,具體細(xì)節(jié)參考www.52nlp.cn/中文分詞入門之字標(biāo)注法4