1. 程式人生 > >Hanlp自然語言處理工具的使用演練

Hanlp自然語言處理工具的使用演練

Hanlp是由一系列模型與演算法組成的工具包,目標是普及自然語言處理在生產環境中的應用。Hanlp具備功能完善、效能高效、架構清洗、語料時新、可自定義的特點;提供詞法分析(中文分詞、磁性標註、命名實體識別)、句法分析、文字分類和情感分析等功能。

本篇將使用者輸入的語句根據詞庫進行分詞、關鍵詞提取、摘要提取、詞庫維護。

工具類名稱:DKNLPBase

1、標準分詞

方法簽名:List StandardTokenizer.segment(String txt);

返回:分詞列表。

簽名引數說明:txt:要分詞的語句。

範例:下例驗證一段話第5個分詞是阿法狗。

程式清單1

public void testSegment() throws Exception

{

    String text = "商品和服務";

    List<Term> termList = DKNLPBase.segment(text);

    assertEquals("商品", termList.get(0).word);

    assertEquals("和", termList.get(1).word);

    assertEquals("服務", termList.get(2).word);

    text = "柯傑解說“李世石VS阿法狗第二局” 結局竟是這樣";

    termList = DKNLPBase.segment(text);

    assertEquals("阿法狗", termList.get(5).word);  // 能夠識別"阿法狗"

}

2、關鍵詞提取

方法簽名:List extractKeyword(String txt,int keySum);

返回:關鍵詞列表.

簽名引數說明:txt:要提取關鍵詞的語句,keySum要提取關鍵詞的數量

範例:給出一段話提取一個關鍵詞是“程式設計師”。

程式清單2

public void testExtractKeyword() throws Exception

{

    String content = "程式設計師(英文Programmer)是從事程式開發、維護的專業人員。" +

            "一般將程式設計師分為程式設計人員和程式編碼人員," +

            "但兩者的界限並不非常清楚,特別是在中國。" +

            "軟體從業人員分為初級程式設計師、高階程式設計師、系統" +

            "分析員和專案經理四大類。";

    List<String> keyword = DKNLPBase.extractKeyword(content, 1);

    assertEquals(1, keyword.size());

    assertEquals("程式設計師", keyword.get(0));

}

3、短語提取

方法簽名:List extractPhrase(String txt, int phSum);

返回:短語

簽名引數說明:txt:要提取短語的語句,phSum短語數量

範例:給出一段文字,能代表文章的五個短語,第一個短語是演算法工程師。

程式清單3

public void testExtractPhrase() throws Exception

{

    String text = "演算法工程師\n" +

            "演算法(Algorithm)是一系列解決問題的清晰指令,也就是說,能夠對一定規範的輸入,在有限時間內獲得所要求的輸出。" +

            "如果一個演算法有缺陷,或不適合於某個問題,執行這個演算法將不會解決這個問題。不同的演算法可能用不同的時間、" +

            "空間或效率來完成同樣的任務。一個演算法的優劣可以用空間複雜度與時間複雜度來衡量。演算法工程師就是利用演算法處理事物的人。\n" +

            "\n" +

            "1職位簡介\n" +

            "演算法工程師是一個非常高階的職位;\n" +

            "專業要求:計算機、電子、通訊、數學等相關專業;\n" +

            "學歷要求:本科及其以上的學歷,大多數是碩士學歷及其以上;\n" +

            "語言要求:英語要求是熟練,基本上能閱讀國外專業書刊;\n" +

            "必須掌握計算機相關知識,熟練使用模擬工具MATLAB等,必須會一門程式語言。\n" +

            "\n" +

            "2研究方向\n" +

            "視訊演算法工程師、影象處理演算法工程師、音訊演算法工程師 通訊基帶演算法工程師\n" +

            "\n" +

            "3目前國內外狀況\n" +

            "目前國內從事演算法研究的工程師不少,但是高階演算法工程師卻很少,是一個非常緊缺的專業工程師。" +

            "演算法工程師根據研究領域來分主要有音訊/視訊演算法處理、影象技術方面的二維資訊演算法處理和通訊物理層、" +

            "雷達訊號處理、生物醫學訊號處理等領域的一維資訊演算法處理。\n" +

            "在計算機音視訊和圖形影象技術等二維資訊演算法處理方面目前比較先進的視訊處理演算法:機器視覺成為此類演算法研究的核心;" +

            "另外還有2D轉3D演算法(2D-to-3D conversion),去隔行演算法(de-interlacing),運動估計運動補償演算法" +

            "(Motion estimation/Motion Compensation),去噪演算法(Noise Reduction),縮放演算法(scaling)," +

            "銳化處理演算法(Sharpness),超解析度演算法(Super Resolution),手勢識別(gesture recognition),人臉識別(face recognition)。\n" +

            "在通訊物理層等一維資訊領域目前常用的演算法:無線領域的RRM、RTT,傳送領域的調製解調、通道均衡、訊號檢測、網路優化、訊號分解等。\n" +

            "另外資料探勘、網際網路搜尋演算法也成為當今的熱門方向。\n" +

            "演算法工程師逐漸往人工智慧方向發展。";

    List<String> phraseList = DKNLPBase.extractPhrase(text, 5);

    assertEquals(5, phraseList.size());

    assertEquals("演算法工程師", phraseList.get(0));

}

