放牧代码和思想
专注自然语言处理、机器学习算法
    This thing called love. Know I would've. Thrown it all away. Wouldn't hesitate.

Lucene 同义词

目录

在Lucene4.6中通过SynonymFilterFactory实现中文同义词非常方便,只需几行代码和一个同义词词典。这个词典还能在Lucene中实现一定程度的拼写纠错,提升搜索体验。在下面这个例子中我们从磁盘载入一个同义词词典,并且对“其实hankcs似好人”这句话进行stream化以供索引,同时还对其中的拼写错误“似->是”做出纠正。

首先是位于./data/synonyms.txt路径下的同义词词典:

我,俺,hankcs
似,is,are => 是
好人,好心人,热心人

可以看出上面有两种词典格式:

通过,分割的可拓展同义词

比如“我,俺,hankcs”代表着这三个词是同义词,并且任何一个词可以被expand(拓展)为其他三个。如果expand设为false的话,则这三个词都会被统一替换为第一个词,也就是“我”。

通过=>收缩的不可拓展同义词

比如“似,is,are => 是”代表这三个词同义,并且无视expand参数,统一会被替换为“是”

然后是加载代码

package com.hankcs.test;

import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
import org.apache.lucene.analysis.synonym.SynonymFilterFactory;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
import org.apache.lucene.analysis.util.FilesystemResourceLoader;
import org.apache.lucene.util.Version;
import org.apache.uima.annotator.WhitespaceTokenizer;

import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;

/**
 * @author hankcs
 */
public class TestSynonyms
{
    private static void displayTokens(TokenStream ts) throws IOException
    {
        CharTermAttribute termAttr = ts.addAttribute(CharTermAttribute.class);
        OffsetAttribute offsetAttribute = ts.addAttribute(OffsetAttribute.class);
        ts.reset();
        while (ts.incrementToken())
        {
            String token = termAttr.toString();
            System.out.print(offsetAttribute.startOffset() + "-" + offsetAttribute.endOffset() + "[" + token + "] ");
        }
        System.out.println();
        ts.end();
        ts.close();
    }

    public static void main(String[] args) throws Exception
    {
        String testInput = "其实 hankcs 似 好人";
        Version ver = Version.LUCENE_46;
        Map<String, String> filterArgs = new HashMap<String, String>();
        filterArgs.put("luceneMatchVersion", ver.toString());
        filterArgs.put("synonyms", "./data/synonyms.txt");
        filterArgs.put("expand", "true");
        SynonymFilterFactory factory = new SynonymFilterFactory(filterArgs);
        factory.inform(new FilesystemResourceLoader());
        WhitespaceAnalyzer whitespaceAnalyzer = new WhitespaceAnalyzer(ver);
        TokenStream ts = factory.create(whitespaceAnalyzer.tokenStream("someField", testInput));
        displayTokens(ts);
    }
}

输出:

0-2[其实] 3-9[我] 3-9[俺] 3-9[hankcs] 10-11[是] 12-14[好人] 12-14[好心人] 12-14[热心人]

由于 我 俺 hankcs 三个词是同一个意思,所以它们被视为同一个term,并且它们的偏移相同,都是3->9,这个长度取决于原来的词 hankcs 的长度。

知识共享许可协议 知识共享署名-非商业性使用-相同方式共享码农场 » Lucene 同义词

评论 4

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #4

    FilesystemResourceLoader在lucene5.5上报错

    new nlp8年前 (2016-05-22)回复
  2. #3

    请问最后得到的TokenStream ts,这个怎么添加到索引当中呢?

    newbie8年前 (2016-04-17)回复
  3. #2

    请问最后得到的TokenStream ts,这个怎么加入到索引当中呢?

    newbie8年前 (2016-04-17)回复
  4. #1

    请问 import org.apache.uima.annotator.WhitespaceTokenizer; 需要导入的是什么jar包呢?

    思密达8年前 (2016-04-11)回复

我的作品

HanLP自然语言处理包《自然语言处理入门》