검색과 클러스터링

클러스터링에 대한 공부는 예전에 k-means 알고리즘을 이용한 음성데이터 클러스터링을 마지막으로 손을 가져가지 않았다가, 이번에 이런저런 책을 보면서 클러스터링에 대한 공부를 해봤다.

검색엔진이 왜 클러스터링과 관련이 있는지 알아보자!

컬렉션이 잘 클러스터링 되어 있다면, 그 해당 클러스터만을 검색해서 문서를 찾아내는것이 더 효과적이다.

이런 효과적인 성능에 비해 크러스터링은 일반적인 검색엔진에 쓰이기 힘든 factor가 있다.

1. 문서 집합에 대해서 클러스터링을 했을경우 그 클러스터가 어떤 쿼리에 관계가 있는지 모호하다.
2. 클러스터링 복잡도가 매우높다. (N * N의 유사도 매트릭스를 사용할 경우 매 클러스터링을 수행할 경우 O(n^2)). 요즘 문서셋이 굉장히 크다는걸 감안할때 상당할 것이다.

이런 한계 때문에 일반적으로 결과셋의 클러스터링에 클러스터링 알고리즘들이 사용된다.

그럼 이런 클러스터링은 어떤 방식으로 수행이 될까?

1. 결과셋의 문서들을 파싱해서 구(단어들의 집합)를 뽑아낸다.
2. 학습 알고리즘으로 학습된 모델에 이 문서 단위의 구를 입력해서 Key가 되는 구를 찾아낸다.(linear regression, logistic regression, support vector regression 등등)
3. 그 키를 이용해 포함된 문서를 초기 클러스터링 한다.
3.1 예를 들어 키 구로 “수도 서울”이 포함된 문서는 같은 클러스터로 분류되서 초기화 된다.
4. 초기 클러스터를 기반으로 문서 대 문서간의 유사도를 이용해 merge 작업을 한다.

그러니까 위의 merge작업을 클러스터 집합에 대한 트리로 만들어서 그 트리를 검색 결과에 보여주면 되는 것이다.

몇몇 클러스터링 알고리즘이 존재한다.

1. Hierarchical Agglomerative Clustring 알고리즘
2. Partitioning(Iterative) 기반의 알고리즘 (one-pass, BuckShot, K-means)

위의 두가지 알고리즘 셋의 차이점은 기 계산된 문서-문서 쌍의 유사도 matrix를 가지고 있느냐 아니느냐의 것이다.

Hierarchical Agglomerative Clustring 알고리즘

1. 유사도가 가장 높은 클러스터 2개를 선택한다.
2. 두 클러스터를 merge하고 유사도 matrix를 재계산 한다.(n번의 계산 필요)

위의 1,2번 과정을 오직 하나의 클러스터가 될때까지 계속 한다.
여기서 merge된 cluster의 유사도를 정하는것은 통상 3가지의 식이 사용된다.

1. Single Link
2. Complete Linkage
3. Group Average

Single Link : 두 클러스터 사이의 문서쌍중에 가장 큰 값을 취하는 방법
Complete Linkage : 두 클러스터 사이의 문서쌍중에 가장 작은 값을 취하는 방법
Group Average : 두 클러스터내의 문서쌍 유사도의 평균값

이런 방식으로 유사도 매트릭스를 업데이트 해가면서 클러스터링을 수행하고 그 클러스터링 결과를 트리 형식의 Bottum-Up 방식으로 구성해서 검색엔진 쿼리 프로세싱에 사용을 하게 된다.

그러나 이 방법은 검색 결과를 보기까지 너무 많은 복잡도를 요구한다.
이 알고리즘은 O(n^2)의 복잡도를 가지는 것으로 알려져 있다. (이것은 유사도 계산의 1회 계산에 포커싱이 맞춰진 복잡도 이다. 만일 유사도 계산의 세부 연산에 대한 복잡도를 계산하자면 이것은 정확한 것이 아닐 수 있다.)

그렇다고 매드릭스를 구성하지 않는 클러스터링 방법을 한다고 해서 복잡도 상으로 그렇게 효과적이지는 않다.

그래서 미리 클러스터링을 해놓은 문서집합을 사용해서 검색 결과를 보여주기도 한다.(몇몇의 국내 제품이 이런 방식을 사용하는것으로 알고 있다. 중요 키워드에 대해 말이다.)

