본문 바로가기

Python

[Python] 코사인 유사도(Cosine Similarity)

반응형

코사인 유사도에대해 설명 드리겠습니다. 워낙 여러 게시들이 있지만 저만의 생각 정리와 헷갈렸던 부분에 대해 포스팅하겠습니다.


 

코사인 유사도란?

코사인 유사도에 대해서 위키에서는 아래와 같이 설명이 나와 있습니다.

코사인 유사도(― 類似度, 영어: cosine similarity)는 내적공간의 두 벡터간 각도의 코사인값을 이용하여 측정된 벡터간의 유사한 정도를 의미한다. 각도가 0°일 때의 코사인값은 1이며, 다른 모든 각도의 코사인값은 1보다 작다. 따라서 이 값은 벡터의 크기가 아닌 방향의 유사도를 판단하는 목적으로 사용되며, 두 벡터의 방향이 완전히 같을 경우 1, 90°의 각을 이룰 경우 0, 180°로 완전히 반대 방향인 경우 -1의 값을 갖는다. 이 때 벡터의 크기는 값에 아무런 영향을 미치지 않는다. 코사인 유사도는 특히 결과값이 [0,1]의 범위로 떨어지는 양수 공간에서 사용된다.

 

 

출처 : 딥 러닝을 이용한 자연어 처리 입문(https://wikidocs.net/24603)

 

위 그림을 보면서 저는 이렇게 정의했습니다.(위 그림이 정말 이해하기 쉽게 잘 만들어 주셨습니다.)

 - 두 직선의 방향과 각도가 비슷한지 를 보는 것

 - 코사인유사도 값의 범위는 -1 ~ 1

 - 방향과 같도가 같으면 1, 완전 반대면 -1

 

 

반응형

코사인유사도는 주로 자연어처리에서 많이 사용되는 것으로 보여집니다. 문장의 키워드를 추출하여 키워드를 메트릭스로 만든 후 코사인 유사도를 적용해주면 두 문장의 유사한 정도를 추출할 수 있습니다.(물론 코사인유사만을 사용했을 때...)

 

저는 물체의 움직임에 대한 로직을 개발하는데 적용했습니다. 코사인유사도를 구하는 2개의 Python 소스코드입니다.

 

 

import math
from numpy import dot
from numpy.linalg import norm

#코사인 유사도1
def CalcCosSim(a, b) :
    return dot(a, b)/(norm(a) * norm(b))

#코사인 유사도2
def CalcCosSim2(a, b) :
    dot1=0
    for i, v in enumerate(a) :
        dot1 += v * b[i]

    norm1 = math.sqrt(sum([x ** 2 for x in a]))
    norm2 = math.sqrt(sum([x ** 2 for x in b]))

    return dot1 / (norm1 * norm2)

 

위 소스는 동일한 소스코드입니다. 위에 소스코드가 워낙 간단하게 되있어서 약간 풀어서 #코사인유사도2를 올렸습니다. 참고하시면 좋을것 같습니다. 

 

 

위 그림은 두 점에 대한 코사인 유사도 함수를 통해 추출한 두개의 값입니다. 동일하게 나오는걸 보니 계산은 맞는 것 같습니다. 추가적으로 당연하듯 다른 분들은 이해하셨을 수 있지만.... 저는 매우 헷갈렸던 부분입니다.

 

두 점만 넣으면 유사도가 나오는 것을 보고 무슨 기준으로 값이 각도가 나오는지 도무지 이해가 가지 않았습니다. 그러던 중 알게된것.... 위 그림과 같이 기준점은 (0,0) 이였습니다.

 

 

(0,0) → (1,1)의 각도와 (0,0) → (5,3)의 각도를 비교한 유사도가 추출됩니다.

기준점을 변경하고 싶다면.... 모두 상대 좌표로 치환하고 사용하시면 됩니다.

 

 

반응형