词典

本章详细介绍HanLP中的词典格式,满足用户自定义的需要。HanLP中有许多词典,它们的格式都是相似的,形式都是文本文档,随时可以修改。

基本格式

词典分为词频词性词典和词频词典。

词频词性词典

每一行代表一个单词,格式遵从[单词] [词性A] [A的频次] [词性B] [B的频次] ...。

动态修改

用户甚至可以通过代码动态修改词频词性词典:

// 动态增加
CustomDictionary.add("孔雀女");
// 强行插入
CustomDictionary.insert("码农", "nz 1024");
// 删除词语(注释掉试试)
// CustomDictionary.remove("码农");
System.out.println(CustomDictionary.add("裸婚", "v 2 nz 1"));
System.out.println(CustomDictionary.get("裸婚"));

String text = "码农和孔雀女裸婚了";  // 怎么可能噗哈哈!

// AhoCorasickDoubleArrayTrie自动机分词
final char[] charArray = text.toCharArray();
CoreDictionary.trie.parseText(charArray, new AhoCorasickDoubleArrayTrie.IHit<CoreDictionary.Attribute>()
{
    @Override
    public void hit(int begin, int end, CoreDictionary.Attribute value)
    {
        System.out.printf("[%d:%d]=%s %s\n", begin, end, new String(charArray, begin, end - begin), value);
    }
});
// trie树分词
BaseSearcher searcher = CustomDictionary.getSearcher(text);
Map.Entry entry;
while ((entry = searcher.next()) != null)
{
    System.out.println(entry);
}

// 标准分词
System.out.println(HanLP.segment(text));
  • 基本说明
    • CustomDictionary 是一份全局的用户自定义词典,可以随时增删,影响全部分词器。
    • 另外可以在任何分词器中关闭它。通过代码动态增删不会保存到词典文件。
  • 追加词典
    • CustomDictionary 主词典文本路径是 data/dictionary/custom/CustomDictionary.txt ,用户可以在此增加自己的词语(不推荐);也可以单独新建一个文本文件,通过配置文件 CustomDictionaryPath=data/dictionary/custom/CustomDictionary.txt; 我的词典.txt; 来追加词典(推荐)。
    • 始终建议将相同词性的词语放到同一个词典文件里,便于维护和分享。
  • 词典格式
    • 每一行代表一个单词,格式遵从 [单词] [词性A] [A的频次] [词性B] [B的频次] ... 如果不填词性则表示采用词典的默认词性。
    • 词典的默认词性默认是名词n,可以通过配置文件修改: 全国地名大全.txt ns; 如果词典路径后面空格紧接着词性,则该词典默认是该词性。
    • 关于用户词典的更多信息请参考 词频词典 一节。

词频词典

每一行代表一个单词,格式遵从[单词] [单词的频次]。 每一行的分隔符为空格符或制表符 少数词典有自己的专用格式,比如同义词词典兼容《同义词词林扩展版》的文本格式,而转移矩阵词典则是一个csv表格。

下文主要介绍通用词典,如不注明,词典特指通用词典。

数据结构

Trie树(字典树)是HanLP中使用最多的数据结构,为此,我实现了通用的Trie树,支持泛型、遍历、储存、载入。

用户自定义词典采用AhoCorasickDoubleArrayTrie和二分Trie树储存,其他词典采用基于双数组Trie树(DoubleArrayTrie)实现的AC自动机AhoCorasickDoubleArrayTrie。

储存形式

词典有两个形态:文本文件(filename.txt)和缓存文件(filename.txt.bin或filename.txt.trie.dat和filename.txt.trie.value)。

文本文件

采用明文储存,UTF-8编码,CRLF换行符。

缓存文件

就是一些二进制文件,通常在文本文件的文件名后面加上.bin表示。有时候是.trie.dat和.trie.value。后者是历史遗留产物,分别代表trie树的数组和值。 如果你修改了任何词典,只有删除缓存才能生效。

修改方法

HanLP的核心词典训练自人民日报2014语料,语料不是完美的,总会存在一些错误。这些错误可能会导致分词出现奇怪的结果,这时请打开调试模式排查问题:

HanLP.Config.enableDebug();

核心词性词频词典

比如你在 data/dictionary/CoreNatureDictionary.txt 中发现了一个不是词的词,或者词性标注得明显不对,那么你可以修改它,然后删除缓存文件使其生效。

核心二元文法词典

二元文法词典 data/dictionary/CoreNatureDictionary.ngram.txt 储存的是两个词的接续,如果你发现不可能存在这种接续时,删掉即可。 你也可以添加你认为合理的接续,但是这两个词必须同时在核心词典中才会生效。

命名实体识别词典

基于角色标注的命名实体识别比较依赖词典,所以词典的质量大幅影响识别质量。 这些词典的格式与原理都是类似的,请阅读相应的文章或代码修改它。 如果问题解决了,欢迎向我提交一个pull request,这是我在代码库中保留明文词典的原因,众人拾柴火焰高!