最大機率分詞

 

這裏介紹一種分詞的方法--最大機率分詞,也叫1-gram分詞,由於它不考慮上下文關係,只考慮當前詞的機率。python

咱們須要有一個詞典,裏面記錄每一個詞的頻次,好比:app

基於這個詞典,咱們能夠將一句話用一個有向無環圖(DAG)的表示出來,好比ui

這個圖裏面,每一個節點是一個字,邊爲兩點構成詞的機率。分詞的問題,就是找出這個DAG裏面機率和最大的一條從開始到結束覆蓋全部字的路徑。好比,辣-》菜,五-》肉,蓋-》飯是一條路徑,辣-》辣,白-》菜,五-》花,肉-》肉,蓋-》飯也是一條路徑,如何找到最大的那條呢?spa

設\(\alpha_i\)爲DAG中以i節點開始以後的部分的最優路徑的累計機率,j爲i的鄰接點,那麼容易的出\(\alpha_i = max_jp(w(i,j))\alpha_{j+1}\),w(i,j)是句子中i開始j結束的詞。code

這是一個動態規劃問題,從最後一個字開始,基於之前的計算結果,逐步向前推移,直到第一個點,而後再從前日後獲得最優路徑。blog

python代碼以下:get

def build_DAG(sentence):
   DAG = {} #dict,key是每一個word的index,value是以這個字開始可以構成的詞list
   N = len(sentence)
   for k in xrange(N):
       tmp = []
       i = k
       piece = sentence[k]
       while i < N and piece in dict.FREQ:  
           if dict.FREQ[piece]:
               tmp.append(i)
           i += 1
           piece = sentence[k:i + 1]
       if not tmp:
           tmp.append(k)
       DAG[k] = tmp
   return DAG
def calc_route(sentence, DAG, route):
        N = len(sentence)
        route[N] = (0, 0)
        logtotal = log(total_freq)
        for idx in xrange(N - 1, -1, -1):
            route[idx] = max((log(dict.FREQ.get(sentence[idx:x + 1]) or 1) -
                              logtotal + route[x + 1][0], x) for x in DAG[idx])

 

def __cut_DAG(self, sentence):
    DAG = build_DAG(sentence)
    route = {}
    calc_route(DAG, route)
    x = 0
    N = len(sentence)
    segs = []
    while x < N:
        y = route[x][1] + 1
        word = sentence[x,y]
        segs.append(word)
        x = y
相關文章
相關標籤/搜索