검색결과 랭킹을 이런 방식으로 했었던 전의 첫눈이라는 검색엔진이 있었다. 상당히 유저에게 어필을 하는 구조였는데 지금은 그 모습을 보기 쉽지 않으니 좀 아쉽기도 하다.

실시간으로 검색 결과 클러스터링을 효율적으로 하는 구조는 있을까?  한번 찾아봄직 할거 같다.

0 0 votes
Article Rating
Subscribe
Notify of
guest

8 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
검색엔진

매번 볼 때 마다 드는 생각인데… 고감자님 멋져~~~

우리 언제 다시 흔드나요.. 유흥부장님도 보고잡고.. 시샵님들도 보고잡고.. 싸이오블레이드님도 보고잡고..

아.. 체력이여.. 아 옛날이여…^^

고감자

박형룡 소장님 같은신데요? ㅋㅋㅋㅋ

언제나 오세요. 문은 열려 있습니다.

최종욱

수직적 클러스터링 보면서 항상 드는 생각인데요, 사람들의 모임에는 그 모임을 대표할만한 사람이 있습니다. 그런 사람 몇 만 거치면 분류가 될 겁니다. 그런 알고리즘을 고안하면 n log(n)의 속도가 나지 않을까요? 뭐, 정확도야 많이 희생이 되겠지만 말이에요. 어느 범위 이상을 벗어나지 않는다는 증명을 하면 될 것도 같은데? ㅎㅎ

고감자

gnutella의 단점을 보완한 kazaa의 알고리즘이 생각나네요.
모든 클라이언트에 쿼리를 보내지 않고 클러스터 대표에게만 보내서 네트워크 부하를 줄인 알고리즘을 쓰더군요.
이것의 단점은 클러스터대표가 클러스터 속한 클라이언트의 정보를 다 알고 있어야 한다는 것이죠.
누가 클러스터를 대표하는것인지 아는것부터 해서 확인해야될 것들이 많아 보이네요.

최종욱

대충 훑어보니 Single pass method clustering 알고리즘이 나오네요. 그냥 처음에 들어온 것 몇개를 대표라 치고 더덕더덕 붙여나가는 겁니다. 참 무식한 방법이긴 하지만, 속도는 O(n log n)으로 가장 빠른 방법이라고 하는군요. 제가 보기에는 상수 시간 안에 좀 더 보완할 방법이 있을 것도 같은데 말이죠.

http://ei.cs.vt.edu/~cs5604/f95/cs5604cnCL/CL-alg-details.html

고감자

이 알고리즘… O(n^2) 아닌가 하는데요.

(n – 1) + (n – 3) + (n – 5) +…… + 1

까지 해서 대충 풀어보면

n(n-1)/2 – (n-2)(n-1)/2

이거 풀고 버릴거 버리면 O(n^2) 이 나오던데요…

평균적인 시간 복잡도라고 쳐도 나머지 클러스터에 대해서 가장 유사도가 가까운 것을 택해야 해서 중간에 그만두는 경우는 없는것으로 생각합니다.

제가 알고리즘을 잘못 이해하고 있을수도 있는거니 참고 바랍니다. ^^;

최종욱

하나 들어올 때마다 기존 클러스터들의 대표값에 하나하나 비교해보고 적당한 것에 넣는 식입니다. 말씀하신 대로 중간에 그만두는 경우는 없겠죠.

최종 클러스터의 개수가 log n에 비례한다면 당연히 O(n log n)일텐데요. 최종 클러스터의 개수가 n에 비례하면 O(n^2)겠군요. 단순히 클러스터 수가 적어서 빠른 것이었다니. OTL. 아래에 그 내용이 있습니다.

… As its name implies, this method requires only one pass through the dataset; the time requirements are typically of order O(NlogN) for order O(logN) clusters. This makes it a very efficient clustering method for a serial processor. A disadvantage is that the resulting clusters are not independent of the order in which the documents are processed, with the first clusters formed usually being larger than those created later in the clustering run …

( http://members.tripod.com/asim_saeed/paper.htm )

최종욱

다시 생각해봤는데요, B Tree 처럼 클러스터링을 하면 O(n log n) 속도가 나올 것 같네요;