详解mmseg

时间:2024-04-15 20:36:58

本文先介绍下mmseg的概念和算法,再说下mmseg4j-solor的3个分词器用法

1.mmseg概念

mmseg是用于中文切词的算法,即Maximum Matching Segment,最大匹配分词。根据在词典(语料库)中的匹配情况把原文切分成一个个词语

2.两种方法

为了便于后续介绍,假设要切分的原文是C1 C2 C3 C4 C5 C6, C表示一个汉字。

简单最大匹配:从头依次查找最长的词语,以此切割。如 [研究生], [研究, 生]

复杂最大匹配:是简单最大匹配的变体,引入三词块的概念,先找到所有可能的连续的三个词语组成的块,以块为单位运用如下规则来确定切割方式。

  • 规则1:块长度最长(包含字符个数最多)Maximum matching
  • 规则2:块中三个词的平均长度最长, Largest average word length
  • 规则3:三词长度的方差最小, Smallest variance of word lengths
  • 规则4:单字频率对数和最大,Largest sum of degree of morphemic freedom of one-character words

复杂最大匹配算法依次运用上面规则来消除歧义,选择符合规则的切词方案

3.mmseg4j-solor提供的3个analyzer

打印切词结果code如下。

    private void print(Analyzer analyzer, String str) throws IOException {
TokenStream stream = analyzer.tokenStream("", new StringReader(str));
StringBuilder sb = new StringBuilder();
stream.reset();
while (stream.incrementToken()) {
sb.append("[").append(stream.getAttribute(CharTermAttribute.class).toString() + "]");
}
stream.end();
stream.close();
System.out.println(sb.toString());
}

SimpleAnalyzer:简单最大匹配

SimpleAnalyzer analyzer = new SimpleAnalyzer("D:\\workspace\\TestLucene\\src\\main\\resources");
print(analyzer, "研究生命起源");

输出-[研究生][命][起源]

ComplexAnalyzer:复杂最大匹配

System.setProperty("mmseg.dic.path", "D:\\workspace\\TestLucene\\src\\main\\resources");
ComplexSeg.setShowChunk(true);
ComplexAnalyzer analyzer = new ComplexAnalyzer();
print(analyzer, "研究生命起源");
print(analyzer, "输入法");

输出:

[研究][生命][起源]

[输入法]

MaxWordAnalyzer: 最多分词切割,是ComplexAnalyzer的子类,在其基础上对词长度做了控制,不允许词长度超过2

MaxWordAnalyzer analyzer = new MaxWordAnalyzer("D:\\workspace\\TestLucene\\src\\main\\resources");
print(analyzer, "研究生命起源");
print(analyzer, "输入法");

输出:

[研究][生命][起源]

[输入][法]

细心的读者会发现上面的代码使用了两种设置词典路径的方法:设置mmseg.dic.path和构造函数传参。注意的是即使设置了新词典路径,mmseg4j-core中的data/words.dic也会被加载。

参考

http://technology.chtsai.org/mmseg/

https://code.google.com/archive/p/mmseg4j/