自然語言處理系列-4條件隨機場(CRF)及其tensorlofw實現
前些天與一位 NLP 大牛交流,請教其如何提升技術水平,其跟我講務必要重視“ NLP的最基本知識 ”的掌握。掌握好最基本的模型理論,不管是對日常工作和後續論文的發表都有重要的意義。小 Dream 聽了不禁心裡一顫,那些自認為放在“歷史塵埃”裡的機器學習演算法我都只有瞭解了一個大概,至於 NLP 早期的那些大作也鮮有拜讀。心下便決定要好好補一補這個空缺。所以,接下來的數篇文章會相繼介紹在 NLP 中應用比較多的一些機器學習模型,隱馬爾科夫模型( HMM ),條件隨機場( CRF ),樸素貝葉斯,支援向量機( SVM ), EM演算法 等相繼都會聊到,感興趣的朋友可以訂閱我的部落格,或者關注我的微信公眾號,會定期更新 NLP 相關的文章。
好了,廢話不多說,這篇部落格先好好聊聊條件隨機場。
1. 條件隨機場是什麼?
條件隨機場( Conditional Random Field ,簡稱 CRF ),是一種判別式無向圖模型。機器學習最重要的任務,是根據一些已觀察到的證據(例如訓練樣本)來對感興趣的未知變數(例如類別標記)進行估計和推測。概率模型提供這樣一種描述的框架,將學習任務歸結於計算變數的概率分佈。在概率模型中,利用已知變數推測未知變數的分佈稱為“推斷”,其核心是如何基於可觀測變數推測出未知變數的條件分佈。具體來說,假定所關心的變數集合為 Y ,可觀測變數集合為 X ,“生成式”模型直接通過訓練樣本基本聯合概率分佈 P ( Y , X );“判別式”模型通過先計算條件分佈 P ( Y|X ) [1] 。
通俗來講, CRF 是在給定一組變數的情況下,求解另一組變數的條件概率的模型。設 X 與 Y 是隨機變數, P ( Y|X )是給定隨機變數 X 情況下,隨機變數 Y 的條件概率。若隨機變數 Y 構成一個無向圖 G(V,E) (概率圖模型,請看李航,《統計學習方法》 chapter10 ),同時, CRF 滿足如下的條件,
其中, v 表示 G 中的任一節點, v~V 。 n(v) 表示與 v 有邊連線的節點的集合。
在更多的情況下,應用的都是線性鏈條件隨機場,線性鏈條件隨機場這樣定義:
設 X={X 1 ,X 2 ,X 3 ,....X n } , Y={Y 1 ,Y 2 ,Y 3 ,....Y n } 均為線性連結串列示的隨機變數序列,若在給定隨機變數序列 X 的情況下,隨機變數序列 Y 的條件概率 P ( Y|X )構成條件隨機場,其滿足如下的條件:
X 和 Y 具有相同圖結構的線性鏈條件隨機場
從上面的定義可以看出,條件隨機場很適合用於解決序列標註問題問題。例如在分詞問題中, X 可以作為輸入的句子, Y 是分詞的標註結果。
上面應該大致講了條件隨機場是個什麼樣的東西,有什麼樣的性質。可能到目前為止,同志們應該還是有點雲裡霧裡。反正我在第一次看到這個定義的時候,能夠理解上述定義,但是總感覺不通透。後來知道,是沒有跟實際結合起來,所以理解不到位。但是在將實際應用之前,還有一個東西需要介紹,就是條件隨機場的引數化形式。
2. 條件隨機場的引數化形式
我們先列出來 CRF 的引數化形式吧。假設 P ( Y|X )是隨機序列 Y 在給定隨機序列 X 情況下的條件隨機場,則在隨機變數 X 取值為 x 的情況下,隨機變數 Y 的取值 y 具有如下關係:
其中
t k 和 S l 是特徵函式, v k 和 u l 是對應的權值。
好的,假如我們所有的 t k , s l 和 v k , u l 都已知的情況下,我們要算的 P ( Y i =y i |X )是不是就可以算出來啦?已知的有所謂的前向 - 後向演算法。在給定隨機序列 X 的情況下,計算概率最大 Y 序列可以用維特比演算法,感興趣的同學可以看李航,《統計學習方法》 chapter11 ,我這裡就不再贅述了。
網上絕大部分的部落格到這裡就結束了,但是大家應該還有一大堆的疑問, t k , s l 和 v k , u l 如何確定和學習?在實際中我們如何使用?小 Dream 如果只講到這裡,就會太讓大家失望了。下面我們看看在 tensorflow 裡, CRF 是怎麼實現的,以及我們如何使用他,經過這一段,大家對條件隨機場應該就會有一個較為完整的認識了。
3.tensorflow 裡的條件隨機場
因為小 Dream 之前做過一個用 LSTM+CRF 的命名實體識別專案,這一節我們以命名實體識別為例,來介紹在 tensorflow 裡如何使用條件隨機場 (CRF) 。命名實力識別與分詞一樣,是一個序列標註的問題,因為篇幅問題,這裡就不展開,不清楚的同學可以出門百度一下,以後我們再找機會,好好講一下命名實體識別的專案。
LSTM+CRF 網路的主要結構如下:
其他的我們先不看,我們只用知道,自然語言的句子經過神經網路進行特徵提取之後,會得到一個特徵輸出,將這個特徵和相應的標記( label )輸入到條件隨機場中,就可以計算損失了。我們來看看具體的程式碼。
這是我定義的損失層, project_logits 是神經網路最後一層的輸出,該矩陣的 shape 為 [batch_size, num_steps, num_tags], 第一個是 batch size ,第二個是輸入的句子的長度,第三個標記的個數,即命名實體識別總標記的類別數。 targets 是輸入句子的 label ,即每個字的 laibel ,它的維度為 [batch_size, num_steps] 。損失層定義了一個 self.trans 矩陣,大小是 [num_tags+1, num_tags+1] , 加 1 是因為還有一個類別是未定義。
將 project_logit , targets 以及 self.trans 交給 tensorflow 的系統函式 crf_log_likelihood 即可求得損失了。
下面我們進一步來看看 crf_log_likelihood 是怎麼實現的。
從 crf_sequence_score 函式的實現中,我們看出, tf 中的損失值包括一元損失和二元損失。其中 unary_scores 表示的是標記是輸入序列之間的損失, unary_scores 表示的轉化矩陣的損失值。那這兩項到底是什麼呢?是不是和 CRF 的引數化形式感覺有點像?我們看看相關論文 [3] 是怎麼說的。
我們看一下,得分分為兩項,第一項,
它表示輸入句子中,第 i 個詞,相應標記位置的概率。舉個例子,加入輸入的句子是“ Mark Watney visit Mars ” , 相應的 label 是 [B-PER,E-PER,O,S-LOC] ,則 P 1 ,“ B-PER ” 表示的是第一個詞的標記是 B-PER 的概率。所以第一項會是 P 1 ,“ B-PER ” +P 2 ,“ E-PER ” +P 3 ,“ O ” +P 4 ,“ S-LOC ” ,具體在程式碼中,就會取到 project_logits 矩陣中相應的值,這一點交叉熵有點像,同學們體會一下。第二項,
它代表的是真個序列從一個標記轉化到下一個標記的損失值,這個矩陣就是 self.trans ,它最開始是按照我們初始化的方式初始化的,然後會隨著訓練的過程優化。最後再對整個序列的損失值做一個歸一化,也就是執行 crf_log_norm 函式。好了, tensorflow 中 crf 就是這麼實現的,是不是有種忽然開朗的感覺??
我們來做一個總結, CRF 是一個在給定某一個隨機序列的情況下,求另一個隨機序列的概率分佈的概率圖模型,在序列標註的問題中有廣泛的應用。在 tensorflow 中,實現了 crf_log_likelihood 函式。在本文講的命名實體識別專案中,自然語言經是已知的序列,自然語言經過特徵提取過後的 logits 被當作是 t k 函式,隨機初始化的 self.trans 矩陣是 S l 函式,隨著訓練的過程不斷的優化。
這就是條件隨機場要講的全部內容啦,歡迎各位評論。後續更新 HMM , SVM 等,感興趣的朋友可以關注我的部落格或者公眾號。
[1] 周志華 . 機器學習. 清華大學出版社
[2] 李航 統計學習方法 .清華大學出版社
[3]Lample G, Ballesteros M, Subramanian S, et al. Neural architectures for named entity recognition[J]. arXiv preprint arXiv:1603.01360, 2016.
分享時刻:
常常再想,人生大抵苦多樂少。每個人都有太多不想做卻又不得不去做的事。那麼,何不在心中忘苦常樂,就算人生命有定數,也要活的自在。