经典算法复现!(条件随机场)CRF原理及实现代码
?Datawhale?
作者:丁媛媛,Datawhale優秀學習者
寄語:本文先對馬爾可夫過程及隱馬爾可夫算法進行了簡單的介紹;然后,對條件隨機場的定義及其三種形式進行了詳細推導;最后,介紹了條件隨機場的三大問題,同時針對預測問題給出了代碼實踐。
條件隨機場(conditional random fields,簡稱 CRF,或CRFs),是一種判別式概率模型,常用于標注或分析序列資料,如自然語言文字或是生物序列。
條件隨機場是條件概率分布模型P(Y|X),表示的是給定一組輸入隨機變量X的條件下另一組輸出隨機變量Y的馬爾可夫隨機場,也就是說CRF的特點是假設輸出隨機變量構成馬爾可夫隨機場。
知識框架
馬爾可夫過程
定義:假設一個隨機過程中, 時刻的狀態的條件發布,只與其前一狀態 相關,即:
則將其稱為馬爾可夫過程。
隱馬爾可夫算法(HMM)
1、定義
隱馬爾可夫算法是對含有未知參數(隱狀態)的馬爾可夫鏈進行建模的生成模型,如下圖所示:
在隱馬爾科夫模型中,包含隱狀態和觀察狀態,隱狀態對于觀察者而言是不可見的,而觀察狀態對于觀察者而言是可見的。隱狀態間存在轉移概率,隱狀態到對應的觀察狀態間存在輸出概率。
2、假設
假設隱狀態的狀態滿足馬爾可夫過程,時刻的狀態的條件分布,僅與其前一個狀態相關,即:
假設觀測序列中各個狀態僅取決于它所對應的隱狀態,即:
3、存在問題
在序列標注問題中,隱狀態(標注)不僅和單個觀測狀態相關,還和觀察序列的長度、上下文等信息相關。例如詞性標注問題中,一個詞被標注為動詞還是名詞,不僅與它本身以及它前一個詞的標注有關,還依賴于上下文中的其他詞。
條件隨機場
以線性鏈條件隨機場為例
1、定義
給定均為線性鏈表示的隨機變量序列,若在給隨機變量序列X的條件下,隨機變量序列Y的條件概率分布P(Y|X)構成條件隨機場,即滿足馬爾可夫性:
則稱為為線性鏈條件隨機場。
通過去除了隱馬爾科夫算法中的觀測狀態相互獨立假設,使算法在計算當前隱狀態時,會考慮整個觀測序列,從而獲得更高的表達能力,并進行全局歸一化解決標注偏置問題。
1)參數化形式
其中:為歸一化因子,是在全局范圍進行歸一化,枚舉了整個隱狀態序列的全部可能,從而解決了局部歸一化帶來的標注偏置問題。
為定義在邊上的特征函數,轉移特征,依賴于前一個和當前位置為定義在節點上的特征函數,狀態特征,依賴于當前位置。
2)簡化形式
因為條件隨機場中同一特征在各個位置都有定義,所以可以對同一個特征在各個位置求和,將局部特征函數轉化為一個全局特征函數,這樣就可以將條件隨機場寫成權值向量和特征向量的內積形式,即條件隨機場的簡化形式。
step 1?將轉移特征和狀態特征及其權值用統一的符號表示,設有個轉移特征,個狀態特征,,記
step 2?對轉移與狀態特征在各個位置求和,記作
step 3?將 和 用統一的權重表示,記作
step 4?轉化后的條件隨機場可表示為:
step 5?若 表示權重向量:以 表示特征向量,即
? ? ?則,條件隨機場寫成內積形式為:
3)矩陣形式
2、基本問題
條件隨機場包含概率計算問題、學習問題和預測問題三個問題。
概率計算問題:已知模型的所有參數,計算觀測序列Y出現的概率,常用方法:前向和后向算法;
學習問題:已知觀測序列Y,求解使得該觀測序列概率最大的模型參數,包括隱狀態序列、隱狀態間的轉移概率分布和從隱狀態到觀測狀態的概率分布,常用方法:Baum-Wehch算法;
預測問題:一直模型所有參數和觀測序列Y,計算最可能的隱狀態序列X,常用算法:維特比算法。
1)概率計算問題
給定條件隨機場,輸入序列 和 輸出序列; 計算條件概率
計算相應的數學期望問題;
前向-后向算法
step 1 前向計算;對觀測序列x的每個位置 ,定義一個階矩陣(m為標記Y_i取值的個數),對每個指標,定義前向向量 ,則遞推公式:
? ? ? 其中,
否則
step 2 后向計算;對每個指標,定義前向向量,則遞推公式:
step 3
step 4 概率計算;所以,標注序列在位置是標注的條件概率為:
? ? ?其中,
step 5 期望值計算;通過利用前向-后向向量,計算特征函數關于聯合概率分布 和 條件概率分布 的數學期望,即特征函數 關于條件概率分布 的數學期望:
? ? ? ?其中:
2)學習問題
這里主要介紹一下 BFGS 算法的思路。
輸入:特征函數 :經驗分布 ;
輸出:最優參數值 ,最優模型。
選定初始點 , 取 為正定對稱矩陣,;
計算 ,若 ,則停止計算,否則轉 (3) ;
利用 計算;
一維搜索:求 使得
設
計算, 若, 則停止計算;否則,利用下面公式計算 :
? ? ?令 ,轉步驟(3);
3)預測問題
對于預測問題,常用的方法是維特比算法,其思路如下:
輸入:模型特征向量 和權重向量,輸入序列(觀測序列);
輸出:條件概率最大的輸出序列(標記序列),也就是最優路徑;
初始化
遞推,對
終止
返回路徑
? ? 求得最優路徑
案例:利用維特比算法計算給定輸入序列 對應的最優輸出序列:
初始化
遞推,對
終止
返回路徑
求得最優路徑
代碼實現如下:
import numpy as npclass CRF(object):'''實現條件隨機場預測問題的維特比算法'''def __init__(self, V, VW, E, EW):''':param V:是定義在節點上的特征函數,稱為狀態特征:param VW:是V對應的權值:param E:是定義在邊上的特征函數,稱為轉移特征:param EW:是E對應的權值'''self.V = V #點分布表self.VW = VW #點權值表self.E = E #邊分布表self.EW = EW #邊權值表self.D = [] #Delta表,最大非規范化概率的局部狀態路徑概率self.P = [] #Psi表,當前狀態和最優前導狀態的索引表sself.BP = [] #BestPath,最優路徑return def Viterbi(self):'''條件隨機場預測問題的維特比算法,此算法一定要結合CRF參數化形式對應的狀態路徑圖來理解,更容易理解.'''self.D = np.full(shape=(np.shape(self.V)), fill_value=.0)self.P = np.full(shape=(np.shape(self.V)), fill_value=.0)for i in range(np.shape(self.V)[0]):#初始化if 0 == i:self.D[i] = np.multiply(self.V[i], self.VW[i])self.P[i] = np.array([0, 0])print('self.V[%d]='%i, self.V[i], 'self.VW[%d]='%i, self.VW[i], 'self.D[%d]='%i, self.D[i])print('self.P:', self.P)pass#遞推求解布局最優狀態路徑else:for y in range(np.shape(self.V)[1]): #delta[i][y=1,2...]for l in range(np.shape(self.V)[1]): #V[i-1][l=1,2...]delta = 0.0delta += self.D[i-1, l] #前導狀態的最優狀態路徑的概率delta += self.E[i-1][l,y]*self.EW[i-1][l,y] #前導狀態到當前狀體的轉移概率delta += self.V[i,y]*self.VW[i,y] #當前狀態的概率print('(x%d,y=%d)-->(x%d,y=%d):%.2f + %.2f + %.2f='%(i-1, l, i, y, \self.D[i-1, l], \self.E[i-1][l,y]*self.EW[i-1][l,y], \self.V[i,y]*self.VW[i,y]), delta)if 0 == l or delta > self.D[i, y]:self.D[i, y] = deltaself.P[i, y] = lprint('self.D[x%d,y=%d]=%.2f\n'%(i, y, self.D[i,y]))print('self.Delta:\n', self.D)print('self.Psi:\n', self.P)#返回,得到所有的最優前導狀態N = np.shape(self.V)[0]self.BP = np.full(shape=(N,), fill_value=0.0)t_range = -1 * np.array(sorted(-1*np.arange(N)))for t in t_range:if N-1 == t:#得到最優狀態self.BP[t] = np.argmax(self.D[-1])else: #得到最優前導狀態self.BP[t] = self.P[t+1, int(self.BP[t+1])]#最優狀態路徑表現在存儲的是狀態的下標,我們執行存儲值+1轉換成示例中的狀態值#也可以不用轉換,只要你能理解,self.BP中存儲的0是狀態1就可以~~~~self.BP += 1print('最優狀態路徑為:', self.BP)return self.BPdef CRF_manual(): S = np.array([[1,1], #X1:S(Y1=1), S(Y1=2)[1,1], #X2:S(Y2=1), S(Y2=2)[1,1]]) #X3:S(Y3=1), S(Y3=1)SW = np.array([[1.0, 0.5], #X1:SW(Y1=1), SW(Y1=2)[0.8, 0.5], #X2:SW(Y2=1), SW(Y2=2)[0.8, 0.5]])#X3:SW(Y3=1), SW(Y3=1)E = np.array([[[1, 1], #Edge:Y1=1--->(Y2=1, Y2=2)[1, 0]], #Edge:Y1=2--->(Y2=1, Y2=2)[[0, 1], #Edge:Y2=1--->(Y3=1, Y3=2) [1, 1]]])#Edge:Y2=2--->(Y3=1, Y3=2)EW= np.array([[[0.6, 1], #EdgeW:Y1=1--->(Y2=1, Y2=2)[1, 0.0]], #EdgeW:Y1=2--->(Y2=1, Y2=2)[[0.0, 1], #EdgeW:Y2=1--->(Y3=1, Y3=2)[1, 0.2]]])#EdgeW:Y2=2--->(Y3=1, Y3=2)crf = CRF(S, SW, E, EW)ret = crf.Viterbi()print('最優狀態路徑為:', ret)returnif __name__=='__main__':CRF_manual()輸出如下圖:
往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習及深度學習筆記等資料打印機器學習在線手冊深度學習在線手冊AI基礎下載(pdf更新到25集)本站qq群1003271085,加入微信群請回復“加群”獲取一折本站知識星球優惠券,復制鏈接直接打開:https://t.zsxq.com/yFQV7am喜歡文章,點個在看
總結
以上是生活随笔為你收集整理的经典算法复现!(条件随机场)CRF原理及实现代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【NLP】NLP从业人员必须知道的十大必
- 下一篇: 四个好用却可能不为人所熟知的Pandas