HMM+Viterbi算法分詞

PS:這篇文章中的代碼,僅為一個簡單的DEMO,并未進行過代碼和算法的優(yōu)化烈掠,參數(shù)也未進行過調(diào)整,僅僅是演示了一個從訓(xùn)練模型到應(yīng)用的完整過程

import numpy as np
from bidict import bidict
from functools import reduce

corpus = [
    '小鳥 聲音 不大 鞠抑, 卻 句 句 在理 , 全場 都 靜靜 恭聽 忌警。',
    '他 說 : “ 神 是否 創(chuàng)造 世界 搁拙,即 神 對 世界 的 關(guān)系 如何 ,這個 問題 其實 就是 關(guān)于 精神 對 感性 一般 或 抽象 對 實在法绵、類 對 個體 的 關(guān)系 如何 的 問題 箕速;這個 問題 是 屬于 人類 認識 和 哲學(xué) 上 最 重要 又 最 困難 的 問題 之一 , 整個 哲學(xué)史 其實 只在 這個 問題 周圍 繞 圈子 朋譬, 古代 哲學(xué) 中 斯多葛派 和 伊壁鳩魯派 間 盐茎、 柏拉圖派 和 亞里士多德派 間 、 懷疑派 和 獨斷派 間 的 爭論 此熬, 中古哲學(xué) 中 唯名論者 和 實在論者 間 的 爭論 庭呜, 以及 近代 哲學(xué) 中 唯心主義者 和 實在論者 或 經(jīng)驗主義者 間 的 爭論 滑进, 歸根結(jié)底 都是 關(guān)于 這個 問題 犀忱。 ”',
    '討論 法 的 本位 問題 , 應(yīng)該 局限 于 實在 法效 用 的 實現(xiàn) 借助 于 何種 規(guī)范 手段 的 范圍 內(nèi) 扶关, 它 主要 應(yīng) 討論 " 法 是 什么 " 的 問題 阴汇, 而 不是 " 法 應(yīng)當 是 什么 " 的 問題 。',
    '現(xiàn)在 节槐, 你 已是 全班 第一名 了 搀庶, 我們 都要 向 你 學(xué)習(xí) , 我們 還會 繼續(xù) 幫助 你 铜异。',
    '他們 的 罪惡 行徑 也 從 反面 教育 我們 哥倔, 革命 的 政治工作 對于 我們 黨 的 各項 工作 , 對于 我們 軍隊 和 人民 來說 揍庄, 確實 是 不可以 須臾 離開 的 生命線 咆蒿。',
    '從 研究系 辦 的 刊物 來看 , 確實 登載 過 大量 的 討論 社會主義 的 文章 , 似乎 亦 擁護 社會主義 沃测, 但 實際上 這 只是 假象 缭黔。',
    '他 那些 舞臺 下 、 劇場 外 的 事 的確 是 鮮為人知 的 蒂破。', '他 說 的 確實 在理'
]
# 隱序列
hidden_states = bidict({'B': 0, 'M': 1, 'E': 2, 'S': 3})

atomic = set(reduce(lambda l1, l2: l1 + l2, map(lambda x: list(x), corpus)))
# 字符及其索引
characters = bidict(enumerate(atomic))

hidden_states_count = len(hidden_states)

characters_count = len(characters)

#初始概率矩陣
init_matrix = np.zeros((1, hidden_states_count))
#轉(zhuǎn)移概率矩陣
trans_matrix = np.zeros((hidden_states_count, hidden_states_count))
#輸出概率矩陣
out_matrix = np.zeros((hidden_states_count, characters_count))

for s in corpus:
    words = s.split()
    #初始矩陣
    state = 'B' if len(words[0]) > 1 else 'S'
    init_matrix[0, hidden_states[state]] += 1
    pre = None
    for word in words:
        l = len(word)

        #求轉(zhuǎn)移矩陣
        first = 'S' if l == 1 else 'B'
        last = 'S' if l == 1 else 'E'
        if l == 1:
            out_matrix[hidden_states['S'], characters.inv[word[0]]] += 1
        elif l == 2:
            trans_matrix[hidden_states['B'], hidden_states['E']] += 1
            out_matrix[hidden_states['B'], characters.inv[word[0]]] += 1
            out_matrix[hidden_states['E'], characters.inv[word[-1]]] += 1
        else:
            trans_matrix[hidden_states['B'], hidden_states['M']] += 1
            trans_matrix[hidden_states['M'], hidden_states['E']] += 1

            out_matrix[hidden_states['B'], characters.inv[word[0]]] += 1
            out_matrix[hidden_states['E'], characters.inv[word[-1]]] += 1
            trans_matrix[hidden_states['M'], hidden_states['M']] += l - 2 - 1
            for i in range(1, l - 1):
                out_matrix[hidden_states['M'], characters.inv[word[i]]] += 1
        if pre:
            trans_matrix[hidden_states[pre], hidden_states[first]] += 1
        pre = last

