9. HanLP《天然語言處理入門》筆記--9.關鍵詞、關鍵句和短語提取

筆記轉載於GitHub項目https://github.com/NLP-LOVE/Introduction-NLPpython

9. 信息抽取

信息抽取是一個寬泛的概念,指的是從非結構化文本中提取結構化信息的一類技術。這類技術依然分爲基於規則的正則匹配、有監督學習和無監督學習等各類實現方法。咱們將使用一些簡單實用的無監督學習方法。因爲不須要標註語料庫,因此能夠利用海量的非結構化文本。git

本章按照顆粒度從小到大的順序,介紹抽取新詞、關鍵詞、關鍵短語和關鍵句的無監督學習方法。程序員

9.1 新詞提取

  1. 概述github

    新詞是一個相對的概念,每一個人的標準都不同,因此咱們這裏定義: 詞典以外的詞語(OOV)稱做新詞算法

    新詞的提取對中文分詞而言具備重要的意義,由於語料庫的標註成本很高。那麼如何修訂領域詞典呢,此時,無監督的新詞提取算法就體現了現實意義。編程

  2. 基本原理網絡

    • 提取出大量文本(生語料)中的詞語,不管新舊。
    • 用詞典過濾掉已有的詞語,因而獲得新詞。

    步驟 2 很容易,關鍵是步驟 1,如何無監督的提取出文本中的單詞。給定一段文本,隨機取一個片斷,若是這個片斷左右的搭配很豐富,而且片斷內部成分搭配很固定,則能夠認爲這是一個詞。將這樣的片斷篩選出來,按照頻次由高到低排序,排在前面的有很高几率是詞。編程語言

    若是文本足夠大,再用通用的詞典過濾掉「舊詞」,就能夠獲得「新詞」。工具

    片斷外部左右搭配的豐富程度,能夠用信息熵來衡量,而片斷內部搭配的固定程度能夠用子序列的互信息來衡量。學習

  3. 信息熵

    在信息論中,信息熵( entropy )指的是某條消息所含的信息量。它反映的是據說某個消息以後,關於該事件的不肯定性的減小量。好比拋硬幣以前,咱們不知道「硬幣正反」這個事件的結果。可是一旦有人告訴咱們「硬幣是正面」這條消息,咱們對該次拋硬幣事件的不肯定性當即降爲零,這種不肯定性的減少量就是信息熵。公式以下:
    \[ H(X)=-\sum_{x} p(x) \log p(x) \]
    給定字符串 S 做爲詞語備選,X 定義爲該字符串左邊可能出現的字符(左鄰字),則稱 H(X) 爲 S 的左信息熵,相似的,定義右信息熵 H(Y),例以下列句子:

    兩隻蝴蝶飛啊飛

    這些蝴蝶飛走了

    那麼對於字符串蝴蝶,它的左信息熵爲1,而右信息熵爲0。由於生語料庫中蝴蝶的右鄰字必定是飛。假如咱們再收集一些句子,好比「蝴蝶效應」「蝴蝶蛻變」之類,就會觀察到右信息熵會增大很多。

    左右信息熵越大,說明字符串可能的搭配就越豐富,該字符串就是一個詞的可能性就越大。

    光考慮左右信息熵是不夠的,好比「吃了一頓」「看了一遍」「睡了一晚」「去了一趟」中的了一的左右搭配也很豐富。爲了更好的效果,咱們還必須考慮詞語內部片斷的凝聚程度,這種凝聚程度由互信息衡量。

  4. 互信息

    互信息指的是兩個離散型隨機變量 X 與 Y 相關程度的度量,定義以下:
    \[ \begin{aligned} I(X ; Y) &=\sum_{x, y} p(x, y) \log \frac{p(x, y)}{p(x) p(y)} \\ &=E_{p(x, y)} \log \frac{p(x, y)}{p(x) p(y)} \end{aligned} \]
    互信息的定義能夠用韋恩圖直觀表達:

    其中,左圓圈表示H(X),右圓圈表示H(Y)。它們的並集是聯合分佈的信息熵H(X,Y),差集有多件嫡,交集就是互信息。可見互信息越大,兩個隨機變量的關聯就越密切,或者說同時發生的可能性越大。

    片斷可能有多種組合方式,計算上能夠選取全部組合方式中互信息最小的那一種爲表明。有了左右信息熵和互信息以後,將兩個指標低於必定閾值的片斷過濾掉,剩下的片斷按頻次降序排序,截取最高頻次的 N 個片斷即完成了詞語提取流程。

  5. 實現

    咱們用四大名著來提起100個高頻詞。

    代碼請見(語料庫自動下載): extract_word.py

    https://github.com/NLP-LOVE/Introduction-NLP/tree/master/code/ch09/extract_word.py

    運行結果以下:

    雖然咱們沒有在古典文學語料庫上進行訓練,但新詞識別模塊成功的識別出了麝月、高太尉等生僻詞語,該模塊也適用於微博等社交媒體的不規範文本。

