Heim  >  Artikel  >  Java  >  Detaillierte Erläuterung der Verwendung von Java Open Source 11 chinesischen Wortsegmentierern und Vergleich der Wortsegmentierungseffekte

Detaillierte Erläuterung der Verwendung von Java Open Source 11 chinesischen Wortsegmentierern und Vergleich der Wortsegmentierungseffekte

黄舟
黄舟Original
2017-03-22 11:00:472122Durchsuche

Die Ziele dieses Artikels sind zwei:

1. Lernen Sie, die 11 wichtigsten Java-Open-Source-Wortsegmentierer zu verwenden

2. Analysieren Sie vergleichend die Wortsegmentierungseffekte der 11 wichtigsten Java Open-Source-Wortsegmentierer für Chinesisch

Dieser Artikel beschreibt die Verwendungsmethoden der 11 wichtigsten Java-Open-Source-Wortsegmentierungen für Chinesisch und den Vergleichscode der Wortsegmentierungsergebnisse. Welcher Effekt besser ist, sollte der Benutzer selbst beurteilen an seinen eigenen Anwendungsszenarien.

11 wichtige Java-Open-Source-Wortsegmentierer haben unterschiedliche Verwendungen und unterschiedliche definierte Schnittstellen:

/**
 * 获取文本的所有分词结果, 对比不同分词器结果
 * @author 杨尚川
 */
public interface WordSegmenter {
    /**
     * 获取文本的所有分词结果
     * @param text 文本
     * @return 所有的分词结果,去除重复
     */
    default public Set<String> seg(String text) {
        return segMore(text).values().stream().collect(Collectors.toSet());
    }
    /**
     * 获取文本的所有分词结果
     * @param text 文本
     * @return 所有的分词结果,KEY 为分词器模式,VALUE 为分词器结果
     */
    public Map<String, String> segMore(String text);
}

Aus der obigen Definition wissen wir das Java, der gleiche Methodenname und die gleichen Parameter, aber unterschiedliche Rückgabewerte, Überladung kann in diesem Fall nicht verwendet werden.

Der Unterschied zwischen diesen beiden Methoden besteht im Rückgabewert. Jeder Wortsegmentierer kann über mehrere Wortsegmentierungsmodi verfügen, und die Wortsegmentierungsergebnisse jedes Modus können unterschiedlich sein. Die erste Methode ignoriert den Wortsegmentierungsmodus und gibt alle zurück Alle eindeutigen Wortsegmentierungsergebnisse des Musters. Die zweite Methode gibt jeden Wortsegmentierungsmodus und die entsprechenden Wortsegmentierungsergebnisse zurück.

Hier ist zu beachten, dass wir die neue Feature-Standardmethode in Java8 verwenden und Stream verwenden, um den Wert einer Karte in eine eindeutige Sammlung umzuwandeln.

Nachfolgend verwenden wir diese 11 wichtigsten Wortsegmentierer, um diese Schnittstelle zu implementieren:

1. Ansj-Wortsegmentierer

@Override
public Map<String, String> segMore(String text) {
    Map<String, String> map = new HashMap<>();
    for(SegmentationAlgorithm segmentationAlgorithm : SegmentationAlgorithm.values()){
        map.put(segmentationAlgorithm.getDes(), seg(text, segmentationAlgorithm));
    }
    return map;
}
private static String seg(String text, SegmentationAlgorithm segmentationAlgorithm) {
    StringBuilder result = new StringBuilder();
    for(Word word : WordSegmenter.segWithStopWords(text, segmentationAlgorithm)){
        result.append(word.getText()).append(" ");
    }
    return result.toString();
}

3. Stanford-Wortsegmentierer

