用Python寫乙個簡單的中文分詞器

2021-09-24 20:05:49 字數 4626 閱讀 9468

作為乙個python初學者+自然語言處理初學者,我用python寫了乙個簡單的中文分詞器,整個程式 加上注釋100行左右,算是乙個小練習。

演算法是最簡單的正向最大匹配(fmm):

注:這是最初的演算法,這樣做**可以控制在60行內,後來看測試結果發現沒有很好地處理數字問題, 才又增加了對數字的處理。

#! /usr/bin/env python

# -*- coding: utf-8 -*-

# author: minix

# date: 2013-03-20

# email: [email protected]

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')']

defproc_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

defproc_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

defrules(line, start):

""" 處理特殊規則 """

if line[start] in nummath:

return proc_num_math(line, start)

elif line[start] in numcn:

return proc_num_cn(line, start)

defgendict(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:

iflen(item)>0 and item[0] in truedict:

value = truedict[item[0]]

truedict[item[0]] = value

else:

truedict[item[0]] = [item]

return truedict

defprint_unicode_list(uni_list):

for item in uni_list:

print item,

defdividewords(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

start = start + maxlen

return result

defmain():

args = sys.ar**[1:]

iflen(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()

注:整個測試過程都在ubuntu下完成

$ python dw.py pku_training.utf8 pku_test.utf8 pku_result.utf8

$ perl score pku_training.utf8 pku_test_gold.utf8 pku_result.utf8 > score.utf8

$ tail -14 score.utf8

=== summary:

=== total insertions: 4623

=== total deletions: 1740

=== total substitutions: 6650

=== total nchange: 13013

=== total true word count: 104372

=== total test word count: 107255

=== total true words recall: 0.920

=== total test words precision: 0.895

=== f measure: 0.907

=== oov rate: 0.940

=== oov recall rate: 0.917

=== iv recall rate: 0.966

基於詞典的fmm演算法是非常基礎的分詞演算法,效果沒那麼好,不過足夠簡單,也易於入手,隨著學習的深入,我可能還會用python實現其它的分詞演算法。另外乙個感受是,看書的時候盡量多去實現,這樣會讓你有足夠的熱情去關注理論的每乙個細節,不會感到那麼枯燥無力。

用python寫乙個簡單的視窗

import sys if name main 建立乙個視窗 w qwidget 設定視窗的尺寸 w.resize 400,200 移動視窗 w.move 300,300 設定視窗的標題 w.setwindowtitle 第乙個基於pyqt5的桌面應用 顯示視窗 w.show 進入程式的主迴圈 並通...

ROS 用Python寫乙個簡單服務

一.編寫服務資料 在功能包的頂級目錄中,建立srv資料夾,並在裡面建立.srv檔案 先成為a.srv 在srv檔案中,填入服務資料,如 int64 a int64 b int64 sum其中,上方是請求資料,下方是答應資料 二.修改cmakelist和package.xml cmakelist ca...

用python寫乙個簡單的彈球遊戲

用python寫乙個簡單的彈球遊戲,可以使用球拍接住球讓球在邊框內不停的彈動,如果球拍沒有接住則遊戲結束 我們需要匯入tkinter模組來建立畫布 匯入時間模組來控制球的速度,就是控制球移動的間隔時間 匯入隨機模組使球彈的方向是隨機的。fromtkinterimport importtime imp...