CRF模型——打通crf模型的任督二脉(一)
CRF模型 是nlp領域的經典模型,也是公認的不好學習的模型(相比其他機器學習模型)
,我記得作為小藍書《統計機器學習》的最后一章,當年看得那叫一個晦澀難懂呢2333333,反正看了一兩遍是看不太懂,
網上博客中 照抄小藍書《統計機器學習》的最后一章的尤為多,也不能說不對,只是對我這種 小白,還是希望能有掰開算法細節和公式細節,甚至源代碼細節來看的文章。
網上關于CRF模型的各種文章,我覺得問題在于沒有 打通 CRF模型的任督二脈,
其中我認為CRF模型之所以被公認為是不好學習的模型,原因就在于相比其他機器學習模型,CRF模型中的特征的處理方式有較大的不同,CRF模型中有特征模板,特征函數,這些都是其他機器學習模型中少有的概念。所以,只要弄清楚 CRF模型中的特征模板,特征函數,特征值 這一條線上的關系,CRF模型就沒有什么晦澀難懂的了。其后的 前向概率-后向概率算法以及維特比預測算法都是通用的算法,不算晦澀難懂。
關于CRF模型中的特征模板,特征函數,特征值,我畫了一個下面的圖。
一般機器學習模型 的特征 表現方式都比較直觀,(雖然構造渠道,方式需要經驗和技巧),但CRF模型中由于特征模板的存在,特征 表現方式就不再那么直觀了,但不管怎么,由上圖可以看到,如果不看中間的第二步(即第二步是透明的),我們能看到,只要 給定語料和特征模板 , 對應的特征值其實就 已經確定下來了,代碼要做的事就是按特征函數來統計算出對應的特征值。
搞清楚CRF模型中 最難懂的概念之后,我們再來看一些公式,我相信感受會更好。
下面輸markdown 也是累死老子了。
還是先從特征函數的表達式開始,然后再看似然函數或者損失函數的式子,最后再看 對參數求導的過程。
參考 兩個我覺得不錯的講解CRF模型的原創博客
條件隨機場(Conditional Random Field)簡介
https://blog.csdn.net/aws3217150/article/details/68935789
CRF++源碼解讀
https://blog.csdn.net/aws3217150/article/details/69212445
特征模版
CRF++訓練的時候,要求我們提供特征模版,特征模版像下面這樣,先來看如下圖片:
“%x[row, column]” 代表獲得當前指向位置向上或向下偏移|row|行,并指向第column列的值,絕大多數情況下,我們的訓練語料都是(字/詞,label),且90%的例子中我們看到的特征模版中的column都是=0的,這意味著column=0,我們只把字/詞當作特征。
比如上圖中,當前指向位置為 “the DT B-NP”,那么”%x[0,0]”代表獲得當前指向偏移0行,第0列的值,也就是”the”,這條模板構成的特征含義是“當前位置的詞是“the”且label=xx”是否為真(xx可以是L中label中的任一個)。
而”%x[0,1]”代表獲得當前指向偏移0行,第1列的值,也就是”DT”。這條模板構成的特征含義是“當前位置的詞性是“DT”且label=xx”是否為真(xx可以是L中label中的任一個)。
”%x[-2,1]”則代表獲得當前指向向上偏移2行,第1列的值,也就是”PRP”,這條模板構成的特征含義是“前前位置的詞性是“PRP”且label=xx”是否為真(xx可以是L中label中的任一個)。
這就是特征最完整的意思,
之前對一個問題迷茫過,就是
”%x[0,0]”和”%x[-1,0]”遇到“the"是否產生了重復的特征。
后面想明白了,解開了這個困惑。
因為”%x[0,0]”遇到“the",產生的特征函數,舉一個label=b為例來說就是,
產生了f1=“當前位置的詞是“the”且當前位置label是b"是否為真。
而”%x[-1,0]”遇到“the”,產生的特征函數,舉一個label=b為例來說就是,
產生了f2="前一個位置的詞是“the”且當前位置label是b"是否為真。
顯然不一樣,f2在每個位置上都會去檢查前一個位置是否為“the”。
看明白了這個,就能準確的知道Unigram模版產生多少個特征函數了。
對每一條Unigram模版的規則而言,它能掃描到M個不同的取值。(一般也就是M個不同的字/詞),M個不同的取值中的每一中對當前位置的label(L種)都要考慮,也就要再乘以L.
如果有N條Unigram模版的規則,那么需要再乘以N,為什么因為每一條Unigram模版的規則,參考的位置都不同,正如前面寫的,”%x[0,0]”參考當前位置的取值,”%x[-1,0]”參考前一位置的取值,”%x[-2,0]”參考前前位置的取值。
所以N條Unigram模版的規則能產生N?M?LN*M*LN?M?L種特征函數。
再看Bigram模版。
絕大多少例子中的Bigram模版就寫了一個B就完事了。
那么寫一個B代表什么意思,沒有具體寫出Bigram模版的規則,會不會是沒有用Bigram模版產生特征函數?如果確實產生了特征函數,那么長什么樣子,能否像Unigram模版的規則知道每一個特征的具體含義呢?
答案一一解開:
1,寫一個B不代表沒有Bigram模版的規則,而是這里的B是一個簡要記法。還原的話應該是”B01:%x[0,0]”,Bigram模版的B二元的意思是,當前標簽取值和上一次標簽取值,(一元的意思是只考慮當前位置的標簽,就一個。二元的意思是不僅考慮當前位置的標簽還考慮前一個位置的標簽,所以是兩個,原來你是這樣的二,笑哭,是不是和開始想象的二不太一樣了,哈哈)。
所以假設一條Bigram模版的規則而言,假設它能掃描到M個不同的取值。(一般也就是M個不同的字/詞),M個不同的取值中的每一取值對當前位置label和前一個位置的label 這兩個位置的label有(L?LL*LL?L種組合)。
所以1條Bigram模版1條Bigram模版1條Bigram模版的規則能產生M?L?LM*L*LM?L?L種特征函數。
另外再補充一點,為什么寫一個B也應該有Bigram特征函數的產生。
那是因為Bigram特征函數本質上就是轉移特征,Bigram特征函數對應的權重就是轉移特征矩陣中的值。
對應著,Unigram特征函數本質上就是發射特征(或者說狀態特征),Unigram特征函數對應的權重就是發射特征矩陣中的值。
小藍書 《統計機器學習》的最后一章 對特征函數的數學表示是,如下:
條件隨機場CRF中的同一特征 會在各個位置上都有定義,可以會對同一特征在各個位置上求和,得到特征函數對應的全局特征值。
特征函數包含兩類,
一類是由B開頭的模板決定的 定義在邊上的特征函數,一般看成是 轉移特征,對應有轉移特征值,依賴當前位置和上一個位置
另一類是由U開頭的模板決定的 定義在節點上的特征函數,一般看成是 轉態特征,對應有轉態特征值,只依賴當前位置的觀測取值(crf++的Unigram特征模版產生的特征函數把“只依賴當前位置”這一條擴展了,變成了依賴當前位置的觀測取值,依賴前一位置的觀測取值,依賴前前一位置的觀測取值)
小藍書 《統計機器學習》也直白的說了, 條件隨機場CRF完全由 轉移特征函數值 tkt_ktk?、 狀態特征函數值sls_lsl? 和對應的 權重 λk,μl\lambda_k,\mu_lλk?,μl?確定。
看到這里估計對下標 k和l有點疑問了,放后面。
小藍書 《統計機器學習》提到,首先將轉移特征函數和狀態特征函數 及其權重用同一的符號表示,設有K1K_1K1?個轉移特征(L?L?NL*L*NL?L?N) , K2K_2K2?個轉態特征(L?NL*NL?N),K=K1+K2K=K_1+K_2K=K1?+K2?,可把特征函數統一記為:
fk(yi?1,yi,x,i)={tk(yi?1,yi,x,i)k=1,2,...,K1sl(yi,x,i)k=K1+l,l=1,2,...,K2f_k(y_{i-1},y_{i},x,i)=\left\{ \begin{array}{rcl} t_k(y_{i-1},y_{i},x,i) & & {k=1,2,...,K_1} \\ s_l(y_{i},x,i) & & { k=K_1+l, l=1,2,...,K_2}\\ \end{array} \right. fk?(yi?1?,yi?,x,i)={tk?(yi?1?,yi?,x,i)sl?(yi?,x,i)??k=1,2,...,K1?k=K1?+l,l=1,2,...,K2??
狀態特征函數需要在 各個位置上求和 ,得到對應特征值,
轉移特征也是如此,得到對應的特征值,記作:
fk(y,x,i)=∑i=1nfk(yi?1,yi,x,i),k=1,2,...,Kf_k(y,x,i) = \sum_{i=1}^{n} f_k(y_{i-1},y_{i},x,i) ,k=1,2,...,Kfk?(y,x,i)=∑i=1n?fk?(yi?1?,yi?,x,i),k=1,2,...,K
并且各特征的權重值是一一對應的:
wk={λkk=1,2,...,K1μlk=K1+l,l=1,2,...,K2w_k=\left\{ \begin{array}{rcl} \lambda_{k} & & {k=1,2,...,K_1} \\ \mu_{l} & & { k=K_1+l, l=1,2,...,K_2}\\ \end{array} \right. wk?={λk?μl???k=1,2,...,K1?k=K1?+l,l=1,2,...,K2??
看了上面之后,我們再看
https://blog.csdn.net/aws3217150/article/details/69212445
博客中,提到的Lafferty的原始論文中的表示方法:
原始論文的闡述形式是CRF是一種概率圖模型,而一幅圖可以由它的邊和節點來表達,也就是
G=(V,E)
其中,V是節點集合,E是邊集合,對于鏈式CRF,模型對于輸入序列和輸出序列可以建立如下的概率模型:
p(y?∣x?)=exp(∑e∈E∑kwk?k(e=(yi?1,yi),x?)+∑v∈V∑twt?t(v=yi,x?))Zp(\vec{y}|\vec{x})=\dfrac{exp( \sum_{e \in E}\sum_{k} w_k \phi_k (e=(y_{i-1},y_{i}), \vec{x}) +\sum_{v \in V}\sum_{t} w_t \phi_t (v=y_{i}, \vec{x})) }{Z}p(y?∣x)=Zexp(∑e∈E?∑k?wk??k?(e=(yi?1?,yi?),x)+∑v∈V?∑t?wt??t?(v=yi?,x))?
這種形式和我們常見的另一種形式其實又很大區別,另一種形式是:
p(y?∣x?)=exp(∑i∑kwk?k(yi?1,yi,x?))∑y′∈Yexp(∑i∑kwk?k(yi?1′,yi′,x?))p(\vec{y}|\vec{x})=\dfrac{exp( \sum_{i}\sum_{k} w_k \phi_k (y_{i-1},y_{i}, \vec{x}) ) }{\sum_{y^{'} \in Y} exp( \sum_{i}\sum_{k} w_k \phi_k (y_{i-1}^{'},y_{i}^{'}, \vec{x}) ) }p(y?∣x)=∑y′∈Y?exp(∑i?∑k?wk??k?(yi?1′?,yi′?,x))exp(∑i?∑k?wk??k?(yi?1?,yi?,x))?
下面的這種形式是沒有將邊和節點區分開來,看上去只是寫了邊的特征函數,因為從某種程度上看,邊包含的信息其實已經涵蓋了節點所擁有的所有信息,將這兩者統一起來只是有利于我們數學公式表達的方便性,另一方面,將邊和節點進行單獨討論,從理論上可能有一點冗余, 但從實際效果來講以及實際源碼編寫中看,都是邊和節點區分開來寫源碼的,節點信息可以充當一種backoff,起到一定的平滑效果(Smoothing)。
下面我們就看 CRF的似然函數或者損失函數的式子:
L=?∑iNlogp(y?i∣x?i)L=- \sum_{i}^{N} log p(\vec y^{i} |\vec x^{i})L=?∑iN?logp(y?i∣xi)
其實我看到這個式子,總覺得和以前看到的機器學習的損失函數式子不一樣,就在于這個∑iN\sum_{i}^{N}∑iN?, 按之前看到的,應該不需要這個∑iN\sum_{i}^{N}∑iN?,直接用L=?logp(y?i∣x?i)L=- log p(\vec y^{i} |\vec x^{i})L=?logp(y?i∣xi)就行了好像。
N應該不是句子的個數,而是語料中按詞或者子拆分后的行數才對。
在直接看對損失函數的求導推導之前,應該再回一下,CRF的模型的損失函數的由來,并由此帶出CRF模型中的前向后向算法。
MEMM(Maximum Entropy Markov Model)最大熵馬爾科夫模型,解決標注問題的假設,也是認為狀態的轉移僅僅依賴于上一狀態(這里我將標注標簽稱為一種狀態)
這其實和crf很像, crf 大致一看其實也是這樣,crf本來就是基于這個改進的,后面再說
上述MEMM雖然可以很優雅地解決標注問題,但存在標注偏好的問題,就是說模型在為輸入序列x 打標簽的時候,存在偏袒心里,會傾向于選擇某些標簽,
如果 s1只有兩種轉移狀態:s1,s2,而s2有5種轉移狀態:s1,s2,s3,s4,s5
因為s1的轉移狀態很少,所以不管實際訓練觀測值有多少,由于每一步的狀態轉移概率都要歸一化,所以s1的轉移概率都會被放大,而s2由于轉移狀態多,因此每一步轉移概率歸一化的時候都被平均分攤了。因此在計算最優序列的時候,MEMM會偏袒那些狀態轉移少的標簽,而忽略了實際觀察值,
為了說明該現象,我們可以參考原始論文的識別 rob和rib例子,可參考https://blog.csdn.net/aws3217150/article/details/68935789
MEMM產生Label Bias的根源是什么,
這是因為MEMM的狀態轉移概率的計算方式,為了獲得轉移概率,它每一步的狀態轉移都會進行歸一化,從而導致問題的產生。
CRF認清了問題的根源,只要不要在每一步狀態轉移進行歸一化,而在全局進行歸一化 就能一下子化解了MEMM產生的Label Bias標注偏好這個大問題。
p(s?∣x?)=∏i=0np(si∣si?1,x1,x2,...,xn)=∏i=0nexp(w?Tf(si,si?1,x?))∑s′∈Sexp(w?Tf(s?′,si?1,x?))p(\vec s| \vec x)=\prod_{i=0}^n p(s_i|s_{i-1},x_1,x_2,...,x_n)=\prod_{i=0}^n \dfrac{exp(\vec w^{T} f(s_i,s_{i-1},\vec x))}{ \sum_{s^{'} \in S} exp(\vec w^{T} f(\vec s^{'},s_{i-1},\vec x))}p(s∣x)=∏i=0n?p(si?∣si?1?,x1?,x2?,...,xn?)=∏i=0n?∑s′∈S?exp(wTf(s′,si?1?,x))exp(wTf(si?,si?1?,x))?
p(s?∣x?)=exp(w?TΦ(s?,x?))∑s′∈Snexp(w?TΦ(s?′,x?))p(\vec s| \vec x)=\dfrac{exp(\vec w^{T} \Phi(\vec s,\vec x))}{ \sum_{s^{'} \in S^{n}} exp(\vec w^{T} \Phi(\vec s^{'},\vec x))}p(s∣x)=∑s′∈Sn?exp(wTΦ(s′,x))exp(wTΦ(s,x))?
第一個是MEMM 對條件概率做的表達式,
第二個是CRF 對條件概率做的表達式,
分母中的 s′∈S,s′∈Sns^{'} \in S , s^{'} \in S^{n}s′∈S,s′∈Sn 一點點不同,表示的含義就千差萬別了,前者只是局部的,后者是全局的。
CRF相對于MEMM做了幾個改動,首先在特征函數上面做了變動:
Φ(s?,x?)→Rd\Phi(\vec s,\vec x) \rightarrow R^ze8trgl8bvbqΦ(s,x)→Rd
第一個是它將輸入序列x?\vec xx和輸出標注s?\vec ss映射為一個d維實數向量(這個d其實就是特征函數的個數,聯系前面講到的特征函數的內容,L?N,L?L?NL*N,L*L*NL?N,L?L?N),而MEMM的特征函數擁有的信息只是輸入序列x?\vec xx和當前狀態以及上一個狀態,也就是說CRF的特征函數掌握信息量更多,從而表達能力更強。
第二個的改進是它不再針對每一次狀態轉移進行歸一化,而是在全局進行歸一化,這樣完美解決Label Bias問題。
有得必有失,注意到全局進行歸一化就意味著 模型的分母需要羅列所有的狀態序列,對于序列長度為n的輸入序列,狀態序列的個數為∣S∣n|S|^{n}∣S∣n,對于這種指數增長問題,在實際應用中一般都是intractable的,只能付諸于近似求解,比如我們之前提過的Variational Bayes或者Gibbs Sampling等等。不過有一種特殊結構的CRF,精確快速求解的方式是存在的(前向后向算法幫助我們),因此在早期得以廣泛應用。
總結
以上是生活随笔為你收集整理的CRF模型——打通crf模型的任督二脉(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网吧操作系统制作与优化
- 下一篇: 完整制作网吧系统全过程