2011년 7월 30일 토요일

Lucene에서 KStemmer 사용하기

정확한 명칭은 Krovertz Stemmer라고 부른다. Lucene등의 툴킷에서는 

KStemmer라는 이름의 약자로 되어 있다. 1993년 꽤 오래전에 논문이 나오고 

lucene, lemur, indri 등 대부분에 포함되어 있지만 생각보다는 많이 쓰이지는 

않는듯하다.

아무래도 사전기반의 알고리즘이다 보니 리소스가 꽤 많이 소비된다는 측면이 

클듯하다. 

가장 최신 버젼인 lucene-3.3.0 버젼에서는 추가된듯하다. 

( 이전 버젼부터 존재했었는지는 확실치 않다. )

자세한 사항이 궁금한 사람은 다음의 논문을 읽어 보도록 하자. 



다음의 표는 Porter Stemmer가 에러를 일으키는 경우를 나타낸다.



Krovetz Stemmer는 Porter Stemmer만큼은 공격적으로 stemming을 하지는 않기때문에 

에러가 적다. 

KStemmer의 알고리즘은 기존의 Porter Stemmer의 알고리즘과 사전기반의 알고리즘이 

결합된 형태이다. 

KStemmer는 Inflectional, Derivational 두가지 방법의 알고리즘을 적용한다.

전자는 suffix를 제거하는 쪽 후자는 추가해서 명사를 만드는 쪽이다.


Inflectional에서 단어가 사전에 있는지를 찾아본후 사전에서 단어를 발견하면

스템처리를 하지 않는다. 


Derivational 방법에서는 -er, -or, -ion, -ly, -ity, -al, ive, -ze, -ment, -able 등을 추가하는데 

논문에 따르면 longman 사전의 빈도수를 기반으로 이를 패턴화 시켜놓았다.

더 자세한 사항은 논문을 참조하도록 하자. 


lucene에는 KStemFilter는 포함되어 있으나 Analyzer는 없기때문에 클래스를 추가해주어야 한다.

간단히 다음과 같이 클래스를 만들어 사용해 보자. 

package org.apache.lucene.demo;

import org.apache.lucene.analysis.en.*;
import org.apache.lucene.analysis.*;
import org.apache.lucene.analysis.standard.*;
import org.apache.lucene.util.Version;

import java.io.Reader;

public class KStemAnalyzer extends Analyzer {
Version MatchVersion;
public KStemAnalyzer(Version matchVersion){
this.MatchVersion = matchVersion;
}
public TokenStream tokenStream(String fieldName, Reader reader){
return new KStemFilter(new StandardTokenizer(MatchVersion,reader));
}
}

코드는 lucene-3.3.0을 기준으로 작성하였다. 

Analyzer는 Filter와 Tokenizer를 모두 필요로 한다. 

위에서는 간단하게 StandardTokenizer를 사용하였지만 lucene에는 

ClassicTokenizer, WhitespaceTokenizer, LowerCaseTokenizer, 

KeywordTokenizer등 여러가지가 있으니 입맛에 맞게 사용하면 된다.

Tokenizer가 있으니 입맛에 따라 골라 사용하자. 

댓글 없음:

댓글 쓰기