9.2 關鍵詞提取

詞語顆粒度的信息抽取還存在另外一個需求,即提取文章中重要的單詞,稱爲關鍵詞提起。關鍵詞也是一個沒有定量的標準,沒法統一語料庫,因此就能夠利用無監督學習來完成。

分別介紹詞頻、TF-IDF和TextRank算法,單文檔提起能夠用詞頻和TextRank,多文檔可使用TF-IDF來提取關鍵詞。

  1. 詞頻統計

    關鍵詞一般在文章中反覆出現,爲了解釋關鍵詞,做者一般會反覆說起它們。經過統計文章中每種詞語的詞頻並排序,能夠初步獲取部分關鍵詞。

    不過文章中反覆出現的詞語卻不必定是關鍵詞,例如「的」。因此在統計詞頻以前須要去掉停用詞。

    詞頻統計的流程通常是分詞、停用詞過濾、按詞頻取前 n 個。其中,求 m 個元素中前 n (n<=m) 大元素的問題一般經過最大堆解決,複雜度爲 O(mlogn)。HanLP代碼以下:

    from pyhanlp import *
    
    TermFrequency = JClass('com.hankcs.hanlp.corpus.occurrence.TermFrequency')
    TermFrequencyCounter = JClass('com.hankcs.hanlp.mining.word.TermFrequencyCounter')
    
    if __name__ == '__main__':
        counter = TermFrequencyCounter()
        counter.add("加油加油中國隊!")  # 第一個文檔
        counter.add("中國觀衆高呼加油中國")  # 第二個文檔
        for termFrequency in counter:  # 遍歷每一個詞與詞頻
            print("%s=%d" % (termFrequency.getTerm(), termFrequency.getFrequency()))
        print(counter.top(2))  # 取 top N
    
        #  根據詞頻提取關鍵詞
        print('')
        print(TermFrequencyCounter.getKeywordList("女排奪冠,觀衆歡呼女排女排女排!", 3))

    運行結果以下:

    中國=2
    中國隊=1
    加油=3
    觀衆=1
    高呼=1
    [加油=3, 中國=2]
    
    [女排, 觀衆, 歡呼]

    用詞頻來提取關鍵詞有一個缺陷,那就是高頻詞並不等價於關鍵詞。好比在一個體育網站中,全部文章都是奧運會報道,致使「奧運會」詞頻最高,用戶但願經過關鍵詞看到每篇文章的特點。此時,TF-IDF 就派上用場了。

  2. TF-IDF

    TF-IDF (Term Frequency-lnverse Document Frequency,詞頻-倒排文檔頻次)是信息檢索中衡量一個詞語重要程度的統計指標,被普遍用於Lucene、Solr、Elasticsearch 等搜索引擎。

    相較於詞頻,TF-IDF 還綜合考慮詞語的稀有程度。在TF-IDF計算方法中,一個詞語的重要程度不光正比於它在文檔中的頻次,還反比於有多少文檔包含它。包含該詞語的文檔趣多,就說明它越寬泛, 越不能體現文檔的特點。 正是由於須要考慮整個語料庫或文檔集合,因此TF-IDF在關鍵詞提取時屬於多文檔方法。

    計算公式以下:
    \[ \begin{aligned} \mathrm { TF } - \operatorname { IDF } ( t , d ) & = \frac { \mathrm { TF } ( t , d ) } { \mathrm { DF } ( t ) } \\ & = \mathrm { TF } ( t , d ) \cdot \mathrm { IDF } ( t ) \end{aligned} \]
    其中,t 表明單詞,d 表明文檔,TF(t,d) 表明 t 在 d 中出現頻次,DF(t) 表明有多少篇文檔包含 t。DF 的導數稱爲IDF,這也是 TF-IDF 得名的由來。

    固然,實際應用時作一些擴展,好比加一平滑、IDF取對數以防止浮點數下溢出。HanLP的示例以下:

    from pyhanlp import *
    
    TfIdfCounter = JClass('com.hankcs.hanlp.mining.word.TfIdfCounter')
    
    if __name__ == '__main__':
        counter = TfIdfCounter()
        counter.add("《女排奪冠》", "女排北京奧運會奪冠")  # 輸入多篇文檔
        counter.add("《羽毛球男單》", "北京奧運會的羽毛球男單決賽")
        counter.add("《女排》", "中國隊女排奪北京奧運會金牌重返巔峯,觀衆歡呼女排女排女排!")
        counter.compute()  # 輸入完畢
        for id in counter.documents():
            print(id + " : " + counter.getKeywordsOf(id, 3).toString())  # 根據每篇文檔的TF-IDF提取關鍵詞
        # 根據語料庫已有的IDF信息爲語料庫以外的新文檔提取關鍵詞
    
        print('')
        print(counter.getKeywords("奧運會反興奮劑", 2))

    運行後以下:

    《女排》 : [女排=5.150728289807123, 重返=1.6931471805599454, 巔峯=1.6931471805599454]
    《女排奪冠》 : [奪冠=1.6931471805599454, 女排=1.2876820724517808, 奧運會=1.0]
    《羽毛球男單》 : [決賽=1.6931471805599454, 羽毛球=1.6931471805599454, 男單=1.6931471805599454]
    
    [反, 興奮劑]

    觀察輸出結果,能夠看出 TF-IDF 有效的避免了給予「奧運會」這個寬泛的詞語太高的權重。

    TF-IDF在大型語料庫上的統計相似於一種學習過程,假如咱們沒有這麼大型的語料庫或者存儲IDF的內存,同時又想改善詞頻統計的效果該怎麼辦呢?此時可使用TextRank算法。

  3. TextRank

    TextRank 是 PageRank 在文本中的應用,PageRank是一種用於排序網頁的隨機算法,它的工做原理是將互聯網看做有向圖,互聯網上的網頁視做節點,節點 Vi 到節點 Vj 的超連接視做有向邊,初始化時每一個節點的權重 S(Vi) 都是1,以迭代的方式更新每一個節點的權重。每次迭代權重的更新表達式以下:
    \[ S \left( V _ { i } \right) = ( 1 - d ) + d \times \sum _ { V _ { j \in I n \left( V _ { i } \right) } } \frac { 1 } { \left| O u t \left( V _ { j } \right) \right| } S \left( V _ { j } \right) \]
    其中 d 是一個介於 (0,1) 之間的常數因子,在PagRank中模擬用戶點擊連接從而跳出當前網站的機率,In(Vi) 表示連接到 Vi 的節點集合,Out(Vj) 表示從 Vj 出發連接到的節點集合。可見,開不是外鏈越多,網站的PageRank就越高。網站給別的網站作外鏈越多,每條外鏈的權重就越低。若是一個網站的外鏈都是這種權重很低的外鏈,那麼PageRank也會降低,形成不良反應。正所謂物以類聚,垃圾網站推薦的連接每每也是垃圾網站。所以PageRank可以比較公正的反映網站的排名。

    將 PageRank 應用到關鍵詞提取,無非是將單詞視做節點而已,另外,每一個單詞的外鏈來自自身先後固定大小的窗口內的全部單詞。

    HanLP實現的代碼以下:

    from pyhanlp import *
    
    """ 關鍵詞提取"""
    content = (
    "程序員(英文Programmer)是從事程序開發、維護的專業人員。"
    "通常將程序員分爲程序設計人員和程序編碼人員,"
    "但二者的界限並不很是清楚,特別是在中國。"
    "軟件從業人員分爲初級程序員、高級程序員、系統"
    "分析員和項目經理四大類。")
    
    TextRankKeyword = JClass("com.hankcs.hanlp.summary.TextRankKeyword")
    keyword_list = HanLP.extractKeyword(content, 5)
    print(keyword_list)

    運行結果以下:

    [程序員, 程序, 分爲, 人員, 軟件]

