在 Maven 專案中使用 HanLP

真實的hello world發表於2020-10-25

今天寫 Java 程式的時候遇到了中文分詞的需求,我找了一個基於 NLP 的中文分詞工具,感覺挺好用的,分享一下。

想要更好的閱讀體驗,可以轉我的個人部落格

匯入Maven庫

pom.xml 中新增,這裡我們使用最新的 1.7.8 版本:

<dependencies>
    <dependency>
        <groupId>com.hankcs</groupId>
        <artifactId>hanlp</artifactId>
        <version>portable-1.7.8</version>
    </dependency>
</dependencies>

下載 data 檔案

根據最新版的 release note ,需要下載 data-for-1.7.5.zip,現在伺服器應該放到國內了,我記得以前下得很慢的,都要在網盤裡備份好多版。

解壓後找到 data 資料夾,移動到 src/main/resources 中,移動完成之後的目錄結構:

.
└── resources
    ├── Z01-Example.txt
    └── data
        ├── README.url
        ├── dictionary
        ├── model
        └── version.txt

data 檔案包括 dictionarymodel 兩部分, HanLP 的大部分庫都會呼叫這些資源,HanLP 還支援自定義的詞典,但不是這篇文章的重點。

下載配置檔案

我不知道 HanLP 的開發者怎麼想的,Mavenportable 版本還缺少一個非常重要的檔案,hanlp.properties

我們需要下載 hanlp-1.7.8-release.zip,因為 hanlp.propertieshanlp-1.7.8-release.zip 裡面。

把這個配置檔案放到專案根目錄中,和 pom.xmlsrc 同級。

.
├── hanlp.properties
├── pom.xml
├── src
└── target

因為前面,我們把 data 檔案放到了 src/main/resources 裡,所以還需要更改 hanlp.properties 中的 root 引數。

#Windows使用者請注意,路徑分隔符統一使用/
root=./src/main/resources

如果不想下載,這是配置改好之後的檔案內容:

#本配置檔案中的路徑的根目錄,根目錄+其他路徑=完整路徑(支援相對路徑,請參考:https://github.com/hankcs/HanLP/pull/254)
#Windows使用者請注意,路徑分隔符統一使用/
root=./src/main/resources

#好了,以上為唯一需要修改的部分,以下配置項按需反註釋編輯。

#核心詞典路徑
#CoreDictionaryPath=data/dictionary/CoreNatureDictionary.txt
#2元語法詞典路徑
#BiGramDictionaryPath=data/dictionary/CoreNatureDictionary.ngram.txt
#自定義詞典路徑,用;隔開多個自定義詞典,空格開頭表示在同一個目錄,使用“檔名 詞性”形式則表示這個詞典的詞性預設是該詞性。優先順序遞減。
#所有詞典統一使用UTF-8編碼,每一行代表一個單詞,格式遵從[單詞] [詞性A] [A的頻次] [詞性B] [B的頻次] ... 如果不填詞性則表示採用詞典的預設詞性。
CustomDictionaryPath=data/dictionary/custom/CustomDictionary.txt; 現代漢語補充詞庫.txt; 全國地名大全.txt ns; 人名詞典.txt; 機構名詞典.txt; 上海地名.txt ns;data/dictionary/person/nrf.txt nrf;
#停用詞詞典路徑
#CoreStopWordDictionaryPath=data/dictionary/stopwords.txt
#同義詞詞典路徑
#CoreSynonymDictionaryDictionaryPath=data/dictionary/synonym/CoreSynonym.txt
#人名詞典路徑
#PersonDictionaryPath=data/dictionary/person/nr.txt
#人名詞典轉移矩陣路徑
#PersonDictionaryTrPath=data/dictionary/person/nr.tr.txt
#繁簡詞典根目錄
#tcDictionaryRoot=data/dictionary/tc
#HMM分詞模型
#HMMSegmentModelPath=data/model/segment/HMMSegmentModel.bin
#分詞結果是否展示詞性
#ShowTermNature=true
#IO介面卡,實現com.hankcs.hanlp.corpus.io.IIOAdapter介面以在不同的平臺(Hadoop、Redis等)上執行HanLP
#預設的IO介面卡如下,該介面卡是基於普通檔案系統的。
#IOAdapter=com.hankcs.hanlp.corpus.io.FileIOAdapter
#感知機詞法分析器
#PerceptronCWSModelPath=data/model/perceptron/pku1998/cws.bin
#PerceptronPOSModelPath=data/model/perceptron/pku1998/pos.bin
#PerceptronNERModelPath=data/model/perceptron/pku1998/ner.bin
#CRF詞法分析器
#CRFCWSModelPath=data/model/crf/pku199801/cws.txt
#CRFPOSModelPath=data/model/crf/pku199801/pos.txt
#CRFNERModelPath=data/model/crf/pku199801/ner.txt
#更多配置項請參考 https://github.com/hankcs/HanLP/blob/master/src/main/java/com/hankcs/hanlp/HanLP.java#L59 自行新增

測試

先在 src/main/resources 下面建立一個 testdata.txt,裡面隨便放點文章。

主類的程式碼:

import java.io.*;

import com.hankcs.hanlp.seg.common.Term;
import com.hankcs.hanlp.tokenizer.NLPTokenizer;

import java.util.List;

public class Main{
    private String text;

    public static void main(String[] args) {
        String fileName = Main.class.getResource("testdata.txt").getFile();
        File file = new File(fileName);
        BufferedReader br;
        StringBuffer sb = new StringBuffer();
        try {
            br = new BufferedReader(new FileReader(file));
            while (br.ready()) {
                sb.append(br.readLine().concat("\n"));
            }
            br.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        final String text = sb.toString();
        List<Term> terms = NLPTokenizer.segment(text);
        System.out.println(terms);
    }
}

相關文章