4、自動摘要

方法簽名:List extractSummary(String txt, int sSum);

返回:摘要語句

簽名引數說明:txt:要提取摘要的語句,sSum摘要句子數量

範例:自動提取三句摘要句子。

程式清單4

public void testExtractSummary() throws Exception

{

    String document = "演算法可大致分為基本演算法、資料結構的演算法、數論演算法、計算幾何的演算法、圖的演算法、動態規劃以及數值分析、加密演算法、排序演算法、檢索演算法、隨機化演算法、並行演算法、厄米變形模型、隨機森林演算法。\n" +

            "演算法可以寬泛的分為三類,\n" +

            "一,有限的確定性演算法,這類演算法在有限的一段時間內終止。他們可能要花很長時間來執行指定的任務,但仍將在一定的時間內終止。這類演算法得出的結果常取決於輸入值。\n" +

            "二,有限的非確定演算法,這類演算法在有限的時間內終止。然而,對於一個(或一些)給定的數值,演算法的結果並不是唯一的或確定的。\n" +

            "三,無限的演算法,是那些由於沒有定義終止定義條件,或定義的條件無法由輸入的資料滿足而不終止執行的演算法。通常,無限演算法的產生是由於未能確定的定義終止條件。";

    List<String> sentenceList = DKNLPBase.extractSummary(document, 3);

    assertEquals(3, sentenceList.size());

}

5、拼音轉換

方法簽名:List convertToPinyinList(txt);

返回:拼音列表

簽名引數說明:txt:要轉換拼音的語句

範例:給出一段文字中第二個字的拼音。

程式清單5

public void testConvertToPinyinList() throws Exception

{

    String text = "鴨綠江的綠跟綠色的綠不是一個讀音";

    List<Pinyin> pinyinList = DKNLPBase.convertToPinyinList(text);

    assertEquals(text.length(), pinyinList.size());

    assertEquals(Pinyin.lu4, pinyinList.get(1));

}

6、新增詞庫

方法簽名:String addCK(String filePath);

返回:空—完成,其它—錯誤資訊

簽名引數說明:filePath:新的詞庫檔案,每個詞使用回車換行分隔。

範例:讀取新詞庫檔案,將檔案內容中第7個詞“新美“新增到詞庫。

程式清單6

public void testAddCK() throws Exception

{

    DKNLPBase.addCK("src/test/resources/custom_dictionary.txt");

    String text = "網際網路家裝質量問題頻繁 新美大殺入勝算幾何";

    List<Term> termList = DKNLPBase.segment(text);

    assertEquals("新美", termList.get(6).word);

}

7、新詞發現

方法簽名:

NewWordDiscover discover = new NewWordDiscover(max_word_len, min_freq, min_entropy, min_aggregation, filter);

discover.discovery(text, size);

返回:空—完成,其它—錯誤資訊

簽名引數說明:max_word_len: 控制識別結果中最長的詞語長度,預設值是 4;該值越大,運算量越大,結果中出現短語的數量也會越多。

min_freq: 控制結果中詞語的最低頻率,低於該頻率的將會被過濾掉,減少一 些運算量。由於結果是按照頻率排序的,所以該引數其實意義不大。實際上,在介面中直接設為了0,意思是所有候選詞都會出來。

min_entropy: 控制結果中詞語的最低資訊熵(資訊的不確定度)的值,一般取 0.5 左右。該值越 大,越短的詞語就越容易被提取出來。

min_aggregation: 控制結果中詞語的最低互資訊值(字和字之間的關聯性),一般取 50 到 200.該值 越大,越長的詞語就越容易被提取出來,有時候會出現一些短語。

Filter: 設為 true 的時候將使用內部詞庫過濾掉“舊詞”。

Text:用於新詞發現的文件。

Size:新詞個數。

範例:新詞發現。

程式清7

public void testFindNewWord() {

NewWordDiscover discover = new NewWordDiscover(4, 0.0f, 0.5f, 100f, true);

//讀取資料夾下所以文件併合併成一篇文件用於新詞發現

StringBuilder sbText = new StringBuilder();

    File[] txtFiles = new File("src/test/resources/搜狗文字分類語料庫微型版/健康").listFiles();

    int i = 0;

    for (File file : txtFiles)

    {

        System.out.printf("[%d / %d] 讀取 %s 中...\n", ++i, txtFiles.length, file.getName());

        sbText.append(IOUtil.readTxt(file.getPath()));

        if (i == 100) break;

    }

    System.out.printf("對長度為%d的語料進行分析中...\n", sbText.length());

    List<WordInfo> wordInfoList = discover.discovery(sbText.toString(), 10);

    //打印出發現的新詞

    for (WordInfo wordInfo : wordInfoList) {

     System.out.println(wordInfo.text);

}

}

文章來源於網路