本文將盡可能使用易懂的方式,儘量不涉及數學公式,而是從總體的思路上來看,運用感性直覺的思考來解釋條件隨機場。而且用水滸傳爲例學習。而且從名著中找了具體應用場景來幫助你們深刻這個概念。html
在機器學習過程當中,會遇到不少晦澀的概念,相關數學公式不少,你們理解起來頗有困難。遇到相似狀況,咱們應該多從直覺角度入手思考,用類別或者舉例來附會,這樣每每會有更好的效果。java
我在講解論述過程當中給本身的要求是:在生活中或者名著中找一個例子,而後用本身的話語闡述出來。node
首先仍是須要大概介紹下HMM和MEMM,這樣才能知道爲何要引入CRF。python
其中HMM在前文[白話解析]以水滸傳爲例學習隱馬爾可夫模型中也詳細介紹。這裏主要講講其推導過程和其缺點。git
HMM模型中存在兩個假設:一是輸出觀察值之間嚴格獨立,二是狀態的轉移過程當中當前狀態只與前一狀態有關(一階馬爾可夫模型)。下面咱們就講講這兩個假設是如何應用在推導過程當中的。github
單樣本樸素貝葉斯分類任務中 (其中 x 是觀測值,y 是隱藏狀態) :
\[ P(y|x)=\frac{P(x|y)*P(y)}{P(x)} \]
擴展到序列化樣本分類問題任務中爲:
\[ P(y_1^n ∣x_1^n)= \frac{P(x_1^n∣y_1^n)∗P(y_1^n)}{P(x_1^n)} \]
其中n表示的是序列的長度,這就是咱們計算某個標籤序列在序列分類中的機率得分。算法
咱們以詞性標註這一序列化分類問題進行後面的講解。對於一個給定的句子x_i^n=(x_1,x_2,...,x_n),咱們的目的是爲其找到一個得分最高的標籤序列 (yˆ1,yˆ2,...,yˆn ),則該問題轉化爲:
\[ \hat y_1^n = arg_{y_1^n} \ max \frac{P(x_1^n∣y_1^n)∗P(y_1^n)}{P(x_1^n)} \]
對於同一個句子的標註,分母是相同的,因此該問題能夠轉化爲:
\[ \hat y_1^n = arg_{y_1^n} \ max P(x_1^n∣y_1^n)∗P(y_1^n) \]
回憶下聯合分佈的公式
\[ P(X = x \ and \ Y = y) = \ P(Y=y|X=x)P(X=x) = \ P(X=x|Y=y)P(Y=y) \]
因此上述問題轉化後的公式就是 P(X,Y)。即 HMM 試圖去擬合 X,Y 的聯合分佈 P(X,Y),因此它是一種生成式模型。網絡
如今咱們須要引入HMM的兩個基本假設,才能計算 P:dom
以上這兩個假設是 HMM 的核心,以後的公式推導都是依賴這兩個假設成立的基礎上進行的。機器學習
這兩個假設分別能夠用於計算上。
\[ 假設1 \ 用於求解 \ 當前狀態 \ P(y_1^n) \\ 假設2 \ 用於求解 \ 當前觀測值 \ P(x_1^n∣y_1^n) \]
原始狀況下,根據有向圖模型計算方式:
\[ P(y_1^n)=P(y_1)∗P(y_2∣y_1)∗P(y_3∣y_1,y_2)∗...∗P(y_n∣y_1,y_2,...,y_{n−1}) \]
咱們先把 假設1 用於求解,則其計算方式變爲:
\[ P(y_1^n)=P(y_1)∗P(y_2∣y_1)∗P(y_3∣y_2)∗...∗P(y_n∣y_{n−1}) \]
根據 假設2 ,當前觀測值僅僅與當前狀態有關,與其餘時刻狀態和觀測值無關,因此
\[ P(x_1^n∣y_1^n)=P(x_1∣y_1)∗P(x_2∣y_2)∗...∗P(x_n∣y_n) \]
即
最後合併起來:
\[ \hat y_1^n = arg \ max_{y_1^n} ∏_{t=1}^nP(x_t∣y_t)∗P(y_t∣y_{t−1}) \]
HMM的學習過程就是在訓練集中學習這兩個機率矩陣 (大小爲 (y, y),(x, y) )
HMM 擁有如下幾個缺陷:
其中最大熵模型在前文 [白話解析] 深刻淺出最大熵模型 以及 [白話解析]用水滸傳爲例學習最大熵馬爾科夫模型 中也有介紹。
假設離散隨機變量 x 的分佈是P(x),則關於分佈P的熵定義爲:
\[ H(P) = -\sum_xP(x)logP(x) \]
能夠看出當 x 服從均勻分佈時對應的熵最大,也就是不肯定性最高。
給定離散隨機變量 和 上的條件機率分佈P(y|x),定義在條件機率分佈上的條件熵爲:
\[ H(P) = -\sum_{x,y}\hat{P}(x)P(y|x)logP(y|x) \]
其中,p̃(x) 是樣本在訓練集熵的經驗分佈,也就是 x 的各個取值在樣本中出現的頻率統計。
最大熵模型就是,在 "知足事先已約束" 的條件下,學習適合的 P(y|x) ,使得條件熵 H(P) 的取值最大。
咱們使用特徵函數來表示約束條件,即 特徵函數也就是用來指示元素是否屬於某一個子集。
最大熵馬爾科夫模型把HMM模型和maximum-entropy模型的優勢集合成一個產生式模型,這個模型容許狀態轉移機率依賴於序列中彼此之間非獨立的特徵上,MEMM是這樣的一個機率模型,即在給定的觀察狀態和前一狀態的條件下,出現當前狀態的機率。
最大熵馬爾科夫模型利用判別式模型的特色,直接對每個時刻的狀態創建一個分類器,而後將全部的分類器的機率值連乘起來。爲了實現是對整個序列進行的分類。在每一個時刻t時,它的特徵不只來自當前觀測值x_t,並且還來自前一狀態值y_{t−1} 。因此MEMM中,給定觀測序列 i1,...in 後,某個狀態序列 in 的條件機率是能夠直接學習的。就是
HMM下一個隱藏狀態 Y + 1 只是由目前隱藏標籤狀態 Y 決定。
MEMM下一個隱藏狀態 Y + 1 只是由目前隱藏標籤狀態 Y 和 觀察狀態 X 共同決定。
MEMM的序列標註問題定義爲,給定觀測序列 x_1^n,求解某個狀態序列 y_1^n ,而且使得條件機率最大,並且該條件機率知足馬爾科夫假設,也就是條件機率依賴於當前時刻的觀察狀態和前一時刻的標籤狀態:
\[ P(y_1^n|x_1^n) = \prod_{t=1}^n P(y_t|y_{t-1},x_t) \]
MEMM貪心地取當前時刻機率分佈中最大對應的標籤做爲當前時刻的解碼標籤。
其中對於前一時刻可能的狀態取值y_{t−1} 和當前觀測值x_t,當前狀態取值y_t 的機率經過最大熵分類器建模爲:
\[ P(y_t|y_{t-1},x_t) = \frac{1}{Z(x_t,y^t)}exp(\sum_aλ_af_a(x_t,y_{t-1})) \]
其中a, λ_a, f_a 分別表示特徵函數數量,特徵函數權重和第 a個特徵函數,Z() 這部分是歸一化。
經過上面的公式,你會發現最大熵模型在每個時刻,針對不一樣的前一狀態y′ 進行歸一化操做,這是一種局部的歸一化操做,會存在標籤偏置問題。即,最大熵馬爾科夫模型雖然結合了隱馬爾科夫模型和最大熵模型的最大特色,可是仍然忽略了標籤之間的約束關係,只求在當前時刻的最大條件機率。
這裏有個網上常見的論斷:
當前狀態是 S1,假設下一個狀態 S2 有兩個選擇,一個是p, 一個是c。通過局部歸一化以後,由於p的轉出狀態比較少,致使 p 的轉移機率*發射機率 相對於轉出狀態多的c而言是比較大的,這會使模型更傾向選擇狀態p。
針對這個論斷,咱們能夠寫代碼實驗下 (若是哪位兄弟知道如何數學論證,還請告訴我,謝謝) 。
# 如下就是MEMM的viterbi算法 def predict_viterbi(x, f_map, tags_s, word_t_map, lib_model): """ For each word in vector x predict his tag. Prediction is done by viterbi algorithm. Check all tags options/globally. :param x: X vector of all words to be tagged. :param f_map: Features map. :param tags_s: Tags set. :param word_t_map: Word to tags map. :param lib_model: Liblinear model. :return: Return best predicted list of tags for each word in x respectively. """ for ind, word in enumerate(x): # Calculate for each word best scores/probabilities and best tags for each word. for pp_t, p_t in v[ind]: for curr_tag in available_tags: word_features = extract.generate_word_features(is_rare, p_t, pp_t, word, ind, x) features_vec = features_to_vec(word_features, f_map) scores = lib_model.predict(features_vec) score = np.amax(scores) if (p_t, curr_tag) not in max_score or score > max_score[(p_t, curr_tag)]: max_score[(p_t, curr_tag)] = score max_tags[(p_t, curr_tag)] = pp_t # 預測代碼,能夠修改這個以測試 def predict(self, feature_ids): weights = self.weights scores = np.zeros(len(self.labels)) for f in feature_ids: if f in weights: scores += weights[f] scores = 1/(1+np.exp(-scores)) scores = scores/np.sum(scores) return scores #把上述代碼修改下,本身傳入feature或者直接傳入weight就知道了。 #好比分別傳入weight #[1, 2, 6, 1, 2] #[1, 2, 9] #就會發現,若是傳入的列表中item的個數越少,則np.amax(scores)越大。 #因此這就與以前的論斷相一致: #通過局部歸一化以後,由於 狀態 p 的轉出狀態比較少,致使 「轉移機率 x 發射機率」 相對於轉出狀態多的 狀態 c 而言是比較大的,這會使模型傾向於更多的選擇 狀態 p 。 #其實 S2 選擇 p 節點仍是 c 節點只取決於 P(p|S1)、P(c|S1),即只與 「S1」 的上下文有關,與 「S2」 的上下文無關,這就是MEMM產生偏置的一種狀況。
由於MEMM有缺點,因此人們引入了CRF。CRFs與最大熵模型的本質區別是:最大熵模型在每一個狀態都有一個機率模型,在每一個狀態轉移時都要進行歸一化。若是某個狀態只有一個後續狀態,那麼該狀態到後續狀態的跳轉機率即爲1。這樣,無論輸入爲任何內容,它都向該後續狀態跳轉。而CRFs是在全部的狀態上創建一個統一的機率模型,這樣在進行歸一化時,即便某個狀態只有一個後續狀態,它到該後續狀態的跳轉機率也不會爲1,從而解決了「label bias」問題。
看到這個概念,估計不少同窗會懵圈。這不是物理學概念嘛,咱們都學過電場,磁場。怎麼這裏也出來了一個場。
其實這是從物理學借鑑來的概念,這也不奇怪。好比熵這個概念就是物理學借鑑過來的。這說明數學物理是天然科學的基礎。
下面是我從網上或者其餘地方找到的關於「場」的解釋。但願能對你們理解有幫助。
闡釋1
這個論斷是一個傳媒學者講藝術表演創做時候提到的。你能夠認爲她說的不精確,可是不可否認從其餘行業的角度來看,反而更容易理解場這個概念。
場就是互相影響。電影表演不須要場。戲劇表演須要場,由於戲劇須要和大量觀衆互動必須對觀衆產生影響。
闡釋2
這是借用的物理裏的概念。理論物理裏提出用蒙特卡羅算法求解體系可能結構的方法,每一個結構出現的機率和exp(-betaE)成正比,-beta和溫度的倒數有關,E是體系每一個部分的勢能之和,和系統全部可能構型的這個因子之和成反比,這個和就是配分函數,而勢函數就是用來計算體系每一個部分間不一樣位置關係下可能的勢能的理論假設的函數形式。機器學習就是借用這種模型來產生機率罷了,或者說它是咱們要考察的物理量的一個因子,並且這個被考察物理量不只取值和這個因子有關,其變化規律也和這個因子有關。這是借用的物理裏的概念。理論物理裏提出用蒙特卡羅算法求解體系可能結構的方法,每一個結構出現的機率和exp(-betaE)成正比,-beta和溫度的倒數有關,E是體系每一個部分的勢能之和,和系統全部可能構型的這個因子之和成反比,這個和就是配分函數,而勢函數就是用來計算體系每一個部分間不一樣位置關係下可能的勢能的理論假設的函數形式。機器學習就是借用這種模型來產生機率罷了,或者說它是咱們要考察的物理量的一個因子,並且這個被考察物理量不只取值和這個因子有關,其變化規律也和這個因子有關。
隨機場是由若干個位置組成的總體,當給每個位置中按照某種分佈隨機賦予一個值以後,其全體就叫作隨機場。舉詞性標註的例子:假如咱們有一個十個詞造成的句子須要作詞性標註。這十個詞每一個詞的詞性能夠在咱們已知的詞性集合(名詞,動詞...) 中去選擇。當咱們爲每一個詞選擇完詞性後,這就造成了一個隨機場。
舉梁山爲例子: 好比梁山好漢一塊兒去聚義廳開會。 每把椅子是一個位置。給每一個椅子賦予一個好漢。這個好漢如何分配? 每次從梁山上各個小團體(三山派,潯陽幫,宋江嫡系......)中隨機取出一人安排到椅子上。
馬爾可夫隨機場(Markov random field)又稱爲機率無向圖模型,是一個能夠由無向圖表示的聯合機率分佈。
機率無向圖模型: 設有聯合機率分佈 P(Y) ,由無向圖 G=(V,E) 表示,在圖 G 中,結點表示隨機變量,邊表示隨機變量之間的依賴關係。若是聯合機率分佈 P(Y) 知足成對、局部或全局馬爾可夫性,就稱此聯合機率分佈爲機率無向圖模型或馬爾可夫隨機場。分別介紹一下三個概念:
\[ A ------ C ------- B \]
總的說來,馬爾可夫隨機場假設隨機場中某一個位置的賦值僅僅與和它相鄰的位置的賦值有關,和與其不相鄰的位置的賦值無關。
所以,聯合機率分佈的分解必定要讓 xi 和 xj 不出如今同一個劃分中,從而讓屬於這個圖的全部可能機率分佈都知足條件獨立性質。讓非鄰接變量不出如今同一個劃分中,即每個劃分中節點都是全鏈接的。這將咱們引向了圖的一個概念,團(clique)。
CRF是經過團以及勢函數的概念來定義條件機率P(y|x)。因此咱們要學習最大團。
馬爾可夫隨機場中,對於圖中結點一個子集,若其中任意兩結點間都有邊鏈接,則稱該結點子集爲一個團,若在一個團中,加入另外任何一個結點都再也不造成團,則稱該團爲極大團,換言之,極大團就是不能被其餘團所包含的團。
好比梁山好漢一塊兒去聚義廳開會。你就會發現,同一個小集團的人會主動聚在一塊兒。 好比打虎將李忠就必然在三山幫這一個小集團中。而九尾龜陶宗旺則必然在黃門山(摩雲金翅歐鵬、神算子蔣敬、鐵笛仙馬麟、九尾龜陶宗旺)小集團中。 李忠和陶宗旺兩我的在私下不會有什麼交集。而黃門山這四人,每一個人和每一個人之間都是全聯接,都互相熟悉。 若是往黃門山四人中加入其餘任何一個梁山好漢以後變成五人團體,則這個五人團體就再也不算是黃門山這個小集團了。因此黃門山四人就是極大團。
顯然,最簡單的團就是兩個節點以及一條邊,而咱們最開始就針對兩節點之間的相關關係(每條邊)定義了勢函數。
勢函數的做用是定量刻畫變量集 Q 中變量之間的相關關係。好比句首幾個字的關係。
給定機率無向圖模型,設其無向圖爲G,C爲G上的最大團,Y_C表示C對應的隨機變量(是最大團的全部結點)。
φ(Y_C)是一個最大團 C 上隨機變量們的聯合機率,是用於對團C中的變量之間的關係進行建模,是定義機率分佈的函數。
φ(Y_C)被稱爲與團C對應的「勢函數(potential function)」。通常而言,你要爲圖中的每一個極大團(maximal clique)定義一個勢函數。
無向圖模型中勢函數的具體形式一般定義爲特徵函數的帶權加和, 也即這些方法一般將條件隨機字段中的勢函數定義爲某些人工設計的特徵函數的線性組合,這些函數是啓發式的。
勢函數是一個表示其對應的團(clique)狀態的非負實值函數,表徵的是該clique的狀態。對於一個圖中的每個clique來說,它有一個狀態,用勢函數表示,狀態則是由多個feature的 加權和 構成,由於一個clique是包含多個 節點的,每一個節點其對應的隨機變量,都會對應一個feature。
所以,馬爾可夫隨機場中,多個變量的聯合機率分佈能基於團分解爲多個勢函數的乘積,每個團對應一個勢函數。因此能夠將聯合機率分佈分解爲其極大團上的勢函數的乘積。
熵用來表示任何一種能量在空間中分佈的均勻程度,能量分佈得越均勻,熵就越大。
對於勢函數,咱們換一種理解方式,定義將potential function表示成指數函數
\[ φ_C(Y_C) = exp \{-E(Y_C)\} \]
這樣p(x)就能夠表示成一系列E(Yc)的和的指數形式。E(Yc)叫作能力函數。
這樣轉化以後,能夠將圖理解爲一個能力的集合,他的值等於各個最大團的能量的和。CRF要作的就是最小化這些能量,以達到穩定的結果。均勻分佈就是最穩定的,熵就達到了最大值。即,用能量最小化表示整個系統達到穩態時各個變量的狀態知足的條件。
好比梁山上,有各類小團體。每個團體對應一個勢函數。 好比 生辰綱七人組,登州幫,三山幫,揭陽幫,降將幫,大名府幫,黃門山幫,清風山.... 那麼梁山就能夠理解爲一個能力的集合,他的值就等於各個小團體能量的和。 CRF就是要最小化這些能量,這樣梁山才能穩定,最好能均勻分佈,這樣熵就達到了最大值。
特徵函數是一些經驗的特性,咱們使用特徵函數來表示約束條件。特徵函數在前文[白話解析]用水滸傳爲例學習最大熵馬爾科夫模型也有詳述。
勢函數是定義場裏面全部變量關係的的一個函數,而因子是爲了或者描述簡化場裏面變量關係所限定的一個假設,例如同時考慮兩個相鄰的因子或者全部相鄰的因子。
特徵函數用來表示因子內的變量的關係,例如構成因子的變量的某些特徵是類似的。好比在詞性標註中,特徵函數多是:前一個詞是動詞,當前詞的觀察狀態[是否是句首,是否是句尾,是否是數字]
CRF中,特徵(feature)是一系列把咱們觀測到的 d 和咱們想要預測的類別 c 聯繫到一塊兒的證據(evidence)。特徵是在實數範圍內一個函數 f。這些特徵是怎麼表達的呢?有兩種特徵:
特徵表達形式比較簡單,就是你是否知足我特徵所說的這個配置,是就是1,不是就是0。
模型會給每一個特徵分配一個權重,咱們最後要學的就是這些權重:
咱們經過引入兩類特徵函數即可以定義出目標條件機率:
表示定義在觀測序列的兩個相鄰標記位置上的轉移特徵函數,用於刻畫相鄰標記變量之間的相關關係以及觀測序列對他們的影響,
表示在觀測序列的標記位置i上的狀態特徵函數,用於刻畫觀測序列對標記變量的影響。
例如詞性標註,如何判斷給出的標註序列靠譜不靠譜,轉移特徵函數主要斷定兩個相鄰的標註是否合理,例如,動詞+動詞語法不通。狀態特徵函數斷定觀測值與對應的標註是否合理,例如:ly結尾的詞-->副詞較合理。
所以咱們能夠定義一個特徵函數集合,用這個特徵函數集合來爲一個標準序列打分,根據此選出靠譜的標註序列。每個特徵函數均可以用來爲一個標準序列評分,把集合中全部特徵函數對同一個標註序列的評分綜合起來,就是這個標註序列最終的評分值。條件隨機場徹底由特徵函數和對應的權值肯定。
和HMM不一樣的是,CRF並無作出HMM的假設,CRF使用feature function來更抽象地表達特徵,使得他再也不侷限於HMM的兩類特徵。特徵函數能夠表示當前的state與任意一個observation或者 state甚至future state的關係。也就是說,特徵方程的存在容許CRF有十分自由的特徵表達。這也就是條件隨機場中場所表明的意義。舉例以下:
func1 = if (output = B-NP and feature="U01:DT") return 1 else return 0 func2 = if (output = I-NP and feature="U01:DT") return 1 else return 0 func3 = if (output = O and feature="U01:DT") return 1 else return 0 ... funcXX = if (output = B-NP and feature="U01:NN") return 1 else return 0 funcXY = if (output = O and feature="U01:NN") return 1 else return 0
一個特徵函數模板會生成 L x N 個特徵函數, 其中 L 輸出類別的狀況數目,N 是expanded feature的全部可能的狀況數目。
實際上,咱們更關心的是如何求機率無向圖模型聯合機率分佈。對給定的機率無向圖模型,咱們但願將總體的聯合機率寫成若干子聯合機率的乘積的形式,也就是將聯合機率進行因子分解,這樣便於模型的學習與計算。事實上,機率無向圖模型的最大特色就是易於因子分解。因此咱們將機率無向圖模型的聯合機率分佈表示爲其最大團上的隨機變量的函數的乘積形式的操做,稱爲機率無向圖模型的因子分解。
對於機率分佈函數而言,咱們也但願可以這樣作,即給定機率無向圖模型,設無向圖爲 G , C 爲 G 上的最大團, YC 表示 C 對應的隨機變量。那麼機率無向圖模型的聯合機率分佈 P(Y) 可分解爲圖中全部最大團 C 上的函數 ΨC(YC) 的乘積形式。
總結一下,便獲得 Hammersley-Clifford定理 ,那麼整個機率無向圖模型的聯合機率分佈P(Y)可寫做圖中 全部 最大團C上的勢函數φ(Y_C)的乘積形式。即
\[ P(Y) = \frac{1}{Z}\prod_Cφ_C(Y_C) \\Z = \sum_Y\prod_Cφ_C(Y_C) \]
其中,C 是無向圖的最大團, YC 是 C 的結點對應的隨機變量, ΨC(YC) 是 C 上定義的嚴格正函數,乘積是在無向圖全部的最大團上進行的。Z表示規範化因子,以確保P(x)是被正肯定義的機率。
儘管在給定每一個節點的條件下,分配給某節點一個條件機率是可能的,但條件隨機場的 無向性很難保證每一個節點在給定它的鄰接點條件下獲得的條件機率和以圖中其它節點爲條件獲得的條件機率一致。所以致使咱們不能用條件機率參數化表示聯合機率,而要從一組條件獨立的原則中找出一系列局部函數的乘積來表示聯合機率。
我的理解就是:由於crf但願過計算整個標記序列 Y 的聯合機率分佈,而不是在給定當前狀態條件下定義下一個狀態的分佈。可是從每一個節點角度講,很難保持條件機率一致。因此選取最大團這個具備獨立性的小羣體。
選擇局部函數時,必須保證可以經過分解聯合機率使沒有邊的兩個節點不出如今同一局部函數中。最簡單的局部函數是定義在圖結構中的最大團(clique)上的勢函數(Potential function),而且是嚴格正實值的函數形式。
可是一組正實數函數的乘積並不能知足機率公理,則必須引入一個歸一化因子 Z ,這 樣能夠確保勢函數的乘積知足機率公理,且是無向圖 中節點所表示的隨機變量的聯合機率分佈。
這樣出來的圖是等價于吉布斯分佈的,就是說,你能夠只在每一個最大子團上定義一個聯合分佈(而不須要對每一個邊定義一個聯合分佈),整個圖的聯合機率分佈就是這些最大子團的聯合機率分佈的乘積。固然這裏最大子團的聯合機率並非標準的聯合機率形式,是沒歸一化的聯合機率,叫factor(因子),整個圖的聯合機率乘完以後下面再除一個歸一化因子和就歸一化了,最終是一個聯合機率,每一個子團記載的都是因子,是沒歸一化的機率,嚴格大於零,能夠大於一。但關鍵是依賴關係、這些相關關係已經encode在裏面了。
從水滸傳角度看,能夠這麼定義特徵函數和勢函數。對了,這裏的勢函數就能夠當作是勢力
三山幫指的是二龍山、桃花山和少華山。這個派系一共13人,頭領是魯智深。下面人是:二龍山的魯智深、楊志、武松、施恩、曹正、張青和孫二孃;桃花山的周通、李忠;少華山的史進、朱武、陳達,楊春。 定義特徵函數以下 *********************** 特徵函數 之 節點屬性 s_1 = 是否是倒拔垂楊柳的僧人 s_2 = 是否是打虎英雄 s_3 = 是否是黑旋風 s_4 = 是否是五虎將 s_5 = 是否是八驃騎 s_6 = 是否是小彪將 s_7 = 是否是一同參贊軍務頭領 s_8 = 是否是步軍將校一十七員 s_9 = ...... *********************** 特徵函數 之 邊屬性 t_1 = 是否是親兄弟 t_2 = 是否是叔侄 t_3 = 是否是夫妻 t_4 = 是否是表親 t_5 = 是否是師徒 t_6 = 是否是主僕 t_7 = 是否是曾經共過生死 t_8 = 是否是一塊兒經歷過尷尬事 t_9 = 是否是同鄉 t_10 = 是否是 "聚會以前就是結拜兄弟" t_11 = 是否是同僚 t_12 = 是否是有同地工做經歷 t_13 = ...... 定義勢函數以下: *********************** 勢函數 φ = λ1t1 + λ2t2 + λ3t3 + λ4t4 + λ5f5 + ...... + w1t1 + w2t2 + w3t3 + w4t4 + w5t5 + ...... 計算結果以下: *********************** 計算結果 s_1 = 魯智深 ————————————— 倒拔垂楊柳的僧人 s_2 = 武松 ——————————————— 打虎英雄 s_3 = 0 s_4 = 0 s_5 = 楊志 史進 ——————————— 八驃騎 s_6 = 陳達,楊春,周通 —————— 小彪將 s_7 = 朱武 ———————————————— 一同參贊軍務頭領 s_8 = 李忠,施恩———————————— 步軍將校一十七員 ...... t_1 = 0 t_2 = 0 t_3 = 張青&孫二孃 —————————— 夫妻 t_4 = 0 t_5 = 0 t_6 = 0 t_7 = 武松&施恩, 魯智深&史進, 史進&朱武&陳達&楊春, 武松&張青&孫二孃, 楊志&魯智深&曹正 ———— 共生死 t_8 = 魯智深&李忠&周通 ———— 共尷尬 t_9 = 張青&孫二孃&施恩&曹正(河南),楊志&楊春(山西),周通&武松(山東),朱武&李忠(定遠縣) ———— 老鄉 t_10 = 武松&施恩, 魯智深&史進, 史進&朱武&陳達&楊春, 武松&張青&孫二孃, 周通&李忠 ———— 老兄弟 t_11 = 0 t_12 = 魯智深&楊志&史進 (都有延安府相關履歷) t_13 = ...... 這裏若是按照影響力計算,則 s_1 ~ s_7,t_3,t_7 的權重都至關大。 因而可知三山幫的勢函數有多大,有猛人,有幫閒,有主將,有副將,有馬軍,有步兵,甚至還有軍師。他們彼此之間關係則是盤根錯節。 其在梁山內部絕對是第二大勢力。
當隨機變量之間有依賴關係的時候就是條件隨機場。好比:
三山派的好漢不能和宋江嫡系挨着坐。
條件隨機場接收一個輸入序列 (觀察序列)如 X = (x1 ,x2, ..., xn),
給出一個輸出目標序列( 隱藏狀態序列 ) Y = (y1 ,y2, ..., yn),這裏使用大寫 X,Y 表示序列。
通常地,輸入序列 X 被稱爲 observations (觀測值) , 輸出序列 Y 叫做 states (隱藏狀態)。Random 指的是隨機變量 X and Y。 Conditional 指的是條件機率 Conditional probability。
HMM、MEMM屬於有向圖模型,貝葉斯網絡通常屬於有向圖。而CRF屬於馬爾科夫網絡屬於無向圖。
CRF是馬爾科夫隨機場的特例,條件隨機場沒有隱馬爾可夫模型那樣嚴格的獨立性假設條件,於是能夠容納任意的上下文信息,能夠靈活地設計特徵。同時,條件隨機場具備表達長距離依賴性和交疊性特徵的能力,並且全部特徵能夠進行全局歸一化,可以求得全局的最優解,還克服了最大熵馬爾可夫模型標記偏置的缺點。
條件隨機場準確的數學語言描述是:設X與Y是隨機變量,P(Y|X)是給定X時Y的條件機率分佈,若隨機變量Y構成的是一個馬爾科夫隨機場,則稱條件機率分佈P(Y|X)是條件隨機場。
條件隨機場是在給定須要標記的觀察序列 X 的條件下計算整個標記序列 Y 的聯合機率分佈,而不是在給定當前狀態條件下定義下一個狀態的分佈。
\[ P(Y|X) = \frac{exp (w.φ(x,y))}{Z_x} \]
注意Z(x)是遍歷全部 y 的全局歸一化,若是Z(x)寫在乘積符號裏面的則就是local歸一化,那樣獲得的是MEMM。
CRF本質上就是一個softmax,只是它不是在單樣本上面作的,而是序列化樣本;爲了保證是整個序列作的分類,在CRF中考慮了相鄰狀態之間的轉換特徵函數。
CRF損失函數由兩部分組成,真實路徑的分數 和 全部路徑的總分數。真實路徑的分數應該是全部路徑中分數最高的。
在CRF的定義中,咱們並無要求X和Y有相同的結構。而實現中,咱們通常都假設X和Y有相同的結構,即:
\[ 𝑋=(𝑋1,𝑋2,...𝑋𝑛), 𝑌=(𝑌1,𝑌2,...𝑌𝑛) \]
線性的CRF,每一個Y都只和前一個或後一個隨機變量相連,如 Y1——Y2——Y3——...Yn。每一個最大團都是鄰近的兩個隨機變量,如(Y1, Y2)、(Y二、Y3)等
CRF也和MEMM同樣作了一階馬爾科夫假設,即當前狀態只與上一狀態有關,可是區別在於CRF的特徵採用了全局特徵,它把觀測序列當作總體來看因此它的特徵函數是全局的。
線性Linear-CRF對比HMM把箭頭(轉移方向)變成了直線。最直白的感官體驗是每一個圓圈(向量)均可以肆無忌憚暢通無阻的相鄰的圓圈相連了,交互多了,模型也變複雜了,每一個圓圈之間的關係從「局部」也變成「全局」。線性Linear-CRF是CRF不少結構中比較經常使用的一種,只要保證狀態序列知足馬爾科夫性都是CRF。
網上關於CRF有兩個比較好的例子,摘錄以下:
例子1
假設你有許多小明同窗一天內不一樣時段的照片,從小明提褲子起牀到脫褲子睡覺各個時間段都有(小明是照片控!)。如今的任務是對這些照片進行分類。好比有的照片是吃飯,那就給它打上吃飯的標籤;有的照片是跑步時拍的,那就打上跑步的標籤;有的照片是開會時拍的,那就打上開會的標籤。問題來了,你準備怎麼幹?
一個簡單直觀的辦法就是,無論這些照片之間的時間順序,想辦法訓練出一個多元分類器。就是用一些打好標籤的照片做爲訓練數據,訓練出一個模型,直接根據照片的特徵來分類。例如,若是照片是早上6:00拍的,且畫面是黑暗的,那就給它打上睡覺的標籤;若是照片上有車,那就給它打上開車的標籤。
這樣可行嗎?
乍一看能夠!但實際上,因爲咱們忽略了這些照片之間的時間順序這一重要信息,咱們的分類器會有缺陷的。舉個例子,假若有一張小明閉着嘴的照片,怎麼分類?顯然難以直接判斷,須要參考閉嘴以前的照片,若是以前的照片顯示小明在吃飯,那這個閉嘴的照片極可能是小明在咀嚼食物準備下咽,能夠給它打上吃飯的標籤;若是以前的照片顯示小明在唱歌,那這個閉嘴的照片極可能是小明唱歌瞬間的抓拍,能夠給它打上唱歌的標籤。
因此,爲了讓咱們的分類器可以有更好的表現,在爲一張照片分類時,咱們必須將與它相鄰的照片的標籤信息考慮進來。這——就是條件隨機場(CRF)大顯身手的地方!
例子2
RF是隨機場,MRF是馬爾可夫隨機場,又稱機率圖模型,CRF是條件隨機場,Linear Chain CRF是線性鏈CRF
拿「一個羣體中人的性格,羣體中一我的的性格可能會影響另外一個的性格」舉例:
定義「我從小到大全部認識的人+我女友從小到大全部認識的人」就是這個空間,「空間裏每一個人的性格」都是一個變量,那麼:RF :這個空間裏每一個人的性格變量都是隨機的,全部人的性格變量的集合就是一個RF
MRF :假設如今有這麼個條件,我不認識的人根本不影響個人性格(成對馬爾可夫性),那麼就是MRF了。
CRF:剛纔只說了性格變量互相影響,說的很虛,由於你須要有一些東西衡量性格呀,因此我又假設了一個條件,假設我能觀測到「全部人在認識的人和她接觸時她的笑的時間」,那麼這時候的性格影響就不是那麼不可描述了,我說她天生笑的多就是天生就是性格樂觀,這我的和這我的一塊兒跟她說話他笑得比平均高,那就是這兩我的對他性格樂觀的影響大,這時候你把笑聲考慮進去研究性格,出現了條件機率,那就是CRF了。
線性鏈CRF:上面說的每一個人可能認識不少人,這個狀況就很複雜,你如今在假設一種狀況,每一個人都有編號,你只認識比你大一號或者比你小一號的那兩我的,因而你的性格就只受那兩我的的性格影響,而無論什麼人,他們發出笑聲仍是能或多或少影響你,那就是線性鏈CRF
若是再嚴格一點,不是全部人的笑聲影響你,就你本身真的笑了才影響你,那就是X和Y結構相同的線性鏈CRF,這樣的好處在於最大團的定義的話就是任意被鏈接兩個點都是最大團,比較好計算圖機率
M就是馬爾可夫的意思,表明具備三種馬爾可夫性(等價的,知足一個另外兩個天然知足),就是和我不要緊的點根本不影響個人機率分佈(成對馬爾可夫性);只有和我有關係的才能影響個人機率分佈,整個羣體對個人機率分佈就是周圍人影響下的個人機率分佈(局部馬爾可夫性),個人高中同窗和大學同窗,這兩撥同窗之間互不認識,那麼我對這兩撥同窗的機率分佈的影響是獨立的(全局馬爾可夫性)
C就是條件,沒有C就是意味着探討P(Y)的分佈,有了C就是探討P(Y|X),因此這個C是條件機率下的那個條件的意思。`
其中HMM中,Yi只與Yi-1有關,而Xi輸出只與Yi有關。在MEMM中,Yi 是由Xi和Yi-1肯定的,在CRF中,肯定某個Yi,它會考慮整個Y及Xi的。
這三個模型均可以用來作序列標註模型。可是其各自有自身的特色。
HMM是創建generative model ,即p(x,y) ,轉化爲創建noisy-channel model,即求arg max p(y) p(x|y) ,繼而轉化爲狀態轉移機率p(yi|yi-1) 和發射機率p(xi|yi) 之積,注意這個發射機率,與crf的發射機率不同。建模是對狀態轉移機率和發射機率進行參數估計,從大量的文檔數據中根據統計學來統計。decode過程是使用vertibe算法,利用狀態轉移機率和發射機率計算最優解答,這是一個生成模型。
MEMM是創建conditional model,即 p(y|x) ,轉化爲狀態轉移機率p(yi|x1, ..., xi, yi-1) 。利用這個依賴關係創建Log-Linear Tagging Model,和HMM相比這樣能夠捕捉到更多的feature,而在log linear的過程當中使用局部歸一化,就是針對每個yi, 都要求 exp(θ . f(hi, yi)) / ∑ exp(θ . f(hi, yi)) 。注意歸一化式子的分母對於不一樣的 yi 是不同的,由於不一樣的yi 依賴的 hi 不同。hi 是 yi 的依賴關係,即x1, ..., xi, yi-1。這也就表明在使用vertibe算法decode過程當中,每一時步求的 yi 多多少少有點局部最優的味道,並不必定是全局最優。建模過程是對 θ 進行參數估計,即求結構化的最大似然估計。
crf是創建conditional model,即 p(y|x) ,crf也是Log-Linear Tagging Model,可是依賴關係變成了整個 y 序列依賴整個 x 序列,也就是全局歸一化,優勢就是在decode過程當中,那個歸一化式子的分母是同樣的,最後求得的必定是全局最優,因此decode時只須要求各類狀態轉移機率和發射機率之和就行了,在decode過程當中HMM和MEMM都是求積,爲何crf是各類求和呢,由於它不用求分母,log 分子其實就是各類狀態轉移機率和發射機率之和。
如下源碼出自 CRF++: Yet Another CRF toolkit ,分析主要摘錄 CRF++代碼分析
計算每一個節點和每條邊的代價(也就是特徵函數乘以相應的權值,簡稱代價),就是勢函數。
其中fvector是當前命中特徵函數的起始id集合,對於每一個起始id,都有連續標籤個數種y值;n->y是當前時刻的標籤,因爲每一個特徵函數都必須同時接受x和y才能決定輸出1或0,因此要把二者加起來才能肯定最終特徵函數的id。用此id就能在alpha向量中取到最終的權值,將權值累加起來,乘以一個倍率(也就是所謂的代價參數cost_factor),獲得最終的代價cost。
對於邊來講,也是相似的,只不過對每一個起始id,都有連續標籤個數平方種y值組合。
struct Node { unsigned int x; unsigned short int y; double alpha; double beta; double cost; double bestCost; Node *prev; const int *fvector; std::vector<Path *> lpath; std::vector<Path *> rpath; } struct Path { Node *rnode; Node *lnode; const int *fvector; double cost; } //計算節點的特徵函數的代價 void FeatureIndex::calcCost(Node *n) const { n->cost = 0.0; // 遍歷節點對應的全部特徵函數,由於一個特徵函數可能會對應多個輸出類別,因此要將目前節點的 y 代入,獲得 *f + n->y,就是當前 y 在 f 輸出類別中對應的位置。而後就能夠從alpha向量中取到最終的權值, 再將權值累加。 #define ADD_COST(T, A) \ do { T c = 0; \ for (const int *f = n->fvector; *f != -1; ++f) { c += (A)[*f + n->y]; } \ n->cost =cost_factor_ *(T)c; } while (0) if (alpha_float_) { ADD_COST(float, alpha_float_); } else { ADD_COST(double, alpha_); } #undef ADD_COST } //計算每條邊的狀態特徵函數的代價 void FeatureIndex::calcCost(Path *p) const { p->cost = 0.0; #define ADD_COST(T, A) \ { T c = 0.0; \ for (const int *f = p->fvector; *f != -1; ++f) { \ c += (A)[*f + p->lnode->y * y_.size() + p->rnode->y]; \ } \ p->cost =cost_factor_*(T)c; } if (alpha_float_) { ADD_COST(float, alpha_float_); } else { ADD_COST(double, alpha_); } } #undef ADD_COST }
void TaggerImpl::forwardbackward() { if (x_.empty()) { return; } //計算全部節點的前向機率 for (int i = 0; i < static_cast<int>(x_.size()); ++i) { for (size_t j = 0; j < ysize_; ++j) { node_[i][j]->calcAlpha(); } } //計算全部節點的後向機率 for (int i = static_cast<int>(x_.size() - 1); i >= 0; --i) { for (size_t j = 0; j < ysize_; ++j) { node_[i][j]->calcBeta(); } } //計算規範化因子 Z_ = 0.0; for (size_t j = 0; j < ysize_; ++j) { Z_ = logsumexp(Z_, node_[0][j]->beta, j == 0); } return; } //其中cost是咱們剛剛計算的當前節點的M_i(x),而alpha則是當前節點的前向機率。lpath是入邊,一個頂點可能有多個入邊。 void Node::calcAlpha() { alpha = 0.0; for (const_Path_iterator it = lpath.begin(); it != lpath.end(); ++it) { alpha = logsumexp(alpha, (*it)->cost +(*it)->lnode->alpha, (it == lpath.begin())); } alpha += cost; } void Node::calcBeta() { beta = 0.0; for (const_Path_iterator it = rpath.begin(); it != rpath.end(); ++it) { beta = logsumexp(beta, (*it)->cost +(*it)->rnode->beta, (it == rpath.begin())); } beta += cost; } void Node::calcExpectation(double *expected, double Z, size_t size) const { const double c = std::exp(alpha + beta - cost - Z); for (const int *f = fvector; *f != -1; ++f) { expected[*f + y] += c; } for (const_Path_iterator it = lpath.begin(); it != lpath.end(); ++it) { (*it)->calcExpectation(expected, Z, size); } } #define MINUS_LOG_EPSILON 50 // log(exp(x) + exp(y)); // this can be used recursivly // e.g., log(exp(log(exp(x) + exp(y))) + exp(z)) = // log(exp (x) + exp(y) + exp(z)) inline double logsumexp(double x, double y, bool flg) { if (flg) return y; // init mode const double vmin = std::min(x, y); const double vmax = std::max(x, y); if (vmax > vmin + MINUS_LOG_EPSILON) { return vmax; } else { return vmax + std::log(std::exp(vmin - vmax) + 1.0); } }
其中先後向機率都有了以後,計算規範化因子,此處能看出來是進行全局歸一化:
Z_ = 0.0; for (size_t j = 0; j < ysize_; ++j) { // 注意,這裏是用 node_[0] 位置的 beta 數值,就是說,這個已是用後向機率的最終結果來計算 Z,這個就已是考慮了全局狀況,若是是用 alpha 計算,也得取最終數值,那就須要取 node_[n][j]->alpha 了 Z_ = logsumexp(Z_, node_[0][j]->beta, j == 0); }
推導過程以下:
咱們定義βi(yi|x)表示序列位置i的標記是yi時,在位置i以後的從i+1到n的部分標記序列的非規範化機率。
這樣,咱們很容易獲得序列位置i+1的標記是yi+1時,在位置𝑖i以後的部分標記序列的非規範化機率βi(yi|x)的遞推公式:
\[ 𝛽_𝑖(𝑦_𝑖|𝑥)=𝑀_{𝑖+1}(𝑦_𝑖,𝑦_{𝑖+1}|𝑥)𝛽_{𝑖+1}(𝑦_{𝑖+1}|𝑥) \]
在終點處,咱們定義:
\[ 𝛽_{𝑛+1}(𝑦_{𝑛+1}|𝑥)= \begin{cases} 1 \ 𝑦_{𝑛+1}=𝑠𝑡𝑜𝑝\\ 0 \ 𝑒𝑙𝑠𝑒 \end{cases} \]
若是用向量表示,則有:
\[ 𝛽_𝑖(𝑥)=𝑀_{𝑖+1}(𝑥)𝛽_{𝑖+1}(𝑥) \]
對應着規範化因子Z(x)的表達式是:
\[ 𝑍(𝑥)=∑_{𝑐=1}^𝑚𝛼_𝑛(𝑦𝑐_|𝑥)=∑_{𝑐=1}^𝑚𝛽_1(𝑦_𝑐|𝑥) \]
也能夠用向量來表示Z(x):
\[ \\Z(x) = \alpha_n^T(x) . 1 = 1^T . \beta_1(x) \]
其中,1是 m維全1向量。
所謂的節點指望值指的是節點對應的狀態特徵函數關於條件分佈P(y|x)的數學指望。
/** * 計算節點指望 * @param expected 輸出指望 * @param Z 規範化因子 * @param size 標籤個數 */ void Node::calcExpectation(double *expected, double Z, size_t size) const { const double c = std::exp(alpha + beta - cost - Z); // 機率求和意味着獲得指望 for (const int *f = fvector; *f != -1; ++f) { expected[*f + y] += c; } // 對應邊的指望值 for (const_Path_iterator it = lpath.begin(); it != lpath.end(); ++it) { (*it)->calcExpectation(expected, Z, size); } }
所謂邊的指望指的是邊對應的轉移特徵函數關於條件分佈P(y|x)的數學指望。
/** * 計算邊的指望 * @param expected 輸出指望 * @param Z 規範化因子 * @param size 標籤個數 */ void Path::calcExpectation(double *expected, double Z, size_t size) const { const double c = std::exp(lnode->alpha + cost + rnode->beta - Z); for (const int *f = fvector; *f != -1; ++f) { expected[*f + lnode->y * size + rnode->y] += c; } }
void TaggerImpl::viterbi() { for (size_t i = 0; i < x_.size(); ++i) { for (size_t j = 0; j < ysize_; ++j) { double bestc = -1e37; Node *best = 0; const std::vector<Path *> &lpath = node_[i][j]->lpath; for (const_Path_iterator it = lpath.begin(); it != lpath.end(); ++it) { double cost = (*it)->lnode->bestCost +(*it)->cost + node_[i][j]->cost; if (cost > bestc) { bestc = cost; best = (*it)->lnode; } } node_[i][j]->prev = best; node_[i][j]->bestCost = best ? bestc : node_[i][j]->cost; } } double bestc = -1e37; Node *best = 0; size_t s = x_.size()-1; for (size_t j = 0; j < ysize_; ++j) { if (bestc < node_[s][j]->bestCost) { best = node_[s][j]; bestc = node_[s][j]->bestCost; } } for (Node *n = best; n; n = n->prev) { result_[n->x] = n->y; } cost_ = -node_[x_.size()-1][result_[x_.size()-1]]->bestCost; }
仍是擴展以前的例子
梁山好漢在聚義廳開會,你們共聚一堂,討論招安事宜。可是羣體中好漢會彼此影響投票的選擇。 隨機場 :假定不是按照座次排序,而是隨意坐,這樣你們座位分佈是隨機的。 最大團 :雖然是隨機場,可是好漢們會自動按照小團體站在一塊兒,好比黃門山四人站在一塊兒,三山幫站在一塊兒。這就造成了不少最大團。 馬爾可夫隨機場 :假設如今有這麼個條件,彼此不挨着的好漢不能影響彼此的投票決定(成對馬爾可夫性),這就是MRF。 條件隨機場:假設有一些其餘條件須要考慮,好比若是鐵笛仙馬麟雖然屬於黃門山這個最大團,可是他的位置不當心挨着李逵,那麼他在投票時候,勢必得考慮鐵牛兄弟的意見,否則鐵牛的拳頭不是吃素的。好比曹正雖然屬於三山幫,可是林沖是他師傅,因此他投票也得考慮豹子頭的意見,這就構成了條件場.....
https://blog.csdn.net/asdfsadfasdfsa/article/details/80833781
隱馬爾可夫模型,最大熵模型,最大熵馬爾可夫模型與條件隨機場的比較
CRF算法學習——本身動手實現一個簡單的CRF分詞(java)
https://github.com/1000-7/xinlp
條件隨機場——深刻剖析邏輯斯蒂迴歸和最大熵模型、條件隨機場,他們到底有啥關係?(二)
CRF算法學習——本身動手實現一個簡單的CRF分詞(java)
CRF++: Yet Another CRF toolkit
Why Do We Need Conditional Random Fields?
what are conditional random fields
Sequence Labeling的發展史(HMM,MEMM,CRF)
【PGM】factor graph,因子圖,勢函數potential function,Template models
https://www.zhihu.com/question/35866596/answer/74187736
http://blog.echen.me/2012/01/03/introduction-to-conditional-random-fields/
如何用簡單易懂的例子解釋條件隨機場(CRF)模型?它和HMM有什麼區別
標註偏置問題(Label Bias Problem)和HMM、MEMM、CRF模型比較
如何用簡單易懂的例子解釋條件隨機場(CRF)模型?它和HMM有什麼區別?