# 1. 유사도란?
hat, cat
위와 같은 문자열 2개가 있다고 해보자. 둘은 얼마나 유사할까?
단순히 문자간의 배열이 같은지, 의미상의 유사성 등 다양한 방식으로 유사한 정도를 표현할 수 있을 것이다.
이처럼 ’유사성’이란 ’비슷한 정도’를 수치적으로 표현한 것을 의미한다.
자연어 처리에서 일반적으로 사용하는 몇가지 유사도 기법이 있다.
이번 글에서는 그에 대해 설명해보고자 한다.
# 2. 코사인 유사도(Cosine Similarity)
코사인 유사도는 말그대로 코사인의 특성을 그대로 가져온 것이다.
코사인 값은 두 벡터 사이의 각도로 결정된다.
학습에 앞서 Raw Data를 전처리하는 과정에서 자연어를 단어, 어간/어미 단위로 쪼갠 뒤에 이를 정수에 대치하는 인코딩을 한다.
하나의 문장을 최소단위로 토큰화 및 정수 인코딩을 진행하여 정수로 표현한 것을 Zero Padding을 해서 길이를 맞춰주게 되면 하나의 정수 벡터를 만들 수 있다.
이것을 바탕으로 각 벡터(문장)간의 코사인 값을 구하는 것을 코사인 유사도라고 할 수 있다.
계산을 위한 수식은 아래와 같다.
> $similarity = cos(\Theta) = \frac{{A \cdot B}}{||A||\ ||B||} = \frac{\sum_{i=1}^{n} A_i \times B_i}{\sqrt{\sum_{i=1}^{n}(A_i)^2}\times\sqrt{\sum_{i=1}^{n}(B_i)^2}}$
코사인의 치역(출력)은 -1~1이므로 벡터(문장)가 일치할수록 절댓값이 1에 가까울 것이고, 벡터가 다를수록 0에 가까워질 것이다.
단순한 예시를 살펴보도록 하자
위 코드는 이미 단어집합에 맞춰 카운트로 인코딩된 문장 doc1, doc2, doc3 이 있다는 가정 하에 코사인 유사도를 계산한 것이다.
numpy.linalg.norm() 함수를 이용해 원점에서 벡터까지의 거리를 구한 뒤 수식에 대입하였다.
doc2, doc3은 벡터의 크기가 2배가 되었을 뿐이므로 문장이 동일하다고 표기되고 있다.
반대로 doc1, doc2 / doc1, doc3은 모두 한자리씩 달라서 코사인값이 0.67이 된 모습을 확인할 수 있다.
# 3. 유클리드 거리(Euclidean Distance)
다차원 공간에서 두 점간의 거리를 비교하는 것이다. 많이 쓰이지는 않는다.
수식은 다음과 같다.
$\sqrt{(q_1 - p_1)^{2} + ... + (q_n - p_n)^{2}} = \sqrt{\sum_{i=1}^n (q_i - p_i)^2}$
# 4. 자카드 유사도(Jaccard Similaity)
자카드 유사도는 두 문장을 이루는 단어들을 원소로하는 집합을 만든 뒤에 두 문장의 합집합과 교집합의 비율을 표시하는 기법이다.
예를들어 문장 2개가 있을 때, 각 문장을 단어집합에 들어가는 단어 단위로 토큰화를 한다.
그렇게 만들어진 각 문장의 단어로 이루어진 집합을 각각 A, B라고 하자.
A와 B의 교집합이 있을 수도 있고, 없을 수도 있다.
이 경우, 다음 수식을 따른다.
$Jaccard Similarity = \frac{P(A \cap B)}{P \cup B}$
비슷한 주제의 문장을 다루는 경우에 효과적이라고 생각된다.
5. 레벤슈타인 유사도(Levenshtein Distance)
레벤슈타인 유사도는 문자열이 얼마나 비슷한지를 나타낸다.
말그대로 문자열을 얼마나 바꾸면 목표하는 문자열이 되는지를 계산한 것이다.
예를들어,
> hat, here
두 문자열이 있다고 해보자. 이들의 편집거리(레벤슈타인 거리)는 3이다 > h -> h (동일, 편집+0회)
> a -> e (수정, 편집+1회)
> t -> r (수정, 편집+1회)
> -> e (삽입, 편집+1회)
>총 편집 횟수) 3회
이같은 방법으로 유사도를 찾는 것이다.
영어같은 경우에는 단순하게 코드를 작성 할 수 있지만 한글의 경우는 고려할 점이 있다.
> 신라면, 푸라면
이 두 문자열에 대해서는 ’신’과 ’푸’가 다르다는 것을 알 수 있다.
그렇다면 이 문자열은 몇번 편집해야 하는가? 라고 묻는다면 3회라고 해야한다.
따라서 이를 해결하기 위해 한글 유니코드표를 대조하여 레벤슈타인 거리를 계산하는 방법을 취해야만 정확한 편집거리를 구할 수 있다.