'TokenStream'에 해당되는 글 2건

  1. 2010.01.08 Lucene 3.0 TokenStream과 AttributeSource. - 1 - (2)
  2. 2010.01.07 Lucene 3.0 TokenStream. 그리고 Attribute. (2)
루씬이 버전업 되면서 바뀐 부분 중 하나가 이 부분인 것 같습니다.
이전에는 Tokenizer나 TokenFilter 클래스를 만들 때 TokenStream 클래스를 상속받아 만들고
이 TokenStream의 next 메서드를 사용해서 얻어지는 Token을 가지고
데코레이터 패턴으로 적용 된 Filter들이 Token을 처리하는 방식이었습니다.

예를 들어서,

Analyzer의 tokenStream 메서드가 위와 같이 정의되어 있다고 하고
분석해야 할 문장이 "검색엔진 개발자" 라고 했을 때
추출 되는 Token을 얻어내기 위해서 next 메서드를 실행했었습니다. 즉,


대략 위와 같은 방식이었죠.
next 메서드가 실행 되면 제일 상위의 Tokenizer에서 "검색엔진,(0,4)" 라는 Token을 만들어서 리턴하고
그것을 받아서 다음 Filter의 next 메서드에서 Token에서 원하는 작업을 하고
(뭐 검색엔진을 검색+엔진으로 분리하여 리턴한다던가..)
그 Token을 또 다음 Filter가 받아서 작업하는 방식이었습니다.

그런데 이번에 Analyzer를 lucene 3.0 버전으로 바꾸다보니
앞선 포스트에 잠깐 언급했던 것 처럼 이 가장 핵심이라고 할 수 있는
Token next() 메서드가 없어졌습니다. 그리고, boolean incrementToken() 이라는 메서드가 생겼습니다.
게다가 리턴타입이 boolean 입니다.

필터가 앞선 필터(즉, TokenStream)으로 부터 추출되는 Token을 받아야 자기 작업을 할텐데
리턴 타입이 boolean이니 이걸 어떻게 하라는건가 싶었습니다.

3.0 버전에서는 예전의 next() 메서드를 대신 전부 incrementToken() 메서드로 대체가 되었습니다.

그럼 3.0 버전에서는 어떻게 필터와 Tokenizer가 동작할까요..

이전버전에 있던 (3.0에도 있지만) Token 클래스는 문장을 나타내는 term과 위치정보를 나타내는 start/end offset
그리고 위치 이동에 대한 정보인 positionIncremental 또 Term의 타입을 지정 할 수 있는 Type을 그 속성으로 가지고 있었습니다.

이 속성들이 Attribute라는 클래스를 상속한 속성 클래스들로 전부 빠져나왔습니다.
즉,

이런식으로 ...
그래서, 이전에 Token에 넣어주던 정보들을 저 속성들에 넣어주게 됩니다.
그러면, 어떻게 각 필터와 Tokenizer가 저 값들을 공유하여 자신들의 작업 (동의어추출,stemming,복합명사 추출등)을
할 수 있는 것일까요..?

Lucene 3.0 (혹은 그 이전버전 부터인지..)에서는 TokenStream 클래스가 AttributeSource라는 클래스를 상속받고 있습니다.
AttributeSource는 내부적으로 Attribute들을 가지고 있고요.. 즉, 위에 나열된 저런 속성들을 가지고 있습니다.
결국 모든 필터들이 TokenStream을 상속받고 있기 때문에
저 AttributeSource를 사용해서 원하는 값들을 공유 할 수 있게 됩니다.

조금 자세하게 살펴보면
일반적으로 가장 앞단에서 Term을 잘라내는 Tokenizer를 살펴보면
생성자에서 아래와 같은 일을 하도록 정의 되어 있습니다.


addAttribute 메서드는 AttributeSource 클래스에 정의되어있는 메서드로
Attribute Class를 자기 속성에 add하고, 만약에 이미 있는 Attribute라면 그 Attribute를 return 하는 메서드입니다.
Tokenizer가 가장 앞단에서 실행 되므르 위 문장에 의해서 TermAttribute와 OffsetAttribute, TypeAttribute가 AttributeSource에
추가 될 것입니다.

그리고, 해당 Tokenizer가 incrementToken()메서드에서
읽어들인 문장에서 Term을 잘라내고나서는

해당 속성값을 Attribute에 넣어주고 true를 리턴하게 됩니다.