9.3 短語提取

在信息抽取領域,另外一項重要的任務就是提取中文短語,也即固定多字詞表達串的識別。短語提取常常用於搜索引擎的自動推薦,文檔的簡介生成等。

利用互信息和左右信息熵,咱們能夠輕鬆地將新詞提取算法拓展到短語提取。只需將新詞提取時的字符替換爲單詞, 字符串替換爲單詞列表便可。爲了獲得單詞,咱們依然須要進行中文分詞。 大多數時候, 停用詞對短語含義表達幫助不大,因此一般在分詞後過濾掉。

代碼以下:

from pyhanlp import *

""" 短語提取"""
text = '''
  算法工程師
  算法(Algorithm)是一系列解決問題的清晰指令,也就是說,可以對必定規範的輸入,在有限時間內得到所要求的輸出。
  若是一個算法有缺陷,或不適合於某個問題,執行這個算法將不會解決這個問題。不一樣的算法可能用不一樣的時間、
  空間或效率來完成一樣的任務。一個算法的優劣能夠用空間複雜度與時間複雜度來衡量。算法工程師就是利用算法處理事物的人。

  1職位簡介
  算法工程師是一個很是高端的職位;
  專業要求:計算機、電子、通訊、數學等相關專業;
  學歷要求:本科及其以上的學歷,大多數是碩士學歷及其以上;
  語言要求:英語要求是熟練,基本上能閱讀國外專業書刊;
  必須掌握計算機相關知識,熟練使用仿真工具MATLAB等,必須會一門編程語言。

  2研究方向
  視頻算法工程師、圖像處理算法工程師、音頻算法工程師 通訊基帶算法工程師

  3目前國內外情況
  目前國內從事算法研究的工程師很多,可是高級算法工程師卻不多,是一個很是緊缺的專業工程師。
  算法工程師根據研究領域來分主要有音頻/視頻算法處理、圖像技術方面的二維信息算法處理和通訊物理層、
  雷達信號處理、生物醫學信號處理等領域的一維信息算法處理。
  在計算機音視頻和圖形圖像技術等二維信息算法處理方面目前比較先進的視頻處理算法:機器視覺成爲此類算法研究的核心;
  另外還有2D轉3D算法(2D-to-3D conversion),去隔行算法(de-interlacing),運動估計運動補償算法
  (Motion estimation/Motion Compensation),去噪算法(Noise Reduction),縮放算法(scaling),
  銳化處理算法(Sharpness),超分辨率算法(Super Resolution) 手勢識別(gesture recognition) 人臉識別(face recognition)。
  在通訊物理層等一維信息領域目前經常使用的算法:無線領域的RRM、RTT,傳送領域的調製解調、信道均衡、信號檢測、網絡優化、信號分解等。
  另外數據挖掘、互聯網搜索算法也成爲當今的熱門方向。
  算法工程師逐漸往人工智能方向發展。'''
 
