DAT加载用户词典分词问题

  1. 运行耗时很长,报错Java heap space
    原句子:
    合闸1SB2按钮卡涩、粘连,未完全复位,处于导通状态,操作人员合上主空气开关QA后,合闸回路接通,接触器动作合闸,导致电机误启动。

参照书上P72,加载化工类字典,运行时报错:
Exception in thread “main” java.lang.OutOfMemoryError: Java heap space

在删除原句子中的 “QA” 后,正常运行。

查找加载的字典,有如下词语:
阳离子醚化剂QA-188;OQA;DMQA;MAQ

  1. 词性问题。(加载字典,默认词性设置为nchem)
    删除原句子中的 “QA”,分词结果如下:
    合闸/v, 1/nchem, SB/nchem, 2/nchem, 按钮/n, 卡/n, 涩/an, 、/w, 粘连/v, ,/w,……

加载的字典中,有大量化工物质名称,如:
2,6-二氯苯甲酸;1,1,3,3-四甲基-1,3-二苯基二硅氧烷;1,2-丙二醇

  1. 正常分词情况
    原句子:
    “该工厂储存有大量的1,2-苯二胺,1,2-苯二酚,1,4-苯二酚”
    分词结果:
    [该/r, 工厂/n, 储存/v, 有/v, 大量/m, 的/uj, 1,2-苯二胺/nchem, ,/w, 1,2-苯二酚/nchem, ,/w, 1,4-苯二酚/nchem]
    (在这句话里加上 “QA” 也会报错)

我理解应该是词典生成树导致的,请教大佬能不能讲讲具体是啥原因。

请提供复现代码。

感谢何博士回复,代码是 HanLp-1.x项目的DemoDoubleArrayTrieSegment.java 中修改了测试文本。

句子1:
该工厂储存有大量的1,2-苯二胺,1,2-苯二酚,1,4-苯二酚

句子2:
合闸按钮1SB2卡涩、粘连,未完全复位,处于导通状态,操作人员合上主空气开关QA后,合闸回路接通,接触器动作合闸,导致电机误启动

加载自定义词典,报错

删除原句子中的QA,正常运行但词性存在问题

没有上传文件的权限,截个字典的图,都是些化学品名词,一共136295个词。

GitHub有权限,请上传代码和词典。

发现是自己上传字典格式有问题显示的无权限(好像不支持上传txt格式)。
另外,字典文件超出上传文件大小限制,拆分了部分出来。ChemSubstanceName1.rar (235.4 KB)

拆分过程中发现应该是跟字典中某些特定词有关,由于某些词语的存在导致bug,并且导致数字词性出错,但背后到底为啥我不太懂。

代码如下
···Java

package com.hankcs.book.ch02;

import com.hankcs.hanlp.HanLP;
import com.hankcs.hanlp.seg.Other.DoubleArrayTrieSegment;
import com.hankcs.hanlp.seg.common.Term;

import java.io.IOException;
/**
* 《自然语言处理入门》2.8 HanLP的词典分词实现
* 配套书籍:http://nlp.hankcs.com/book.php
* 讨论答疑:https://bbs.hankcs.com/
*
* @author hankcs
* @see <a href="http://nlp.hankcs.com/book.php">《自然语言处理入门》</a>
* @see <a href="https://bbs.hankcs.com/">讨论答疑</a>
*/
public class DemoDoubleArrayTrieSegment
{
    public static void main(String[] args) throws IOException
    {
        HanLP.Config.ShowTermNature = false; // 分词结果不显示词性
        // 默认加载配置文件指定的 CoreDictionaryPath
        DoubleArrayTrieSegment segment = new DoubleArrayTrieSegment();
        String example = "该工厂储存有大量的1,2-苯二胺,1,2-苯二酚,1,4-苯二酚";
        String example1 = "合闸按钮1SB2卡涩、粘连,未完全复位,处于导通状态,操作人员合上主空气开关QA后,合闸回路接通,接触器动作合闸,导致电机误启动";
        String example11 = "合闸按钮1SB2卡涩、粘连,未完全复位,处于导通状态,操作人员合上主空气开关后,合闸回路接通,接触器动作合闸,导致电机误启动";    // 删除, QA

        System.out.println(segment.seg(example1));

        // 也支持加载自己的词典
        String dict1 = "data/dictionary/CoreNatureDictionary.mini.txt";
        String dict2 = "H:/NLP/dataset/sogou_dictionary/txt/ChemSubstanceName1.txt nchem";
        segment = new DoubleArrayTrieSegment(dict1, dict2);
        System.out.println(segment.seg(example));    // 正常输出
        System.out.println(segment.seg(example11));    // 正常输出
        // System.out.println(segment.seg(example1));    // Java heap space

        segment.enablePartOfSpeechTagging(true);    // 激活数词和英文识别
        HanLP.Config.ShowTermNature = true;         // 顺便观察一下词性
        System.out.println(segment.seg(example));
        System.out.println(segment.seg(example11));

        for (Term term : segment.seg(example11))
        {
            System.out.printf("单词:%s 词性:%s\n", term.word, term.nature);
        }
   }
}

···

你上传的片段能够复现该问题吗?

可以,至少我运行的时候出现了相同的问题。

完整字典上传到网盘,供大家使用。
链接: https://pan.baidu.com/s/1WlNnNL2oI7gAgciXuoprtg 提取码: de3a

化学名称词典收了,感谢老铁分享 :grinning:

你的词典中多处包含空白行,导致DAT无法转移状态。当然,词典加载机制也应当做相应的防御性编程:

补充一句,感谢提bug,但论坛上的消息我经常看漏,回复也仅限周末一次。bug提到GitHub上去的话处理的优先级最高,也不存在漏掉的情况。