그렇게 되면 다음 필터에서는 저 AttributeSource의 Attribute들을 얻어 낼 수 있다면
앞에서 동작하는 Filter나 Tokenizer의 결과 값을 사용 할 수 있게 되는 것 입니다.

그럼 어떻게 얻어낼까요?

바로 addAttribute 혹은 getAttribute 메서드를 통해 얻어낼 수 있습니다.

 - 계속 -
Posted by 용식
예전에 만들었던 한글 명사 추출 Analyzer를 공개하려고 하다가
그 Analyzer의 core 버전이 2.4.0 base여서 이것을 최신 루씬 버전인
3.0으로 컨버팅 하려고 했는데... 바뀐게 한두가지가 아니라서.. 일단 바뀐 부분부터 공부를
해야겠다 싶었다. -_-;

제일 당황스러운 부분이...
TokenStream.next(Token token) 메서드가 사라진 것이었다. -_-;

이 부분이 TokenStream.incrementToken() 메서드를 대체가 되었는데 이건 조만간 다시 포스팅 하기로 하고..
일단, 기존에 사용되던 Token이란 클래스가 남아있기는 한데..
대부분 Attribute 클래스에 기초한 놈들로 변경이 된 것 같다.

예전에 하나의 String에서 Analyzer로 분석 된 Term 리스트를 얻으려는 소스는
아래와 같았다.


TokenStream의 next 메서드로 다음 Analyzer로 분석 된 Token들을 하나씩 얻어내고
거기서 Token의 term을 사용해서 단어를 얻거나 offset등의 데이터들을 모두 얻어낼 수 있었는데
이 next() 메서드가 사라진 것이다. -_-;

그 대신 Attribute 클래스를 상속한 TermAttribute 혹은 OffsetAttribute등의 클래스를 이용해서 위의 작업을 대신 할 수 있다.
다른 Attribute도 많이 존재한다.
결국, 예전에 Token 클래스가 가지고 있던 속성들이 각각의 클래스로 분리 되서 나온 것이라고 보면 정확 할 것 같다.


TokenStream으로부터 Attribute인 TermAttribute와 OffsetAttribute를 얻어내고 이것을 통해서 단어와 위치 정보를
보여주고 있다.
그리고, incrementToken 메서드를 사용해서 다음 Term으로의 접근을 하고 있다.

결국, 이전 버전의 Tokenizer나 TokenFilter에서 next메서드가 하는 일을
incrementToken 메서드가 대신 하고 있는 것이다. 다만, 리턴을 해주는 것이 아니라
내부적으로 Attribute에 set을 하고 있는 것.. 그리고 이것을 그냥 가져다 쓰는 방식.

이게 왜 이렇게 바뀌었나 살펴보면.. TokenStream 메서드 중에
현재 상태를 capture하는 등의 메서드가 추가 된 것이 보이는데 이것을 위해서
Attribute들이 전부 멤버로 들어갔나 싶다.. 아직 자세히 못 들여다봐서..

결국, 내가 만들었던 Analyzer의 Filter들과 모듈을 거의 전부
뜯어 고쳐야 한다는 얘기가 나온다.. 어휴.... -.-

그외 다른 것도 모르는 것 천지.. 하나하나 이것저것 해보는 수 밖에.. ㄷㄷ;;

이전에 사용되던 Token 클래스도
TokenStream.addAttributeImpl 메서드를 통해서 사용 할 수 있는 것 같기는 한데
이건 구현되어있는 Tokenizer에 따라서 다른 것 같다.

그 Tokenizer가ㅏ AttributeImpl에도 값을 set 해주면 값이 들어갈 것이고..
아니면 안 들어갈 것이고..

참고로 가장 많이 사용되는 (루씬 analyzer에서.)
charTokenizer는
incrementToken메서드가 아래와 같이 구현 되어 있다.


이전 버전과 비교해보면 하는 일은 거의 같다.
다만 메서드 이름이 바뀌고 Token에 추출 된 결과를 넣어 주는 것이 아니라
TermAttribute와 OffsetAttribute에 넣어주는 것...

그러면, 이 Tokenizer가 도대체 어떤 Attribute와 AttributeImpl을 가지고 있는지 알아야 할 텐데..
보니까 TokenStream에 두 클래스에 대한 Iterator를 얻을 수 있는 메서드가 있다.
그걸 사용하면 될 듯..
Posted by 용식