1. 程式人生 > >中文分詞演算法之最大正向匹配演算法(Python版)

中文分詞演算法之最大正向匹配演算法(Python版)

最大匹配演算法是自然語言處理中的中文匹配演算法中最基礎的演算法,分為正向和逆向,原理都是一樣的。

正向最大匹配演算法,故名思意,從左向右掃描尋找詞的最大匹配。

首先我們可以規定一個詞的最大長度,每次掃描的時候尋找當前開始的這個長度的詞來和字典中的詞匹配,如果沒有找到,就縮短長度繼續尋找,直到找到或者成為單字。

例項:

S1="計算語言學課程是三個課時" ,設定最大詞長MaxLen = 5  ,S2= " "

字典中含有三個詞:[計算語言學]、[課程]、[課時]

(1)S2="";S1不為空,從S1左邊取出候選子串W="計算語言學";
(2)查詞表,“計算語言學”在詞表中,將W加入到S2中,S2=“計算語言學/  ”,        並將W從S1中去掉,此時S1="課程是三個課時";
(3)S1不為空,於是從S1左邊取出候選子串W="課程是三個";
(4)查詞表,W不在詞表中,將W最右邊一個字去掉,得到W="課程是三";
(5)查詞表,W不在詞表中,將W最右邊一個字去掉,得到W="課程是";
(6)查詞表,W不在詞表中,將W最右邊一個字去掉,得到W="課程"
(7)查詞表,W在詞表中,將W加入到S2中,S2=“計算語言學/  課程/  ”,並        將W從S1中去掉,此時S1="是三個課時";

(8)S1不為空,於是從S1左邊取出候選子串W="是三個課時";
(9)查詞表,W不在詞表中,將W最右邊一個字去掉,得到W="是三個課";
(10)查詞表,W不在詞表中,將W最右邊一個字去掉,得到W="是三個";
(11)查詞表,W不在詞表中,將W最右邊一個字去掉,得到W="是三"
(12)查詞表,W不在詞表中,將W最右邊一個字去掉,得到W=“是”,這時     W是單字,將W加入到S2中,S2=“計算語言學/  課程/  是/  ”,並將     W從S1中去掉,此時S1="三個課時";
(13)S1不為空,從S1左邊取出候選子串W="三個課時";
(14)查詞表,W不在詞表中,將W最右邊一個字去掉,得到W="三個課";
(15)查詞表,W不在詞表中,將W最右邊一個字去掉,得到W="三個";
(16)查詞表,W不在詞表中,將W最右邊一個字去掉,得到W=“三”,這時     W是單字,將W加入到S2中,S2=“計算語言學/  課程/  是/  三/  ”,並    將W從S1中去掉,此時S1="個課時";

(17)S1不為空,從S1左邊取出候選子串W="個課時";
(18)查詞表,W不在詞表中,將W最右邊一個字去掉,得到W="個課";
(19)查詞表,W不在詞表中,將W最右邊一個字去掉,得到W=“個”,     這時W是單字,將W加入到S2中,S2=“計算語言學/  課程/  是/       三/  個/  ",並將W從S1中去掉,此時S1="課時";
(20)S1不為空,從S1左邊取出候選子串W="課時";
(21)查詞表,W在詞表中,將W加入到S2中,S2=“計算語言學/  課程/       是/  三/  個/  課時/  ",並將W從S1中去掉,此時S1=""。
(22)S1為空,輸出S2作為分詞結果,分詞過程結束。

中文分詞演算法的Python實現:

指令碼接受兩個引數,一個是輸入檔案的路徑,另一個是詞典的路徑。

它的執行方法如下:

python max-match.py <data> <dict>
#!/usr/bin/env python
import cPickle as pickle
import sys

window_size=5

def max_match_segment(line, dic):
    # write your code here
    chars = line.decode("utf8")
    words = []
    idx = 0
    while idx < len(chars):
        matched = False
        for i in xrange(window_size, 0, -1):
            cand=chars[idx:idx+i].encode("utf8")
            if cand in dic:
                words.append(cand)
                matched = True
                break
        if not matched: 
            i = 1
            words.append(chars[idx].encode("utf8"))
        idx += i

    return words