#求三個矩陣概率
init_matrix /= np.sum(init_matrix)
trans_matrix /= np.sum(trans_matrix)
out_matrix /= np.sum(out_matrix)

#==========
input = '他說的確實在理'

ilen = len(input)

path = np.full((hidden_states_count, ilen - 1), -1, dtype=np.int8)

#先求第一個字的概率
weight = init_matrix * out_matrix[:, characters.inv[input[0]]]

# 求后續(xù)概率
for col in range(1, ilen):
    c = input[col]
    prob = weight.reshape(4,
                          1) * trans_matrix * out_matrix[:, characters.inv[c]]

    path[:, col - 1] = np.argmax(prob, axis=0)
    #再取對應(yīng)的最大概率 賦值給weight

    if col == 0:
        print('char', c)
        print("weight:", weight)  #上一個字的可能性權(quán)重
        print("weight*trans-martrix", weight.reshape(4, 1) * trans_matrix)
        print("out-matrix", out_matrix[:, characters.inv[c]])
        print("result", prob)
        print("argmax", path[:, col - 1])
        exit()
    weight = np.max(prob, axis=0)

print(path)
state = 'E' if weight[hidden_states['E']] > weight[hidden_states['S']] else 'S'


state_seq = [state]
for i in range(ilen - 2, -1, -1):
    print(path[hidden_states[state], i])
    state = hidden_states.inv[path[hidden_states[state], i]]
    state_seq.append(state)

state_seq.reverse()

print(state_seq)

result = []

for i, s in enumerate(state_seq):
    result.append(input[i])
    if s in ('S', 'E'):
        result.append(" ")

print(result)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末馏谨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子附迷,更是在濱河造成了極大的恐慌惧互,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件喇伯,死亡現(xiàn)場離奇詭異壹哺,居然都是意外死亡,警方通過查閱死者的電腦和手機艘刚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門管宵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人攀甚,你說我怎么就攤上這事箩朴。” “怎么了秋度?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵炸庞,是天一觀的道長。 經(jīng)常有香客問我荚斯,道長埠居,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任事期,我火速辦了婚禮滥壕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘兽泣。我一直安慰自己绎橘,他們只是感情好,可當我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布唠倦。 她就那樣靜靜地躺著称鳞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪稠鼻。 梳的紋絲不亂的頭發(fā)上冈止,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天,我揣著相機與錄音候齿,去河邊找鬼熙暴。 笑死苫亦,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的怨咪。 我是一名探鬼主播屋剑,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼诗眨!你這毒婦竟也來了唉匾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤匠楚,失蹤者是張志新(化名)和其女友劉穎巍膘,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芋簿,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡峡懈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了与斤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肪康。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖撩穿,靈堂內(nèi)的尸體忽然破棺而出磷支,到底是詐尸還是另有隱情,我是刑警寧澤食寡,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布雾狈,位于F島的核電站,受9級特大地震影響抵皱,放射性物質(zhì)發(fā)生泄漏善榛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一呻畸、第九天 我趴在偏房一處隱蔽的房頂上張望移盆。 院中可真熱鬧,春花似錦擂错、人聲如沸味滞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至昨凡,卻和暖如春爽醋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背便脊。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工蚂四, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓遂赠,卻偏偏與公主長得像久妆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子跷睦,可洞房花燭夜當晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,080評論 25 707
  • 20180708星期日 天氣晴 天氣預(yù)報說有中雨筷弦,然后改為小雨,最后就下了那么一陣… 今天胥怡戎...
    璇戎爸爸閱讀 112評論 0 0
  • 歡迎關(guān)注幼兒說抑诸,用簡書的媽咪烂琴,都是有品味的母親 昨天是年初一,帶了阿瓜到親戚家拜年蜕乡。本想舒舒服服過個年奸绷,但遭遇熊孩...
    幼兒說閱讀 1,387評論 4 23
  • 這是我來學(xué)校的第三次降溫,冷的令我發(fā)指层玲!是的号醉,估計也只有我在這個天氣裹著厚厚的羽絨服再加一個防風(fēng)衣了吧。 猶...
    象煦閱讀 450評論 2 4