Entnehmen Sie nach dem Entpacken die folgenden Dateien:
Trainingsdaten: icwb2-data/training/pku_training.utf8
Testdaten: icwb2-data/testing/pku_test.utf8
Korrektes Wortsegmentierungsergebnis: icwb2-data/gold/pku_ test_ gold.utf8
Bewertungstool: icwb2-data/script/socre
2 Algorithmusbeschreibung
Algorithmus Es handelt sich um das einfachste Vorwärts-Maximum-Matching (FMM):
Erzeugen Sie ein Wörterbuch mithilfe der Trainingsdaten.
Scannen Sie die Testdaten von links nach rechts und segmentieren Sie sie, wenn Sie auf die längste Zeit stoßen Wort. Bis zum Ende des Satzes
Hinweis: Dies ist der ursprüngliche Algorithmus. Auf diese Weise kann der Code innerhalb von 60 Zeilen gesteuert werden Das Nummernproblem wurde nicht gut gelöst, daher wurde die Nummernverarbeitung hinzugefügt.
3 Quellcode und Kommentare
#! /usr/bin/env python # -*- coding: utf-8 -*- # Author: minix # Date: 2013-03-20 import codecs import sys # 由规则处理的一些特殊符号 numMath = [u'0', u'1', u'2', u'3', u'4', u'5', u'6', u'7', u'8', u'9'] numMath_suffix = [u'.', u'%', u'亿', u'万', u'千', u'百', u'十', u'个'] numCn = [u'一', u'二', u'三', u'四', u'五', u'六', u'七', u'八', u'九', u'〇', u'零'] numCn_suffix_date = [u'年', u'月', u'日'] numCn_suffix_unit = [u'亿', u'万', u'千', u'百', u'十', u'个'] special_char = [u'(', u')'] def proc_num_math(line, start): """ 处理句子中出现的数学符号 """ oldstart = start while line[start] in numMath or line[start] in numMath_suffix: start = start + 1 if line[start] in numCn_suffix_date: start = start + 1 return start - oldstart def proc_num_cn(line, start): """ 处理句子中出现的中文数字 """ oldstart = start while line[start] in numCn or line[start] in numCn_suffix_unit: start = start + 1 if line[start] in numCn_suffix_date: start = start + 1 return start - oldstart def rules(line, start): """ 处理特殊规则 """ if line[start] in numMath: return proc_num_math(line, start) elif line[start] in numCn: return proc_num_cn(line, start) def genDict(path): """ 获取词典 """ f = codecs.open(path,'r','utf-8') contents = f.read() contents = contents.replace(u'\r', u'') contents = contents.replace(u'\n', u'') # 将文件内容按空格分开 mydict = contents.split(u' ') # 去除词典List中的重复 newdict = list(set(mydict)) newdict.remove(u'') # 建立词典 # key为词首字,value为以此字开始的词构成的List truedict = {} for item in newdict: if len(item)>0 and item[0] in truedict: value = truedict[item[0]] value.append(item) truedict[item[0]] = value else: truedict[item[0]] = [item] return truedict def print_unicode_list(uni_list): for item in uni_list: print item, def divideWords(mydict, sentence): """ 根据词典对句子进行分词, 使用正向匹配的算法,从左到右扫描,遇到最长的词, 就将它切下来,直到句子被分割完闭 """ ruleChar = [] ruleChar.extend(numCn) ruleChar.extend(numMath) result = [] start = 0 senlen = len(sentence) while start < senlen: curword = sentence[start] maxlen = 1 # 首先查看是否可以匹配特殊规则 if curword in numCn or curword in numMath: maxlen = rules(sentence, start) # 寻找以当前字开头的最长词 if curword in mydict: words = mydict[curword] for item in words: itemlen = len(item) if sentence[start:start+itemlen] == item and itemlen > maxlen: maxlen = itemlen result.append(sentence[start:start+maxlen]) start = start + maxlen return result def main(): args = sys.argv[1:] if len(args) < 3: print 'Usage: python dw.py dict_path test_path result_path' exit(-1) dict_path = args[0] test_path = args[1] result_path = args[2] dicts = genDict(dict_path) fr = codecs.open(test_path,'r','utf-8') test = fr.read() result = divideWords(dicts,test) fr.close() fw = codecs.open(result_path,'w','utf-8') for item in result: fw.write(item + ' ') fw.close() if __name__ == "__main__": main()
4 Test- und Bewertungsergebnisse
Verwenden Sie dw.py-Trainingsdaten, um die Daten zu testen und die Ergebnisdatei zu generieren
Verwenden Sie die Bewertung, um basierend auf den Trainingsdaten, den Ergebnissen der korrekten Wortsegmentierung und den von uns generierten Ergebnissen zu bewerten.
Verwenden Sie tail, um zusätzlich die Gesamtbewertung der letzten paar Zeilen der Ergebnisdatei anzuzeigen , socre.utf8 bietet auch eine große Anzahl von Vergleichsergebnissen. Es kann verwendet werden, um herauszufinden, wo Ihre eigenen Wortsegmentierungsergebnisse nicht gut genug sind
Hinweis: Der gesamte Testprozess wird unter Ubuntu abgeschlossen
$ python dw.py pku_training.utf8 pku_test.utf8 pku_result.utf8
$ perlScore pku_training.utf8 pku_test_gold.utf8 pku_result.utf8 >Score.utf8
$ Tail -22 Score.utf8
EINFÜGEN: 0
LÖSCHUNGEN: 0
ERSATZE: 0
NVERÄNDERUNG: 0
NUTRUTH: 27
NTEST: 27
WÄHRENDE WÖRTER ERINNERN: 1.000
PRÄZISION DER TESTWÖRTER: 1.000
=== ZUSAMMENFASSUNG:
=== EINFÜGUNGEN INSGESAMT: 4623
=== LÖSCHUNGEN INSGESAMT: 1740
=== ERSETZUNGEN INSGESAMT: 6650
=== NÄNDERUNGEN INSGESAMT: 13013
=== INSGESAMT WAHR WORTANZAHL: 104372
=== GESAMTZAHL DER TESTWÖRTER: 107255
=== GESAMTZAHL DER ECHTEN WÖRTER: 0,920
=== GESAMTZAHL DER TESTWÖRTER: 0,895
=== F-MESSUNG: 0,907
=== OOV-Rate: 0,940
=== OOV-Rückrufrate: 0,917
=== IV-Rückruf Rate: 0,966
Der wörterbuchbasierte FMM-Algorithmus ist ein sehr einfacher Wortsegmentierungsalgorithmus. Der Effekt ist nicht so gut, aber er ist einfach genug und leicht zu verwenden Wenn ich das Studium vertiefe, kann ich Python auch verwenden, um andere Wortsegmentierungsalgorithmen zu implementieren. Ein anderes Gefühl ist, dass Sie beim Lesen eines Buches versuchen, es so weit wie möglich zu verwirklichen. Dies wird Ihnen genug Begeisterung geben, um jedem Detail der Theorie Aufmerksamkeit zu schenken, und Sie werden sich nicht so langweilig und machtlos fühlen.