문서들 간에 유사도를 구하기 위해서는 문서마다 동일한 단어나 비슷한 단어가 얼마나 사용되었는지를 파악할 수 있다. BoW, DTM, TF-IDF, Word2Vec 등의 방법으로 단어를 수치화 했다면, 유사도 기법을 사용하여 문서의 유사도를 구하는 게 가능하다.
- 코사인 유사도(Cosine similarity) 는 두 벡터의 방향에 따라 1~ -1 의 값을 가지며 1에 가까울수록 유사하다.
- 유클리드 거리(Euclidean distance) 는 두 점 사이의 직선 거리를 구하여 거리의 값이 작을수록 유사하다.
- 자카드 유사도(Jaccard similarity) 는 두개의 집합이 있을 때 합집합에서 교집합의 비율을 구하며, 1에 가까울 수록 유사하다.
문서1 : 저는 사과 좋아요
문서2 : 저는 바나나 좋아요
문서3 : 저는 바나나 좋아요 저는 바나나 좋아요
위 문서간의 유사도 구하기
from sklearn.feature_extraction.text import CountVectorizer from numpy import dot from numpy.linalg import norm import numpy as np corpus = [ "저는 사과 좋아요", "저는 바나나 좋아요", "저는 바나나 좋아요 저는 바나나 좋아요", ] vector = CountVectorizer() dtm = vector.fit_transform(corpus).toarray() print(dtm) # [[0 1 1 1] # [1 0 1 1] # [2 0 2 2]] def cos_sim(A, B): return dot(A, B) / (norm(A)*norm(B)) print(cos_sim(dtm[0], dtm[1])) #문서1과 문서2의 코사인 유사도 0.6666666666666667 print(cos_sim(dtm[0], dtm[2])) #문서1과 문서3의 코사인 유사도 0.6666666666666667 print(cos_sim(dtm[1], dtm[2])) #문서2과 문서3의 코사인 유사도 1.0000000000000002 def dist(A, B): return np.sqrt(np.sum((A-B)**2)) print(dist(dtm[0], dtm[1])) #문서1과 문서2의 유클리드 거리 1.4142135623730951 print(dist(dtm[0], dtm[2])) #문서1과 문서3의 유클리드 거리 2.6457513110645907 print(dist(dtm[1], dtm[2])) #문서2과 문서3의 유클리드 거리 1.7320508075688772 corp1 = corpus[0].split() corp2 = corpus[1].split() corp3 = corpus[2].split() def jaccard(A, B): union = set(A).union(set(B)) # 합집합 intersection = set(A).intersection(set(B)) # 교집합 return len(intersection) / len(union) print(jaccard(dtm[0], dtm[1])) #문서1과 문서2의 자카드 유사도 1.0 print(jaccard(dtm[0], dtm[2])) #문서1과 문서3의 자카드 유사도 0.3333333333333333 print(jaccard(dtm[1], dtm[2])) #문서2과 문서3의 자카드 유사도 0.3333333333333333 | cs |
위 코드에서 처럼 문서의 유사도의 성능은 각 문서의 단어들의 수치화 방법, 유사도 방법에 따라 다르다는 것을 알 수 있다.
WRITTEN BY
- 손가락귀신
정신 못차리면, 벌 받는다.
,