if __name__=="__main__":

    try:
        fpi=open(sys.argv[1], "r")
    except:
        print >> sys.stderr, "failed to open file"
        sys.exit(1)

    try:
        dic = pickle.load(open(sys.argv[2], "r"))
    except:
        print >> sys.stderr, "failed to load dict %s" % sys.argv[2]
        sys.exit(1)
    try:
        fpo = open("out.txt","w")
    except:
        print >> sys.stderr, "failed to load out.txt"
        sys.exit(1)
    for line in fpi:
        fpo.write("\t".join( max_match_segment(line.strip(), dic) ))
當然,這只是最基礎的,還可以有很多高階的優化,比如說改成Trie樹版本的,控制最大詞長度的等等。

相關推薦

中文演算法正向匹配演算法Python

最大匹配演算法是自然語言處理中的中文匹配演算法中最基礎的演算法,分為正向和逆向,原理都是一樣的。 正向最大匹配演算法,故名思意,從左向右掃描尋找詞的最大匹配。 首先我們可以規定一個詞的最大長度,每次掃描的時候尋找當前開始的這個長度的詞來和字典中的詞匹配,如果沒有找到,就縮短

中文--正向匹配算法python實現

命中 col odin app () 切分 -- \n 多個 最大匹配法:最大匹配是指以詞典為依據,取詞典中最長單詞為第一個次取字數量的掃描串,在詞典中進行掃描(為提升掃描效率,還可以跟據字數多少設計多個字典,然後根據字數分別從不同字典中進行掃描)。例如:詞典中最長詞為“中

中文的逆向匹配演算法(2016年)

逆向最大匹配演算法,中文分詞機械化分詞中最基本的演算法,也是入門級別的演算法。但是,在機械化分詞方面的效果,表現卻很好。尤其是在大文字的時候,一次取較多詞語進行匹配,因為大文字匹配成詞的概率遠遠高於小文字,所以會有很好的表現。下面的程式碼,來自IK分詞的一部分原始碼包,201

中文實現——雙向匹配

關於中文分詞的一些基本介紹,可以看這篇部落格《中文分詞方法總結》。這裡就不再進行詳細介紹了。 雙向最大匹配方法 雙向最大匹配方法是一種基於詞典的分詞方法。基於詞典的分詞方法是按照一定策略將待分析的漢字串與一個“大機器詞典”中的詞條進行匹配,若在詞典中找到某個字串,則匹配成功

演算法分析-連續子陣列分治策略

大家好,我是三十三,第一次寫部落格,有什麼考慮不周的,請廣大同學多多指正。作為一個計算機專業毛都不會的即將畢業狗,說實話,心裡一點有一絲絲慌慌的。在即將畢業之際,自己還是想囤點貨給自己貼貼金,有啥錯誤還望指出。一、 實驗目的及任務分治法求解最大子陣列問題二、 實驗環境c++或

排序演算法氣泡排序和快速排序Java

轉自:http://www.cnblogs.com/0201zcr/p/4763806.html  作者:Whywin 1、氣泡排序 演算法如下(排序後,由小到大排列): /** * 氣泡排序 * 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。

棧應用 括號匹配問題Python

text 所有 != parent else 括號 check style pan 棧應用之 括號匹配問題(Python 版) 檢查括號是否閉合 循序掃描被檢查正文(一個字符)裏的一個個字符 檢查中跳過無關字符(所有非括號字符都與當前處理無關) 遇到開括號將其壓入棧 遇到

一個簡單正向匹配Maximum MatchingMM中文演算法的實現

1.構建詞典記憶體樹的TrieNode節點類:       package cn.wzb.segmenter.mm.bean; import java.util.HashMap; /** * 構建記憶體詞典的Trie樹結點 * */ public cla

自己動手寫引擎——逆向正向、雙向演算法的實現

分詞引擎已經是NLP最成熟的部分了,經歷了:字典分詞,統計分詞等發展之後,除了應付學術中才有的各種變態歧義句之外,目前工業界的分詞引擎對於絕大多數的常見問題已經足以應對,頂多是需要不斷優化新詞字典就可以了。 但不管怎麼樣,對於一個NLPer還是要能夠手寫最簡單的分詞演算法的

