1. 程式人生 > >HanLP《自然語言處理入門》筆記--5.感知機模型與序列標註

HanLP《自然語言處理入門》筆記--5.感知機模型與序列標註

筆記轉載於GitHub專案:https://github.com/NLP-LOVE/Introduction-NLP

5. 感知機分類與序列標註

第4章我們利用隱馬爾可夫模型實現了第一個基於序列標註的中文分詞器,然而效果並不理想。事實上,隱馬爾可夫模型假設人們說的話僅僅取決於一個隱藏的{B.M,E,S序列,這個假設太單純了,不符合語言規律。語言不是由這麼簡單的標籤序列生成,語言含有更多特徵,而隱馬彌可夫模型沒有捕捉到。隱馬彌可夫模型能捕捉的特徵僅限於兩種: 其一,前一個標籤是什麼;其二,當前字元是什麼。

為了利用更多的特徵,線性模型( linear model )應運而生。線性模型由兩部分構成: 一系列用來提取特徵的特徵函式 φ,以及相應的權重向量 w。

本章將深人講解感知機演算法的原理,以及在分類和序列標註上的應用。在序列標註應用部分,我們將實現基於感知機的中文分詞器。由於感知機序列標註基於分類,並且分類問題更簡單,所以我們先學習分類問題。

5.1 分類問題

  1. 定義

    分類指的是預測樣本所屬類別的一類問題。二分類也可以解決任意類別數的多分類問題(one vs rest)。

    • 將型別class1看作正樣本,其他型別全部看作負樣本,然後我們就可以得到樣本標記型別為該型別的概率 p1。

    • 然後再將另外型別class2看作正樣本,其他型別全部看作負樣本,同理得到 p2。

    • 以此迴圈,我們可以得到該待預測樣本的標記型別分別為型別 class i 時的概率 pi,最後我們取 pi 中最大的那個概率對應的樣本標記型別作為我們的待預測樣本型別。
    • 總之還是以二分類來依次劃分,並求出最大概率結果。

  2. 應用

    在NLP領域,絕大多數任務可以用分類來解決。文字分類天然就是一個分類問題。關鍵詞提取時,對文章中的每個單詞判斷是否屬於關鍵詞,於是轉化為二分類問題。在指代消解問題中,對每個代詞和每個實體判斷是否存在指代關係,又是一個二分類問題。在語言模型中,將詞表中每個單詞作為一種類別,給定上文預測接下來要出現的單詞。

5.2 線性分類模型

線性模型是傳統機器學習方法中最簡單最常用的分類模型,用一條線性的直線或高維平面將資料一分為二。

直線將平面分割為兩部分,分別對應男女。對於任何姓名,計算它落入哪個區域,就能預測它的性別。這樣的區域稱為決策區域,它們的邊界稱為決策邊界。二維空間中,如果決策邊界是直線,則稱為線性分類模型: Y = Wx + b。

如果是任意維度空間中的線性決策邊界統稱為分離超平面

推廣到 D 維空間,分離超平面的方程為:

\[\sum_{i=1}^{D} w_{i} x_{i}+b=0\]

其中,w 是權重,b 偏置(截距),可以寫成向量的形式:

\[\hat{y}={sign}(w \cdot x)=\{\begin{array}{cc}{-1,} {w \cdot x \leqslant 0} \\ {1,} {w \cdot x>0}\end{array}\]
\[ \begin{aligned} &\boldsymbol{w}=\left[w_{1}, \cdots, w_{D}, b\right]\\ &x=\left[x_{1}, \cdots, x_{D}, 1\right] \end{aligned}\\ \hat{y}=\operatorname{sign}(\boldsymbol{w} \cdot \boldsymbol{x})=\left\{\begin{array}{cc} {-1,} & {\boldsymbol{w} \cdot \boldsymbol{x} \leqslant 0} \\ {1,} & {\boldsymbol{w} \cdot \mathbf{x}>0} \end{array}\right. \]

5.3 感知機演算法

找出這個分離超平面其實就是感知機演算法。感知機演算法則是一種迭代式的演算法:在訓練集上執行多個迭代,每次讀入一個樣本,執行預測,將預測結果與正確答案進行對比,計算誤差,根據誤差更新模型引數,再次進行訓練,直到誤差最小為止。

  • 損失函式: 從數值優化的角度來講,迭代式機器學習演算法都在優化(減小)一個損失函式( loss function )。損失函式 J(w) 用來衡量模型在訓練集上的錯誤程度,自變數是模型引數 w,因變數是一個標量,表示模型在訓練集上的損失的大小。
  • 梯度下降: 給定樣本,其特徵向量 x 只是常數,對 J(w) 求導,得到一個梯度向量 Δw,它的反方向一定是當前位置損失函式減小速度最快的方向。如果引數點 w 反方向移動就會使損失函式減小,叫梯度下降。
  • 學習率: 梯度下降的步長叫做學習率。
  • 隨機梯度下降(SGD): 如果演算法每次迭代隨機選取部分樣本計算損失函式的梯度,則稱為隨機梯度下降。

這時候問題來了,假如資料本身線性不可分,感知機損失函式不會收斂,每次迭代分離超平面都會劇烈振盪。這時可以對感知機演算法打補丁,使用投票感知機或平均感知機。

  1. 投票感知機和平均感知機

    投票感知機:每次迭代的模型都保留,準確率也保留,預測時,每個模型都給出自己的結果,乘以它的準確率加權平均值作為最終結果。

    投票感知機要求儲存多個模型及加權,計算開銷較大,更實際的做法是取多個模型的權重的平均,這就是平均感知機。

5.4 基於感知機的人名性別分類

解決人名性別分類的監督學習流程:

  • 標註人名分類語料庫
  • 利用感知機演算法訓練線性模型
  • 利用線性模型給人名分類,評估準確率。
  1. 人名性別語料庫

    筆者整理了一份人名性別語料庫 cnname

    執行下面程式碼後會自動下載。

    預料格式為逗號分隔的 .csv,第一列為姓名,第二列為性別:

    趙伏琴,女
    錢沐楊,男
    孫竹珍,女
    李潮陽,男
  2. 訓練

    程式碼詳見:classify_name.py

    https://github.com/NLP-LOVE/Introduction-NLP/tree/master/code/ch05/classify_name.py

    執行結果如下:

    下載 http://file.hankcs.com/corpus/cnname.zip 到 /usr/local/lib/python3.7/site-packages/pyhanlp/static/data/test/cnname.zip
    100.00%, 1 MB, 256 KB/s, 還有 0 分  0 秒   
    =====樸素感知機演算法=====
    訓練集準確率: P=85.44 R=85.06 F1=85.25
    特徵數量: 9089
    趙建軍=男
    沈雁冰=男
    陸雪琪=女
    李冰冰=女
    測試集準確率: P=82.85 R=82.90 F1=82.88
    =====平均感知機演算法=====
    訓練集準確率: P=93.62 R=83.06 F1=88.02
    特徵數量: 9089
    趙建軍=男
    沈雁冰=男
    陸雪琪=女
    李冰冰=女
    測試集準確率: P=90.92 R=80.39 F1=85.33

5.5 結構化預測問題

自然語言處理問題大致可分為兩類,一種是分類問題,另一種就是結構化預測問題,序列標註只是結構化預測的一個特例,對感知機稍作拓展,分類器就能支援結構化預測。

  1. 定義

    資訊的層次結構特點稱作結構化。那麼結構化預測(structhre,prediction)則是預測物件結構的一類監督學習問題。相應的模型訓練過程稱作結構化學習(stutured laming )。分類問題的預測結果是一個決策邊界, 迴歸問題的預測結果是一個實數標量,而結構化預測的結果則是一個完整的結構。

    自然語言處理中有許多工是結構化預測,比如序列標註預測結構是一整個序列,句法分析預測結構是一棵句法樹,機器翻譯預測結構是一段完整的譯文。這些結構由許多部分構成,最小的部分雖然也是分類問題(比如中文分詞時每個字元分類為{B,M,E,S} ),但必須考慮結構整體的合理程度。

  2. 結構化預測與學習流程

    結構化預測的過程就是給定一個模型 λ 及打分函式 score,利用打分函式給一些備選結構打分,選擇分數最高的結構作為預測輸出,公式如下:
    \[ \hat{y}=\arg \max _{y \in Y} \operatorname{score}_{\lambda}(x, y) \]
    其中,Y 是備選結構的集合。既然結構化預測就是搜尋得分最高的結構 y,那麼結構化學習的目標就是想方設法讓正確答案 y 的得分最高。不同的模型有不同的演算法,對於線性模型,訓練演算法為結構化感知機。

5.6 線性模型的結構化感知機演算法

  1. 結構化感知機演算法

    要讓線性模型支援結構化預測,必須先設計打分函式。打分函式的輸入有兩個缺一不可的引數: 特徵 x 和結構 y。但之前介紹的線性模型的“打分函式”只接受一個自變數 x。

    做法是定義新的特徵函式 ϕ(x,y),把結構 y 也作為一種特徵,輸出新的“結構化特徵向量”。新特徵向量與權重向量做點積後,就得到一個標量,將其作為分數:
    \[ \operatorname{score}(x, y)=w \cdot \phi(x, y) \]
    打分函式有了,取分值最大的結構作為預測結果,得到結構化預測函式:
    \[ \hat{y}=\arg \max _{y \in Y}(w \cdot \phi(x, y)) \]
    預測函式與線性分類器的決策函式很像,都是權重向量點積特徵向量。那麼感知機演算法也可以拓展複用,得到線性模型的結構化學習演算法。

    • 讀入樣本 (x,y),進行結構化預測 \(\hat{y}=\arg \max_{y \in Y}(w \cdot \phi(x, y))\)

    • 與正確答案相比,若不相等,則更新引數: 獎勵正確答案觸發的特徵函式的權重,否則進行懲罰:

      \[w \leftarrow w+\phi\left(x^{(i)}, y\right)-\phi\left(x^{(i)}, \hat{y}\right)\]

    • 還可以調整學習率:

      \[\boldsymbol{w} \leftarrow \boldsymbol{w}+\alpha\left(\phi\left(\boldsymbol{x}^{(i)}, \boldsymbol{y}\right)-\phi\left(\boldsymbol{x}^{(i)}, \hat{\boldsymbol{y}}\right)\right)\]

  2. 與感知機演算法比較

    • 結構化感知機修改了特徵向量。
    • 結構化感知機的引數更新賞罰分明。
  3. 結構化感知機與序列標註

    上面已經講了結構化感知機的模型公式,看如何運用到序列標註上,我們知道序列標註最大的結構特點就是標籤相互之間的依賴性,這種依賴性利用初始狀態概率想倆狗和狀態轉移概率矩陣體系那,那麼對於結構化感知機,就可以使用轉移特徵來表示:
    \[ \phi_{k}\left(y_{t-1}, y_{t}\right)=\left\{\begin{array}{ll} {1,} & {y_{t-1}=s_{i}, \mathrm{H} y_{t}=s_{j}} \\ {0,} & {其他 } \end{array} \quad i=0, \cdots, N ; j=1, \cdots, N\right. \]
    其中,Yt 為序列第 t 個標籤,Si 為標註集第 i 種標籤,N 為標註集大小。

    狀態特徵如下,類似於隱馬爾可夫模型的發射概率矩陣,狀態特徵只與當前的狀態有關,與之前的狀態無關:
    \[ \phi_{i}\left(x_{i}, y_{i}\right)=\left\{\begin{array}{l} {1} \\ {0} \end{array}\right. \]
    於是,結構化感知機的特徵函式就是轉移特徵和狀態特徵的合集:
    \[ \phi=\left[\phi_{k} ; \phi_{l}\right] \quad k=1, \cdots, N^{2}+N ; l=N^{2}+N+1, \cdots \]
    基於以上公式,我們統一用打分函式來表示:
    \[ \operatorname{score}(\boldsymbol{x}, \boldsymbol{y})=\sum_{t=1}^{T} \boldsymbol{w} \cdot \phi\left(y_{t-1}, y_{t}, \boldsymbol{x}_{t}\right) \]
    有了打分公式,就可以利用維特比演算法求解得分最高的序列。

5.7 基於結構化感知機的中文分詞

程式碼詳見(註釋寫得很清楚): perceptron_cws.py

https://github.com/NLP-LOVE/Introduction-NLP/tree/master/code/ch05/perceptron_cws.py

執行以上程式碼結果如下:

P:96.68 R:96.51 F1:96.59 OOV-R:71.54 IV-R:97.18
[王思斌, ,, 男, ,, 1949年10月, 生, 。]
[山東, 桓臺縣, 起鳳鎮, 穆寨村, 婦女, 穆玲英]
[現, 為, 中國藝術研究院中國文化研究所, 研究員, 。]
[我們, 的, 父母, 重, 男, 輕, 女]
[北京輸氣管道, 工程]

準確性與效能的比較

演算法 P R F1 R(oov) R(IV)
最長匹配 89.41 94.64 91.95 2.58 97.14
二元語法 92.38 96.70 94.49 2.58 99.26
一階HHM 78.49 80.38 79.42 41.11 81.44
二階HHM 78.34 80.01 79.16 42.06 81.04
平均感知機 96.69 96.45 96.57 70.34 97.16
結構化感知機 96.67 96.64 96.65 70.52 97.35

對比各項指標,我們終於將 OOV 提高到了 70% 以上,並且綜合 F1 也提高了 96.7%,感知機是截止到這章最好用的演算法,完全達到了實用水平,在實際專案中,無非還需要掛載一些領域詞庫。

5.8 GitHub

HanLP何晗--《自然語言處理入門》筆記:

https://github.com/NLP-LOVE/Introduction-NLP

專案持續更新中......

目錄


<
章節
第 1 章:新手上路
第 2 章:詞典分詞
第 3 章:二元語法與中文分詞
第 4 章:隱馬爾可夫模型與序列標註
第 5 章:感知機分類與序列標註
第 6 章:條件隨機場與序列標註
第 7 章:詞性標註
第 8 章:命名實體識別
第 9 章:資訊抽取
第 10 章:文字聚類
第 11 章:文字分類
第 12 章:依存句法分析
第 13 章:深度學習與自然語言處理