詞性標註維特比演算法實現
阿新 • • 發佈:2020-07-22
基於前幾篇文章對維特比演算法的說明,此文對維特比演算法進行實現,並基於維特比演算法實現給定語句的詞性標註。關於\(pi,A,B\)的說明參考文章詞性標註語料預處理實戰,維特比相關演算法說明參考詞性標註維特比演算法介紹
def log(v): if v == 0: return np.log(v+0.000001) return np.log(v) def vertibe(x, pi, A, B): """ :param x:輸入的待預測詞性的文字,例如 "I like NLP" :param pi:初始的詞性概率 :param A:給定詞性,每個單詞的概率 :param B:詞性之間的狀態轉移概率 :return: """ # 處理輸入的文字數,獲取輸入文字在上文處理的id號 x = [word2id[word] for word in x.split(" ")] # 獲取輸入文字分詞後的長度 T = len(x) # dp[i][j] 標識第i個詞的詞性為第j個詞性 dp = np.zeros((T, N)) ptr = np.array([[0 for x in range(N)] for y in range(T)]) # 計算第一個詞在給定詞性的概率 for j in range(N): dp[0][j] = log(pi[j]) + log(A[j][x[0]]) for i in range(1, T): # 迴圈每一個單詞 for j in range(N): # 每個詞性 dp[i][j] = -99999999 # 設定一個很小的分值,作為後續計算每次的計算比較值 for k in range(N): # 迴圈每個詞性,計算從上一個詞性到當前詞性的值 score = dp[i-1][k] + log(B[k][j]) + log(A[j][x[i]]) if score > dp[i][j]: dp[i][j] = score ptr[i][j] = k # 記錄得分最高的值是從上一層的那個節點過來的 # 把最好的詞性標註序列打印出來 best_seq = [0]*T # step 1 找出對應於最後一個詞的詞性 best_seq[T-1] = np.argmax(dp[T-1]) # step 2 通過迴圈,從後到前依次求出每個單詞的詞性 for i in range(T-2, -1, -1): best_seq[i] = ptr[i+1][best_seq[i+1]] # 列印預測的詞性序列 for i in range(len(best_seq)): print(id2tag[best_seq[i]]) x = "Newsweek , trying to keep pace with rival Time magazine , announced new advertising rates for 1990" vertibe(x, pi, A, B)
執行結果如下
NNP
,
VBG
TO
VB
NN
IN
JJ
NN
NN
,
VBD
JJ
NN
NNS
IN
CD
該測試語料是從訓練語料中提取的,我們看下訓練語料的標註,如下所示
Newsweek/NNP
,/,
trying/VBG
to/TO
keep/VB
pace/NN
with/IN
rival/JJ
Time/NNP
magazine/NN
,/,
announced/VBD
new/JJ
advertising/NN
rates/NNS
for/IN
1990/CD
前面是詞,後面是該詞的詞性,從對比看,詞性標註的預測結果相對準確。
備註:此章節實現參考了貪心學院的相關視訊課程和程式碼,在此標註。