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)