@Override
public Map<String, String> segMore(String text) {
    Map<String, String> map = new HashMap<>();

    StringBuilder result = new StringBuilder();
    for(Term term : BaseAnalysis.parse(text)){
        result.append(term.getName()).append(" ");
    }
    map.put("BaseAnalysis", result.toString());

    result.setLength(0);
    for(Term term : ToAnalysis.parse(text)){
        result.append(term.getName()).append(" ");
    }
    map.put("ToAnalysis", result.toString());

    result.setLength(0);
    for(Term term : NlpAnalysis.parse(text)){
        result.append(term.getName()).append(" ");
    }
    map.put("NlpAnalysis", result.toString());

    result.setLength(0);
    for(Term term : IndexAnalysis.parse(text)){
        result.append(term.getName()).append(" ");
    }
    map.put("IndexAnalysis", result.toString());

    return map;
}

5. Jieba-Wortsegmentierer

private static final StanfordCoreNLP CTB = new StanfordCoreNLP("StanfordCoreNLP-chinese-ctb");
private static final StanfordCoreNLP PKU = new StanfordCoreNLP("StanfordCoreNLP-chinese-pku");
private static final PrintStream NULL_PRINT_STREAM = new PrintStream(new NullOutputStream(), false);
public Map<String, String> segMore(String text) {
    Map<String, String> map = new HashMap<>();
    map.put("Stanford Beijing University segmentation", seg(PKU, text));
    map.put("Stanford Chinese Treebank segmentation", seg(CTB, text));
    return map;
}
private static String seg(StanfordCoreNLP stanfordCoreNLP, String text){
    PrintStream err = System.err;
    System.setErr(NULL_PRINT_STREAM);
    Annotation document = new Annotation(text);
    stanfordCoreNLP.annotate(document);
    List<CoreMap> sentences = document.get(CoreAnnotations.SentencesAnnotation.class);
    StringBuilder result = new StringBuilder();
    for(CoreMap sentence: sentences) {
        for (CoreLabel token: sentence.get(CoreAnnotations.TokensAnnotation.class)) {
            String word = token.get(CoreAnnotations.TextAnnotation.class);;
            result.append(word).append(" ");
        }
    }
    System.setErr(err);
    return result.toString();
}

6 🎜>

private static CWSTagger tagger = null;
static{
    try{
        tagger = new CWSTagger("lib/fudannlp_seg.m");
        tagger.setEnFilter(true);
    }catch(Exception e){
        e.printStackTrace();
    }
}
@Override
public Map<String, String> segMore(String text) {
    Map<String, String> map = new HashMap<>();
    map.put("FudanNLP", tagger.tag(text));
    return map;
}
7. MMSeg4j-Tokenizer

private static final JiebaSegmenter JIEBA_SEGMENTER = new JiebaSegmenter();
@Override
public Map<String, String> segMore(String text) {
    Map<String, String> map = new HashMap<>();
    map.put("INDEX", seg(text, SegMode.INDEX));
    map.put("SEARCH", seg(text, SegMode.SEARCH));
    return map;
}
private static String seg(String text, SegMode segMode) {
    StringBuilder result = new StringBuilder();                
    for(SegToken token : JIEBA_SEGMENTER.process(text, segMode)){
        result.append(token.word.getToken()).append(" ");
    }
    return result.toString(); 
}
8. IKAnalyzer-Tokenizer

