chenlb / mmseg4j-core

mmseg4j core MMSEG for java chinese analyzer
Apache License 2.0
157 stars 89 forks source link

max-word为什么要采用两个字一组,不采用在词库中存在的词就分出来呢? #1

Open haochun opened 10 years ago

haochun commented 10 years ago

如题,在实际应用中可能会出现分词的时候使用max-word,而检索采用complex,但您的max-word测试后发现是最多两个字一组,这样的话是否有问题?我在使用的过程中是将其能分成更多的词,比如 计算机学院 我会分成 计算机、学院、计算 这样的,我对代码修改了一点,其中主要对MaxWordSeg.java进行了修改,如下:

public Chunk seg(Sentence sen) {
        Chunk chunk = new Chunk();
        char[] chs = sen.getText();
        List<Word> cks = new ArrayList<Word>();
        for(int k=0; k<3&&!sen.isFinish(); k++) {
            int offset = sen.getOffset();
            int maxLen = 0;
            //有了 key tree 的支持可以从头开始 max match
            ArrayList<Integer> lens = dic.maxMatchs(chs, offset);
            maxLen = lens.get(0);
            for(int len:lens){
                if(len>maxLen){
                    maxLen = len;
                }
                cks.add(new Word(chs, sen.getStartOffset(), offset, len+1));
            }
            chunk.words[k] = new Word(chs, sen.getStartOffset(), offset, maxLen+1);
            offset += maxLen + 1;
            sen.setOffset(offset);
        }
        chunk.words = cks.toArray(new Word[cks.size()]);
        chunk.count = cks.size();
        return chunk;
    }

如有不当之处,请见谅

chenlb commented 9 years ago

关于这个问题,我最初的回复:http://blog.chenlb.com/2009/04/chinese-segment-mmseg4j-dictionary-format.html


关于最多分词还没有什么好的想法。考虑到很多长词基本都是由 2-3 个字的词组成的。又考虑到类似"咖啡" 能找到 “咖啡厅”,所以草率地决定词长最长为2。

假设:"咖啡" 和 “咖啡厅” 在词库中,max-word 方式分为 "咖啡 | 厅","咖啡" 和 “咖啡厅” 搜索时(默认Lucene 的 QueryParser 解析出来的 “短语查询”)都可以找到 “咖啡厅”。

目前没有 api 或配置可设置 max-word 方式分出的词长超过2,这个效果是否可行,还要多讨论(找个话题在 javaeye 讨论征集建议)。目前这方式,有一些情况不顺眼的:“为什么” 分成 "为 | 什么"。


haochun commented 9 years ago

@chenlb 那我上面提的方法不可行吗?我目前这样改,做到项目里面了,感觉还可以。我只是拿您的代码做了修改,尽量找到词库中都存在的词,而不限定长度,这样,在索引的时候使用max-word,检索使用complex,效果还可以。

chenlb commented 9 years ago

可行,我考虑把这种模式加进来。这种模式可以解决多分词准确性提高的场景。

haochun commented 9 years ago

好,那您有时间给加吧,我只是拿您的代码修改了,没有完整阅读您的代码,因此,不敢保证完全正确。