phrase_list = HanLP.extractPhrase(text, 5)
print(phrase_list)

運行結果以下:

[算法工程師, 算法處理, 一維信息, 算法研究, 信號處理]

目前該模塊只支持提取二元語法短語。在另外一些場合,關鍵詞或關鍵短語依然顯得碎片化,不足以表達完整的主題。這時一般提取中心句子做爲文章的簡短摘要,而關鍵句的提取依然是基於 PageRank 的拓展。

9.4 關鍵句提取

因爲一篇文章中幾乎不可能出現相同的兩個句子,因此樸素的 PageRank 在句子顆粒度上行不通。爲了將 PageRank 利用到句子顆粒度上去,咱們引人 BM25 算法衡量句子的類似度,改進連接的權重計算。這樣窗口的中心句與相鄰的句子間的連接變得有強有弱,類似的句子將獲得更高的投票。而文章的中心句每每與其餘解釋說明的句子存在較高的類似性,這剛好爲算法提供了落腳點。本節將先介紹BM25算法,後介紹TextRank在關鍵句提取中的應用。

  1. BM25

    在信息檢索領域中,BM25 是TF-IDF的一種改進變種。TF-IDF衡量的是單個詞語在文檔中的重要程度,而在搜索引擎中,查詢串(query)每每是由多個詞語構成的。如何衡量多個詞語與文檔的關聯程度,就是BM25所解決的問題。

    形式化的定義 Q 爲查詢語句,由關鍵字 q1 到 qn 組成,D 爲一個被檢索的文檔,BM25度量以下:
    \[ \operatorname { BM } 25 ( D , Q ) = \sum _ { i = 1 } ^ { n } \operatorname { IDF } \left( q _ { i } \right) \cdot \frac { \operatorname { TF } \left( q _ { i } , D \right) \cdot \left( k _ { 1 } + 1 \right) } { \operatorname { TF } \left( q _ { i } , D \right) + k _ { 1 } \cdot \left( 1 - b + b \cdot \frac { | D | } { \operatorname { avg } D L } \right) } \]

  2. TextRank

    有了BM25算法以後,將一個句子視做查詢語句,相鄰的句子視做待查詢的文檔,就能獲得它們之間的類似度。以此類似度做爲 PageRank 中的連接的權重,因而獲得一種改進算法,稱爲TextRank。它的形式化計算方法以下:
    \[ \mathrm{WS}\left(V_{i}\right)=(1-d)+d \times \sum_{V_{j} \in \ln \left(V_{i}\right)} \frac{\mathrm{BM} 25\left(V_{i}, V_{j}\right)}{\sum_{V_{k} \in O u t\left(V_{j}\right)} \operatorname{Bu} 2 \mathrm{s}\left(V_{k}, V_{j}\right)} \mathrm{WS}\left(V_{j}\right) \]
    其中,WS(Vi) 就是文檔中第 i 個句子的得分,重複迭代該表達式若干次以後獲得最終的分值,排序後輸出前 N 個即獲得關鍵句。代碼以下:

    from pyhanlp import *
    
    """自動摘要"""
    document = '''水利部水資源司司長陳明忠9月29日在國務院新聞辦舉行的新聞發佈會上透露,
    根據剛剛完成了水資源管理制度的考覈,有部分省接近了紅線的指標,
    有部分省超過紅線的指標。對一些超過紅線的地方,陳明忠表示,對一些取用水項目進行區域的限批,
    嚴格地進行水資源論證和取水許可的批准。'''
    
    TextRankSentence = JClass("com.hankcs.hanlp.summary.TextRankSentence")
    sentence_list = HanLP.extractSummary(document, 3)
    print(sentence_list)

    結果以下:

    [嚴格地進行水資源論證和取水許可的批准, 水利部水資源司司長陳明忠9月29日在國務院新聞辦舉行的新聞發佈會上透露, 有部分省超過紅線的指標]

9.5 總結

咱們看到,新詞提取與短語提取,關鍵詞與關鍵句的提取,在原理上都是同一種算法在不一樣文本顆粒度上的應用。值得一提的是, 這些算法都不須要標註語料的參與,知足了人們「坐享其成」的慾望。然而必須指出的是,這些算法的效果很是有限。對於同一個任務,監督學習方法的效果一般遠遠領先於無監督學習方法。

9.6 GitHub

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

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

項目持續更新中......

目錄


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