貪心演算法的子組合求解

      本來博主是沒有心情寫這篇部落格了,因為昨天住的地方遭賊了。半夜兩點多,偷開我家窗戶,把博主臥室裡面的玫瑰金給偷走了。當時博主就睡得特別不舒服,半夜醒來就發現手機被偷了。搞得博主後半夜基本沒有睡,萬幸的是,博主的手機開了“查詢iphone”功能,因此開啟了丟失

列舉演算法

題目描述 有一條河,河中間有一些石頭,已知石頭的數量和相鄰兩塊石頭之間的距離。現在可以移除一些石頭,問最多移除m塊石頭後(首尾兩塊石頭不可以移除),相鄰兩塊石頭之間的距離的最小值最大是多少。 輸入資料 第一行輸入兩個數字,n(2<=n<=1000)為石頭

機器學習期望(EM)演算法

1.EM演算法簡介 最大期望(Expectation Maximum)演算法是一種迭代優化演算法,其計算方法是每次迭代分為期望(E)步和最大(M)步。我們先看下最大期望演算法能夠解決什麼樣的問題。 假如班級裡有50個男生和50個女生,且男生站左,女生站右。我們假

機器學習似然演算法

機器學習十大演算法之一:EM演算法。能評得上十大之一,讓人聽起來覺得挺NB的。什麼是NB啊,我們一般說某個人很NB,是因為他能解決一些別人解決不了的問題。神為什麼是神,因為神能做很多人做不了的事。那麼EM演算法能解決什麼問題呢?或者說EM演算法是因為什麼而來到這個世界上,

貪心演算法相容活動子集合問題

問題:     有n個活動的集合E={1,2,…,n},其中每個活動都要求使用同一資源,如演講會場等,而在同一時間內只有一個活動能使用這一資源。每個活動i都有一個要求使用該資源的起始時間si和一個結束時間fi,且si <fi 。如果選擇了活動i,則它在半開時間區間[si

排程演算法短作業優先演算法

最短作業優先演算法又叫做短程序優先演算法 寫此博文目的: 1.方便自己複習 2.給正在學習此演算法的人一點參考 單道(一次只能執行一個程序) 分析: 先將程序按照到達時間升序排序,第一個程序到達的時候不等待,直接執行,因為他是第一個到達的程序,在他之前沒有程序在執行,當有程序到達但是有其他程序在執行的時候,到

杭州電子科技大學Online Judge 連續子序列ID1231”解題報告

杭州電子科技大學Online Judge 之 “最大連續子序列(ID1231)”解題報告 Problem Description 給定K個整數的序列{ N1, N2, ..., NK },其任意連續子序列可表示為{ Ni, Ni+1, ..., Nj },其中 1 &

正向匹配java

之前在網上尋找中文分詞使用的一些方法,看過一篇帖子(http://blog.csdn.net/niuox/article/details/11248567)是利用python寫的關於最大正向匹配的例子。 寫的還不錯,適合新入門的小白來學習學習。 後來因為執行程式的時候資料量

洛谷P4151 [WC2011]XOR和路徑線性基

std 回來 int 沒有 moto ext pri 線性 inf 傳送門 首先看到異或就想到線性基 我們考慮有一條路徑,那麽從這條路徑走到圖中的任意一個環再走回這條路徑上,對答案的貢獻是這個環的異或和,走到這個環上的路徑對答案是沒有影響的 以這張(偷來的)圖為

ZZULIOJ 1159: 的兩個數指標專題

題目描述 求n個整數中的最大的兩個元素。要求定義一個函式LargestTow(),求陣列a的最大的兩個元素,分別存入形參指標pfirst和psecond所指儲存單元,函式原型如下: void LargestTow(int a[],int n,int *pfirst,int *psecon

流模板 EK 鄰接表

題目描述 如題,給出一個網路圖,以及其源點和匯點,求出其網路最大流。 輸入輸出格式 輸入格式: 第一行包含四個正整數N、M、S、T,分別表示點的個數、有向邊的個數、源點序號、匯點序號。 接下來M行每行包含三個正整數ui、vi、wi,表示第i條有向邊從ui出發,到