코사인 유사도(cosine similarity)는 두 벡터간의 방향 유사도를 나타내며 코사인 값으로 -1 ~ 1 사이의 값이 나온다.

1에 가깝다면 두 벡터는 같은 방향을 바라보고 있다는 의미이고 0에 가까우면 두 벡터는 직교 그리고 -1에 가까우면 두 벡터는 반대 방향을 바라보고 있다는 의미가 된다.

 

수식으로 살펴보면 아래와 같다.

$$similarity(V_{a}, V_{b}) = \frac{ V_{a} \cdot V_{b} }{ \|V_{a}\|_{2} \times \|V_{b}\|_{2} } = V_{a(normalized)} \cdot V_{b(normalized)}$$

 

계산을 진행 할 때는 맨 마지막 항 처럼 정규화된 두 벡터의 내적만 계산하면 되고, 이를 numpy를 사용하여 그대로 구현하면 아래와 같이 작성을 할 수 있다.

 

코드에는 eps를 사용하여 만약 L2 norm 값이 1e-12보다 작은 경우(사실 원래 목적은 0이 되는 걸 방지하려고 넣은거임)를 제거하기 위해서 추가하였다.

 

사실 pytorch나 scikit-learn에 있는 코사인 유사도를 사용하면 편하지만, numpy로 구현한 이유는 속도 측면에서 이득이 있기 때문에 이렇게 구현했다. 간단하게 scikit-learn과 numpy를 비교한 결과는 아래 그림1과 같다.

 

그림1 어레이 크기에 따른 scikit-learn과 numpy의 간단한 속도 비교결과

 

비교에 각 2차원 어레이를 사용하였다. 예로 가로축 값이 10이면 10x10 행렬을 계산에 사용했다는 의미가 되며 세로축은 해당 행렬을 계산하는데 걸린 시간을 의미한다.

 

실험을 진행한 코드는 아래와 같다.

결론은 큰 차이를 보기 힘들엇지만 시간이 중요하다면 이렇게 만들어서 사용하는 것도 괜찮을 것 같다.

+ Recent posts