요즘 루씬 코드 리딩을 하고 있다. 루씬 core 패키지는 예전에 한번 분석 해본 경험이 있어서 이번엔 contrib 패키지를 중점적으로 살펴보고 있다. 그중에서도 spellcheck 모듈은 가장 최근에 성능좋은 라이브러리로 구현한 경험이 있어서 관심이 갔다. 이 패키지 내에서는 Jaro Winkler Distance 라는 짧은 이름에서 사용 가능한 string 비교 클래스가 구현이 되어 있었으며 n-gram 기반의 string 비교 클래스도 있었다. 그러나 메인으로는 예상대로 edit distance가 사용되고 있었다.
무엇보다 이 패키지의 특이점은 루씬이 색인한 색인 term들을 기반으로 별도의 spellcheck용 색인을 구성한다는 것이다. 그리고 한 단어의 필요한 모든 n-gram 단어 시퀀스를 추출해 단어문서의 필드 데이터로 추가 한다는 것이다. 이렇게 색인을 구성하고 입력된 쿼리를 n-gram 분리한 다음 불린 쿼리를 구성해 색인에 검색 결과를 요청하면 요청한 수 만큼의 정타 후보를 구할 수 있다. 이 방법은 예전에 논문을 통해 살펴본 경험이 있었는데, 루씬에서 이런 방식으로 구성을 하고 있다는 사실이 참 흥미로웠다. 이렇게 구현하는 이유는 간단하다. 색인을 조회하는 복잡도가 edit distance의 복잡도보다 낮기 때문이다. 이렇게 구한 후보들을 대상으로 좀더 비싼 연산인 edit distance로 정확하게 정타를 추천해 내는 것이다.
게다가 이렇게 구현하면 루씬 색인에서 지원하는 많은 기능을 쓸 수 있는데, 예를 들어 메모리에 색인을 다 올려서 스펠러 퍼포먼스를 올리는 기능이 바로 구현가능하다. 물론 확률 기반으로 하기 위한 frequence정보도 루씬 색인에서 기본적으로 제공하는 정보니 이를 활용해서 error model을 구현하는 방법도 사용해 볼 만한 방법이다.
한글에 대한 단어 추천을 하기 위해서는 역시 이 패키지 만으로 부족하다. 내 논문에서 언급 했지만 한글 음절단위로 동작하기 위해서는 엄청난 수의 가능 자소조합에 대한 단어 정보들이 있어야 하는데 이는 상당히 어려운 작업이고 따라서 자소단위로 연산을 해서 추천모듈을 구성하는게 훨씬 간단하고 성능도 좋다. 따라서 몇몇 한글처리 모듈이 추가가 되어야 한글 추천이 원활하게 가능할 것이다.
여튼 이 추가 부분에 대한 contribution을 할 수 있을지 모르겠지만 오랜만에 자바 코드 공부하는 셈 치고 해볼 생각이기도 하다.
Lucene spellcheck package by from __future__ import dream is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.