private static final JcsegTaskConfig CONFIG = new JcsegTaskConfig();
private static final ADictionary DIC = DictionaryFactory.createDefaultDictionary(CONFIG);
static {
    CONFIG.setLoadCJKSyn(false);
    CONFIG.setLoadCJKPinyin(false);
}
@Override
public Map<String, String> segMore(String text) {
    Map<String, String> map = new HashMap<>();

    map.put("复杂模式", segText(text, JcsegTaskConfig.COMPLEX_MODE));
    map.put("简易模式", segText(text, JcsegTaskConfig.SIMPLE_MODE));

    return map;
}
private String segText(String text, int segMode) {
    StringBuilder result = new StringBuilder();        
    try {
        ISegment seg = SegmentFactory.createJcseg(segMode, new Object[]{new StringReader(text), CONFIG, DIC});
        IWord word = null;
        while((word=seg.next())!=null) {         
            result.append(word.getValue()).append(" ");
        }
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
    return result.toString();
}
10 Wortsegmentierer

private static final Dictionary DIC = Dictionary.getInstance();
private static final SimpleSeg SIMPLE_SEG = new SimpleSeg(DIC);
private static final ComplexSeg COMPLEX_SEG = new ComplexSeg(DIC);
private static final MaxWordSeg MAX_WORD_SEG = new MaxWordSeg(DIC);
@Override
public Map<String, String> segMore(String text) {
    Map<String, String> map = new HashMap<>();
    map.put(SIMPLE_SEG.getClass().getSimpleName(), segText(text, SIMPLE_SEG));
    map.put(COMPLEX_SEG.getClass().getSimpleName(), segText(text, COMPLEX_SEG));
    map.put(MAX_WORD_SEG.getClass().getSimpleName(), segText(text, MAX_WORD_SEG));
    return map;
}
private String segText(String text, Seg seg) {
    StringBuilder result = new StringBuilder();
    MMSeg mmSeg = new MMSeg(new StringReader(text), seg);        
    try {
        Word word = null;
        while((word=mmSeg.next())!=null) {       
            result.append(word.getString()).append(" ");
        }
    } catch (IOException ex) {
        throw new RuntimeException(ex);
    }
    return result.toString();
}
11. HanLP-Wortsegmentierer

@Override
public Map<String, String> segMore(String text) {
    Map<String, String> map = new HashMap<>();

    map.put("智能切分", segText(text, true));
    map.put("细粒度切分", segText(text, false));

    return map;
}
private String segText(String text, boolean useSmart) {
    StringBuilder result = new StringBuilder();
    IKSegmenter ik = new IKSegmenter(new StringReader(text), useSmart);        
    try {
        Lexeme word = null;
        while((word=ik.next())!=null) {          
            result.append(word.getLexemeText()).append(" ");
        }
    } catch (IOException ex) {
        throw new RuntimeException(ex);
    }
    return result.toString();
}
Jetzt haben wir das erste Ziel dieses Artikels erreicht: Lernen Sie, die 11 Java-Open-Source-Chinesisch-Wortsegmentierer zu verwenden.

Lassen Sie uns abschließend den zweiten Zweck dieses Artikels erkennen: die vergleichende Analyse der Wortsegmentierungseffekte von 11 großen Java-Open-Source-Wortsegmentierern für Chinesisch:
private static final PaodingAnalyzer ANALYZER = new PaodingAnalyzer();
@Override
public Map<String, String> segMore(String text) {
    Map<String, String> map = new HashMap<>();

    map.put("MOST_WORDS_MODE", seg(text, PaodingAnalyzer.MOST_WORDS_MODE));
    map.put("MAX_WORD_LENGTH_MODE", seg(text, PaodingAnalyzer.MAX_WORD_LENGTH_MODE));

    return map;
}
private static String seg(String text, int mode){
    ANALYZER.setMode(mode);
    StringBuilder result = new StringBuilder();
    try {
        Token reusableToken = new Token();
        TokenStream stream = ANALYZER.tokenStream("", new StringReader(text));
        Token token = null;
        while((token = stream.next(reusableToken)) != null){
            result.append(token.term()).append(" ");
        }
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
    return result.toString();          
}

Das Die Laufergebnisse lauten wie folgt:
private static final SmartChineseAnalyzer SMART_CHINESE_ANALYZER = new SmartChineseAnalyzer();
@Override
public Map<String, String> segMore(String text) {
    Map<String, String> map = new HashMap<>();
    map.put("smartcn", segText(text));
    return map;
}
private static String segText(String text) {
    StringBuilder result = new StringBuilder();
    try {
        TokenStream tokenStream = SMART_CHINESE_ANALYZER.tokenStream("text", new StringReader(text));
        tokenStream.reset();
        while (tokenStream.incrementToken()){
            CharTermAttribute charTermAttribute = tokenStream.getAttribute(CharTermAttribute.class);
            result.append(charTermAttribute.toString()).append(" ");
        }
        tokenStream.close();
    }catch (Exception e){
        e.printStackTrace();
    }
    return result.toString();
}

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Verwendung von Java Open Source 11 chinesischen Wortsegmentierern und Vergleich der Wortsegmentierungseffekte. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn