4.4 유클리드 거리와 유사도

유사도를 측정하는 일반적인 방법 중 하나는 거리(Distance/Metric)를 측정하는 것입니다. 보통 거리라고 함은 두 장소의 가깝고 먼 정도를 표현하는 개념이지만 여기에서는 두 데이터 포인트(Data Point)의 가깝고 먼 정도, 즉 n차원의 벡터로 표현되는 데이터 포인트 간 거리를 의미합니다. 두 데이터 포인트의 거리가 가까울수록 비슷한 것이고 멀수록 두 데이터 포인트는 서로 다르다고 할 수 있습니다.

이처럼 거리는 유사도의 반대 개념(Inverse)으로 유사도가 1이면 거리는 0이 되어 거리를 비유사도(Dissimilarity)라고도 합니다. 여기에서는 두 점 사이의 직선 거리를 계산할 때 흔히 쓰이는 유클리드 거리(Euclidean Distance)를 유사도 계산을 위한 거리 측도로 사용합니다. 평점 데이터의 유클리드 거리를 사용하는 유사도 계산은 두 사용자 모두에게 평가된 아이템 집합의 평점 간의 유사도를 계산하는 사용자-사용자 유사도(이하 사용자 유사도)와 두 아이템 모두 평가한 사용자 집합의 평점 간의 유사도를 계산하는 아이템-아이템 유사도(이하 아이템 유사도) 계산의 두 가지 방법을 살펴봅니다.

4.4.1 수식 살펴보기

여기에서는 유클리드 거리 계산을 위한 수식을 먼저 살펴보고, 사용자-사용자 간 유클리드 유사도 계산과 아이템-아이템 유클리드 유사도 계산에 대한 수식을 살펴봅니다.

4.4.1.1 유클리드 거리와 유사도

두 점 사이의 직선거리를 계산하기 위한 유클리드 거리 계산을 위한 수식을 이해하는 데 맨해튼 거리 계산을 위한 수식과 유클리드 거리와 맨해튼 거리를 일반화한 민코우스키 거리 계산을 위한 수식도 함께 살펴봅니다.

다음 그림은 3차원 공간에 서로 수직인 3개의 좌표 축(X, Y, Z)의 좌표로 공간상의 위치를 예를 들어 나타낸 것입니다. 여기에서 a, b는 원점을 기준으로 한 X Y Z의 방향과 크기인 데이터 포인트로 (1,3,4)와 (3,2,3)입니다. 유클리드 거리는 그림에서 실선으로 표현된 두 데이터 포인트 사이의 거리 중 가장 짧은 거리인 직선 거리이며, 맨해튼 거리는 그림에서 점선으로 표현된 두 데이터 포인트에 투영된 선분 길이의 합으로 간단하게 각 차원의 절대값을 합산한 거리입니다.

Download

[3차원 공간의 두 데이터] [포인트 예시]

임의의 벡터 ${{\bf{x}}_a}$와 ${{\bf{x}}_b}$간의 유클리드 거리는 다음과 같이 정의됩니다.

$$ \begin{flalign} \notag \mathrm{dist} _{euclidean} ({{\bf{x}}_a},{{\bf{x}}_b}) = \sqrt {\sum\nolimits _{i=1}^{n} {{{({a_i} - {b_i})}^2}} } \end{flalign} $$

예를 들어 예시 데이터로 유클리드 거리를 계산해 봅니다. 두 벡터 (1,3,4)와 (3,2,3)의 유클리드 거리는 $\sqrt {{{(1 - 3)}^2} + {{(3 - 2)}^2} + {{(4 - 3)}^2}} = \sqrt {4 + 1 + 1} $로 2.4494897이 됩니다.

유클리드 거리의 확장인 가중 유클리드 거리(WED: Weighted Euclidean Distance)는 다음과 같이 정의됩니다.

$$ \begin{flalign} \notag \mathrm{dist} _{\mathit{WeightedEuclidean}} ({{\bf{x}}_a},{{\bf{x}}_b}) = \sqrt {\sum\nolimits _{i=1}^{n} {{w_i}{{({a_i} - {b_i})}^2}} } \end{flalign} $$

여기에서 $w_i$은 가중치(Weight)로 여기에서는 축척을 나타내는 환산 계수(Scaling Factor)를 사용합니다.

축척을 나타내는 환산 계수는 다음과 같이 정의됩니다.

$$ \begin{flalign} \notag SF = \frac{AS}{PS} \end{flalign} $$

여기에서 $SF$는 환산 계수(Scale Factor), $AS$는 실제 척도(Actual Scale)로 $PS$는 기준 척도(Principle Scale)입니다.

임의의 벡터 ${{\bf{x}}_a}$와 ${{\bf{x}}_b}$간의 맨해튼 거리는 다음과 같이 정의됩니다.

$$\mathrm{dist} _{manhattan} ({{\bf{x}}_a},{{\bf{x}}_b}) = \sum\nolimits _{i=1}^{n} {\left| {{a_i} - {b_i}} \right|} $$

예를 들어 예시 데이터로 맨해튼 거리를 계산해 봅니다. 두 벡터 (1,3,4)와 (3,2,3)의 맨해튼 거리는 $\left| {1 - 3} \right| + \left| {3 - 2} \right| + \left| {4 - 3} \right| = 2 + 1 + 1$로 4가 됩니다.

임의의 벡터 ${{\bf{x}}_a}$와 ${{\bf{x}}_b}$간의 민코우스키 거리는 다음과 같이 정의됩니다.

$$\mathrm{dist}({{\bf{x}}_a},{{\bf{x}}_b}) _{minkowski} = ( \sum\nolimits _{i=1}^{n} |a_i - b_i|^p )^{\frac {1} {p}}$$

여기에서 $p$은 거리의 차수(degree)로 $p > 1$ 입니다. $p = 1$ 인 경우에는 때 맨해튼(city block, taxicab 또는 L1 norm) 거리, $p = 2$인 경우에는 유클리드 거리(L2 norm), $p \to \infty $이면 체비셰프(supremum, ${L_{\max }}$ norm 또는 ${L_\infty }$ norm) 거리입니다.

임의의 벡터 ${{\bf{x}}_a}$와 ${{\bf{x}}_b}$간의 유클리드 거리를 2차-민코우스키 거리로 일반화한 형태는 다음과 같이 정의됩니다.

$$\mathrm{dist} _{euclidean} ({{\bf{x}}_a},{{\bf{x}}_b}) = ( \sum\nolimits _{i=1}^{n} |a_i - b_i|^2 )^{\frac {1} {2}} = \sqrt {\sum\nolimits _{i=1}^{n} {{{\left| {{a_i} - {b_i}} \right|}^2}} } $$

예를 들어 예시 데이터로 2차-민코우스키 거리를 계산해 봅니다. 두 벡터 (1,3,4)와 (3,2,3)의 L2 거리는 $\sqrt {{{\left| {1 - 3} \right|}^2} + {{\left| {3 - 2} \right|}^2} + {{\left| {4 - 3} \right|}^2}} = \sqrt {4 + 1 + 1} $로 2.4494897이 됩니다. 계산 결과가 유클리드 거리와 같음을 확인할 수 있습니다.

임의의 벡터 ${{\bf{x}}_a}$와 ${{\bf{x}}_b}$간의 맨해튼 거리를 1차-민코우스키 거리로 일반화한 형태는 다음과 같이 정의됩니다.

$$\mathrm{dist} _{manhattan} ({{\bf{x}}_a},{{\bf{x}}_b}) = ( \sum\nolimits _{i=1}^{n} |a_i - b_i|^1 )^{\frac {1} {1}} = \sum\nolimits _{i=1}^{n} {\left| {{a_i} - {b_i}}\right|} $$

예를 들어 예시 데이터로 1차-민코우스키 거리를 계산해 봅니다. 두 벡터 (1,3,4)와 (3,2,3)의 L1 거리는 $\left| {1 - 3} \right| + \left| {3 - 2} \right| + \left| {4 - 3} \right| = 2 + 1 + 1$로 4가 됩니다. 계산 결과가 맨해튼 거리와 같음을 확인할 수 있습니다.

거리(비유사도)를 사용한 임의의 벡터 ${{\bf{x}}_a}$와 ${{\bf{x}}_b}$간의 유사도는 다음과 같이 정의됩니다.

$$ \begin{flalign} \notag \mathrm{sim}({{\bf{x}}_a},{{\bf{x}}_b}) = \frac{1}{{1 + \mathrm{dist} ({{\bf{x}}_a},{{\bf{x}}_b})}} \end{flalign} $$

여기에서 $\mathrm{dist} ({{\bf{x}}_a},{{\bf{x}}_b})$는 두 벡터 간의 거리입니다.

Note:

유사도와 거리(비유사도)는 서로 역수의 관계로 유사할수록 거리가 더 가까워지기 때문에 유사도(0과 1사이의 범위로 0은 완전 불일치, 1은 완전 일치)에서 $\mathrm{dist}({{\bf{x}}_a},{{\bf{x}}_b}) = 1 - sim({{\bf{x}}_a},{{\bf{x}}_b})$과 같이 1에서 거리를 빼 주거나 $sim({{\bf{x}}_a},{{\bf{x}}_b}) = \frac{1}{{1 + \mathrm{dist}({{\bf{x}}_a},{{\bf{x}}_b})}}$과 같이 거리 값에 1을 더하고 역수를 취하여 0과 1사이의 범위 값을 가지는 유사도로 변환합니다. 여기에서 1을 더해 주는 이유는 거리가 0이 되는 경우 유사도 최댓값인 1이 되도록 하기 위해서입니다.

4.4.1.2 사용자 유클리드 유사도

사용자 유클리드 유사도는 두 사용자 모두에게 평가된 아이템 집합의 평점간 유사도를 계산합니다. 임의의 사용자 $u$와 사용자 $v$의 유클리드 거리는 다음과 같이 정의됩니다.

$$ \begin{flalign} {\mathrm{dist} _{euclidean}}(u,v) & = \sqrt{\sum\nolimits_{i \in {I_u} \cap {I_v}} (r_{ui} - r_{vi})^2} \end{flalign} $$

여기에서 ${I_u} \cap {I_v}$는 사용자 $u$와 사용자 $v$ 모두에게 평가된 아이템 집합, $r_{ui}$와 ${r_{vi}}$는 사용자 $u$와 사용자 $v$가 아이템 $i$에 매긴 평점입니다.

여기에서는 유클리드 거리 대신 환산 계수(Scale Factor)를 가중치로 부여한 가중 유클리드 거리를 사용합니다. 환산 계수는 결측값을 고려한 비례 변환(Proportional Scaling)을 위해 계산에 사용된 아이템 비율의 역수입니다.

임의의 사용자 $u$와 사용자 $v$의 가중 유클리드 거리는 다음과 같이 정의됩니다.

$$ \begin{flalign} \mathrm{dist} _{\mathit{WeightedEuclidean}} (u,v) & = \sqrt{\sum\nolimits_{i \in {I_u} \cap {I_v}} {w_i} (r_{ui} - r_{vi})^2} \end{flalign} $$

여기에서 ${w_i}$는 가중치로 전체 아이템 집합 $I$와 사용자 $u$와 사용자 $v$ 모두에게 평가된 아이템 집합 ${I_u} \cap {I_v}$의 원소 개수의 비의 역수 $\frac{{\left| I \right|}}{{\left| {{I_u} \cap {I_v}} \right|}}$, ${I_u} \cap {I_v}$는 사용자 $u$와 사용자 $v$ 모두에게 평가된 아이템 집합, $r_{ui}$와 ${r_{vi}}$는 사용자 $u$와 사용자 $v$가 아이템 $i$에 매긴 평점입니다.

임의의 사용자 $u$와 사용자 $v$의 사용자 유사도는 다음과 같이 정의됩니다.

$$ \begin{flalign} \notag \mathrm{sim}(u,v) = \frac{1}{{1 + \mathrm{dist} (u,v)}} \end{flalign} $$

여기에서 $\mathrm{dist} (u,v)$는 사용자 $u$와 사용자 $v$의 거리입니다.

4.4.1.3 아이템 유클리드 유사도

아이템 유클리드 유사도는 두 아이템을 모두 평가한 사용자 집합의 평점간 유사도를 계산합니다. 임의의 아이템 $i$와 아이템 $j$의 유클리드 거리는 다음과 같이 정의됩니다.

$$ \begin{flalign} \mathrm{dist} _{euclidean} (i,j) & = \sqrt{\sum\nolimits_{u \in {U_i} \cap {U_j}} (r_{ui} - r_{uj})^2} \end{flalign} $$

여기에서 ${U_i} \cap {U_j}$는 아이템 $i$와 $j$를 모두 평가한 사용자 평점 집합, $r_{ui}$와 ${r_{uj}}$는 사용자 $u$가 아이템 $i$와 아이템 $j$에 매긴 평점입니다.

여기에서는 유클리드 거리 대신 환산 계수(Scale Factor)를 가중치로 부여한 가중 유클리드 거리를 사용합니다. 환산 계수는 결측값을 고려한 비례 변환(Proportional Scaling)을 위해 계산에 사용된 아이템 비율의 역수입니다.

임의의 아이템 $i$와 아이템 $j$의 가중 유클리드 거리는 다음과 같이 정의됩니다.

$$ \begin{flalign} \mathrm{dist} _{\mathit{WeightedEuclidean}} (i,j) & = \sqrt{\sum\nolimits_{u \in {U_i} \cap {U_j}} {w_u} (r_{ui} - r_{uj})^2} \end{flalign} $$

여기에서 ${w_u}$는 가중치로 전체 사용자 집합 $U$와 아이템 $i$와 아이템 $j$를 모두 평가한 사용자 집합 ${U_i} \cap {U_j}$의 원소 개수의 비의 역수 $\frac{{\left| U \right|}}{{\left| {{U_i} \cap {U_j}} \right|}}$, ${U_i} \cap {U_j}$는 아이템 $i$와 아이템 $j$를 모두 평가한 사용자 집합, $r_{ui}$와 ${r_{uj}}$는 사용자 $u$가 아이템 $i$와 아이템 $j$에 매긴 평점입니다.

아이템 유클리드 유사도는 다음과 같이 정의됩니다.

$$ \begin{flalign} \mathrm{sim} _{euclidean} (i,j) & = \frac{1}{{1 + \mathrm{dist} _{euclidean} (i,j)}} \end{flalign} $$

여기에서 ${\mathrm{dist} _{euclidean}}(i,j)$는 아이템 $i$와 아이템 $j$의 유클리드 거리입니다.

임의의 아이템 $i$와 아이템 $j$의 아이템 유사도는 다음과 같이 정의됩니다.

$$ \begin{flalign} \notag \mathrm{sim}(i,j) = \frac{1}{{1 + \mathrm{dist} (i,j)}} \end{flalign} $$

여기에서 $\mathrm{dist} (i,j)$는 아이템 $i$와 아이템 $j$의 거리입니다.

4.4.2 직접 계산해보기

이제부터 예제 데이터셋을 사용하여 앞서 살펴본 수식으로 직접 계산해 볼 것입니다. 다음 표는 평점 데이터를 사용자는 행, 아이템은 열로 나타낸 것입니다.

예제 데이터셋의 평점 데이터

사용자/아이템 $i_1$ $i_2$ $i_3$ $i_4$ $i_5$ $i_6$ $i_7$ $i_8$ $i_9$ $i_{10}$
$u_1$ 0.5 5 1 3 3.5 5 2.5
$u_2$ 3 2 3.5 2 4 4 1
$u_3$ 3.5 1 3.5 4 1 3.5
$u_4$ 3 5 0.5 3.5 3.5 4.5
$u_5$ 3 4 2.5 4

4.4.2.1 사용자 유클리드 유사도

사용자 유클리드 유사도는 평점 데이터로 다음 수식을 사용하여 계산해 볼 것입니다.

  • 유클리드 거리
  • 가중 유클리드 거리

다음 표는 평점 데이터를 사용자는 행, 아이템은 열로 나타낸 것입니다.

평점 데이터

사용자/아이템 $i_1$ $i_2$ $i_3$ $i_4$ $i_5$ $i_6$ $i_7$ $i_8$ $i_9$ $i_{10}$
$u_1$ 0.5 5 1 3 3.5 5 2.5
$u_2$ 3 2 3.5 2 4 4 1
$u_3$ 3.5 1 3.5 4 1 3.5
$u_4$ 3 5 0.5 3.5 3.5 4.5
$u_5$ 3 4 2.5 4

예를 들어 사용자 $u_4$와 사용자 $u_5$의 유사도를 유클리드 거리를 사용하여 계산해 봅니다. 다음 표는 사용자 $u_4$와 사용자 $u_5$의 평점 데이터를 사용자는 행, 아이템은 열로 나타낸 것입니다.

사용자 $u_4$와 사용자 $u_5$의 평점 데이터

사용자/아이템 $i_1$ $i_2$ $i_3$ $i_4$ $i_5$ $i_6$ $i_7$ $i_8$ $i_9$ $i_{10}$
$u_4$ 3 5 0.5 3.5 3.5 4.5
$u_5$ 3 4 2.5 4

여기에서 사용자 $u_4$와 사용자 $u_5$가 공통으로 평가한 아이템 {$i_2$, $i_6$}에 대한 각 사용자의 평점은 {5, 3.5}와 {3, 2.5}입니다. 두 사용자의 유클리드 거리는 $2.236067$이 되지만 가중 유클리드 거리는 전체 10개의 아이템 중 공통으로 평가한 2개의 아이템만 대상으로 하기 때문에 환산 계수 $5$를 곱하여 거리를 보정한 $5$가 됩니다.

$$ \begin{flalign} \mathrm{dist} _{euclidean} (u_4,u_5) & = \sqrt{(5 - 3)^2 + (3.5 - 2.5)^2} \\ & = \sqrt {5} \\ & = 2.236067 \end{flalign} $$
$$ \begin{flalign} \mathrm{dist} _{\mathit{WeightedEuclidean}} (u_4,u_5) & = \sqrt{\frac{10}{2} \times 5 } \\ & = \sqrt {25} \\ & = 5 \end{flalign} $$

유사도는 유클리드 거리라면 $0.309$, 가중 유클리드 거리라면 $0.1666$가 됩니다.

$$ \begin{flalign} \mathrm{sim} _{euclidean} (u_4,u_5) & = \frac{1}{{1 + 2.236067}} \\ & \approx 0.309 \end{flalign} $$
$$ \begin{flalign} \mathrm{sim} _{\mathit{WeightedEuclidean}} (u_4,u_5) & = \frac{1}{{ 1 + 5}} \\ & \approx 0.166 \end{flalign} $$

다음 표는 직접 계산한 결괏값을 나타낸 것입니다.

계산 결과

유클리드 거리 유사도 환산계수 가중 유클리드 거리 유사도
2.236067 0.309 5 5 0.166

다음 표는 사용자 유클리드 유사도와 사용자 가중 유클리드 유사도를 모두 계산해 봅니다. 다음 표는 사용자 유사도 데이터를 사용자(LHS)는 행, 사용자 (RHS)는 열로 나타낸 것입니다.

사용자 가중 유클리드 유사도 데이터

사용자(RHS) 사용자(LHS) $u_1$ $u_2$ $u_3$ $u_4$ $u_5$
$u_1$ 1 0.126132 0.1782604 0.1957744 0.1468542
$u_2$ 0.126132 1 0.1617047 0.140376 0.3288131
$u_3$ 0.1782604 0.1617047 1 0.128193 0.1390551
$u_4$ 0.1957744 0.140376 0.128193 1 0.1666667
$u_5$ 0.1468542 0.3288131 0.1390551 1

사용자 유클리드 유사도 데이터

사용자(RHS) 사용자(LHS) $u_1$ $u_2$ $u_3$ $u_4$ $u_5$
$u_1$ 1 0.1695208 0.2553968 0.2779263 0.2139388
$u_2$ 0.1695208 1 0.2337148 0.2296685 0.472136
$u_3$ 0.2553968 0.2337148 1 0.1886379 0.22773
$u_4$ 0.2779263 0.2296685 0.1886379 1 0.309017
$u_5$ 0.2139388 0.472136 0.22773 0.309017 1

다음 표는 사용자 $u_5$의 사용자 가중 유클리드 유사도와 사용자 유클리드 유사도를 유사도가 높은 순으로 비교하여 나타낸 것입니다.

사용자 $u_5$의 사용자 유클리드 유사도 비교

순위 가중 유클리드 유클리드
사용자 유사도 사용자 유사도
1 $u_5$ 1 $u_5$ 1
2 $u_2$ 0.3288131 $u_2$ 0.472136
3 $u_4$ 0.1666667 $u_4$ 0.309017
4 $u_1$ 0.1468542 $u_3$ 0.22773
5 $u_3$ 0.1390551 $u_1$ 0.2139388

사용자 가중 유클리드 유사도와 사용자 유클리드 유사도의 유사도 순위가 4번째, 5번째에서 서로 다른 결과가 나오는 것을 확인할 수 있습니다.

4.4.2.2 아이템 유클리드 유사도

아이템 유클리드 유사도는 평점 데이터로 다음 수식을 사용하여 계산해 볼 것입니다.

  • 유클리드 거리
  • 가중 유클리드 거리

다음 표는 평점 데이터를 사용자는 행, 아이템은 열로 나타낸 것입니다.

평점 데이터

사용자/아이템 $i_1$ $i_2$ $i_3$ $i_4$ $i_5$ $i_6$ $i_7$ $i_8$ $i_9$ $i_{10}$
$u_1$ 0.5 5 1 3 3.5 5 2.5
$u_2$ 3 2 3.5 2 4 4 1
$u_3$ 3.5 1 3.5 4 1 3.5
$u_4$ 3 5 0.5 3.5 3.5 4.5
$u_5$ 3 4 2.5 4

예를 들어 아이템 $i_3$과 아이템 $i_1$의 유사도를 유클리드 유사도를 사용하여 계산해 봅니다. 다음 표는 아이템 $i_3$과 아이템 $i_1$의 평점 데이터를 사용자는 행, 아이템은 열로 나타낸 것입니다.

아이템 $i_3$과 아이템 $i_1$의 평점 데이터

사용자 아이템 $u_1$ $u_2$ $u_3$ $u_4$ $u_5$
$i_3$ 1 3.5 1 4
$i_1$ 0.5 3 3

여기에서 아이템 $i_3$과 아이템 $i_1$을 공통으로 평가한 사용자 {$u_3$, $u_1$}에 대한 각 아이템의 평점은 {1, 3.5}와 {0.5, 3}입니다. 두 아이템의 유클리드 거리는 $0.707107$가 되지만 가중 유클리드 거리는 전체 5명의 사용자 중 공통으로 평가한 2명의 사용자만 대상으로 하기 때문에 환산 계수 $2.5$를 곱하여 거리를 보정한 $1.11803$가 됩니다.

$$ \begin{flalign} \mathrm{dist} _{euclidean} (i_3, i_1) & = \sqrt{(1 - 0.5)^2 + (3.5 - 3)^2} \\ & = \sqrt {0.5} \\ & = 0.707107 \end{flalign} $$
$$ \begin{flalign} \mathrm{dist} _{\mathit{WeightedEuclidean}} (i_3, i_1) & = \sqrt{\frac{5}{2} \times 0.5 } \\ & = \sqrt {1.25} \\ & = 1.11803 \end{flalign} $$

유사도는 유클리드 거리라면 $0.5857$, 가중 유클리드 거리라면 $0.4721$가 됩니다.

$$ \begin{flalign} \mathrm{sim} _{euclidean} (i_3, i_1) & = \frac{1}{1 + 0.707107} \\ & \approx 0.5857 \end{flalign} $$
$$ \begin{flalign} \mathrm{sim} _{\mathit{WeightedEuclidean}} (i_3, i_1) & = \frac{1}{1 + 1.11803} \\ & \approx 0.4721 \end{flalign} $$

다음 표는 직접 계산한 결괏값을 나타낸 것입니다.

계산 결과

유클리드 거리 유사도 환산계수 가중 유클리드 거리 유사도
0.707107 0.5857 2.5 1.11803 0.4721

다음 표는 아이템 유클리드 유사도와 아이템 가중 유클리드 유사도를 모두 계산해 봅니다. 다음 표는 사용자 유사도 데이터를 사용자(LHS)는 행, 사용자 (RHS)는 열로 나타낸 것입니다.

아이템 가중 유클리드 유사도 데이터

아이템(RHS) 아이템(LHS) $i_1$ $i_2$ $i_3$ $i_4$ $i_5$ $i_6$ $i_7$ $i_8$ $i_9$ $i_{10}$
$i_1$ 1 0.1335619 0.472136 0.19021 0 0.1987625 0.1666667 0 0.1176471 0.182744
$i_2$ 0.1335619 1 0.1504711 0.1468542 0.2347638 0.2003133 0.2234083 0 0.607719 0.19021
$i_3$ 0.472136 0.1504711 1 0.1782604 0.1721512 0.2365472 0.233024 NaN 0.1182282 0.1782604
$i_4$ 0.19021 0.1468542 0.1782604 1 0.2347638 0.1393817 0 0 0.1365271 0
$i_5$ 0 0.2347638 0.1721512 0.2347638 1 0 0 NaN 0 0
$i_6$ 0.1987625 0.2003133 0.2365472 0.1393817 0 1 0.2857143 0 0.1876128 0
$i_7$ 0.1666667 0.2234083 0.233024 0 0 0.2857143 1 NaN 0 0.1666667
$i_8$ 0 0 NaN 0 NaN 0 NaN 1 0 NaN
$i_9$ 0.1176471 0.607719 0.1182282 0.1365271 0 0.1876128 0 0 1 0
$i_{10}$ 0.182744 0.19021 0.1782604 0 0 0 0.1666667 NaN 0 1

아이템 유클리드 유사도 데이터

아이템(RHS) 아이템(LHS) $i_1$ $i_2$ $i_3$ $i_4$ $i_5$ $i_6$ $i_7$ $i_8$ $i_9$ $i_{10}$
$i_1$ 1 0.1659768 0.5857864 0.2708132 0 0.281729 0.2402531 0 0.1741124 0.2612039
$i_2$ 0.1659768 1 0.165296 0.1818182 0.3266316 0.2187842 0.2708132 0 0.6666667 0.2708132
$i_3$ 0.5857864 0.165296 1 0.2553968 0.2474402 0.2857143 0.281729 NaN 0.1749172 0.2553968
$i_4$ 0.2708132 0.1818182 0.2553968 1 0.3266316 0.2038684 0 0 0.2 0
$i_5$ 0 0.3266316 0.2474402 0.3266316 1 0 0 NaN 0 0
$i_6$ 0.281729 0.2187842 0.2857143 0.2038684 0 1 0.3874259 0 0.2296685 0
$i_7$ 0.2402531 0.2708132 0.281729 0 0 0.3874259 1 NaN 0 0.2402531
$i_8$ 0 0 NaN 0 NaN 0 NaN 1 0 NaN
$i_9$ 0.1741124 0.6666667 0.1749172 0.2 0 0.2296685 0 0 1 0
$i_{10}$ 0.2612039 0.2708132 0.2553968 0 0 0 0.2402531 NaN 0 1

NaN에 대한 설명 추가 필요 -> R코드 실행 결과에도 recommenderlab과 비교 설명 필요

다음 표는 아이템 $i_3$의 아이템 가중 유클리드 유사도와 아이템 유클리드 유사도를 유사도가 높은 순으로 비교하여 나타낸 것입니다.

아이템 $i_3$의 아이템 유클리드 유사도 비교

순위 가중 유클리드 유클리드
아이템 유사도 아이템 유사도
1 $i_3$ 1 $i_3$ 1
2 $i_1$ 0.472136 $i_1$ 0.5857864
3 $i_6$ 0.2365472 $i_6$ 0.2857143
4 $i_7$ 0.233024 $i_7$ 0.281729
5 $i_4$ 0.1782604 $i_4$ 0.2553968
6 $i_{10}$ 0.1782604 $i_{10}$ 0.2553968
7 $i_5$ 0.1721512 $i_5$ 0.2474402
8 $i_2$ 0.1504711 $i_9$ 0.1749172
9 $i_9$ 0.1182282 $i_2$ 0.165296
10 $i_8$ NaN $i_8$ NaN

아이템 가중 유클리드 유사도와 아이템 유클리드 유사도의 유사도 순위가 8번째, 9번째에서 서로 다른 결과가 나오는 것을 확인할 수 있습니다.

4.4.3 예제 코드 실행해보기

앞서 "직접 계산하기"에서는 예제 데이터셋의 평점 데이터를 사용하여 계산해 보았습니다. 이제부터는 평점 데이터 파일과 예제 코드를 사용하여 "직접 계산하기"의 계산 결과에 대해 한번 더 확인해 볼 것입니다.

"직접 계산하기"의 결과

“직접 계산하기”의 결과

구분 평점 정규화 결측값 처리 실제척도 좌변 우변 유사도 설명
사용자 유사도 없음 쌍대 열 제외 - $u_4$ $u_5$ 0.3090 두 사용자 모두에게 평가된 아이템 집합의 평점간 유사도
10 0.1666
아이템 유사도 - $i_3$ $i_1$ 0.5857 두 아이템을 모두 평가한 사용자 집합의 평점간 유사도
5 0.4721

4.4.3.1 구현 클래스 살펴보기

먼저 예제 코드에서 사용하는 평균 중심화가 구현된 EuclideanSimilarityMeasurer 클래스를 살펴봅니다. EuclideanSimilarityMeasurer 클래스는 Apache Spark ML 패키지의 추상 클래스인 Transformer 클래스를 상속받아 평점 데이터를 평균 중심화된 평점 데이터로 변환하는 transform 메서드를 구현한 클래스입니다.

다음 그림은 UML 클래스 다이어그램 표기법을 사용하여 EuclideanSimilarityMeasurer클래스를 클래스 다이어그램으로 나타낸 것입니다.

Download

[UML 클래스 다이어그램]

EuclideanSimilarityMeasurer 클래스는 평균 중심화를 위해 필요한 매개변수의 설정이나 기본값 변경이 필요한 경우에는 필요에 따라 다음 코드와 같이 빌더 패턴을 사용하여 인스턴스를 생성할 수 있습니다.

EuclideanSimilarityMeasurer measurer =
    new EuclideanSimilarityMeasurer()
        .setGroup(Group.USER)
        .setGroupCol("user")
        .setImputeZero(false)
        .setWeight(10)
        .setIds("u4", "u5")
        .setVerbose(true)
        .setUserCol("user")
        .setItemCol("item")
        .setRatingCol("rating")
        .setOutputCol("similarity");

EuclideanSimilarityMeasurer 클래스의 인스턴스에 설정 가능한 매개변수는 다음과 같습니다.

주요 매개변수

매개변수 유형 필수여부 기본값 설명
group Enum Group.USER 유사도 계산 기준을 Group 열거형 유형으로 설정(Group.USER: 사용자, Group.ITEM: 아이템)
groupCol String criterion 유사도 계산 기준을 문자열로 설정(“user”: 사용자, “item”:아이템).
imputeZero 쌍대 열의 어느 한쪽 값이 결측인 경우의 결측치 처리(true: 0 대체, false: 쌍대 열 제외)
actualScale Integer null 가중 유클리드 유사도 계산을 위한 실제 척도
ids - 유사도 계산 대상 ID(LHS) 지정(미지정시 전체 대상)
verbose boolean false 처리과정에 대한 정보를 출력할 것인지 여부 체크(기본값: false).
userCol String user 평점 데이터의 사용자 컬럼명(기본값: “user”)
itemCol String item 평점 데이터의 아이템 컬럼명(기본값: “item”)
ratingCol String rating 평점 데이터의 평점 컬럼명(기본값: “rating”)
outputCol String “similarity” 출력 컬럼명(기본값: “similarity”)으로 정규화된 평점

생성된 EuclideanSimilarityMeasurer 인스턴스는 RatingSimilarityMeasurer클래스에 구현된 transform 메서드를 사용하여 평점 데이터를 입력받아 평점을 평균 중심화된 평점으로 변환할 수 있습니다.

Dataset<Row> similarityDS = measurer.transform(ratingDS);

4.4.3.2 예제 코드 살펴보기

여기에서는 "직접 계산하기"의 계산 결과를 확인하기 위해 JUnit으로 작성된 예제 클래스의 소스 코드를 살펴봅니다. 다음은 r4tings-recommender 라이브러리에 포함된 코사인 유사도 계산을 위한 구현 클래스인 EuclideanSimilarityMeasurer 클래스를 이용하여 "직접 계산하기"의 계산 결과를 확인하기 위한 EuclideanSimilarityTest 클래스의 euclideanSimilarityExamples는 테스트 메서드입니다.

EuclideanSimilarityTest.java

소스 코드에서 볼 수 있듯이 대부분 코드는 테스트를 처리하기 위한 것이지만 기본 흐름은 매우 단순합니다. 먼저 ❶ 매개변수를 바꿔가면서 실행하고 결과를 확인하기 위한 CSV 형식의 인자 목록을 설정합니다( 23행~28행). 반복 실행되는 euclideanSimilarityExamples 메서드에서는 테스트 인자들을 매개변수로 받습니다. 다음으로 ❷ Parquet 유형의 평점 데이터를 읽어 들이고(38행) ❸ 평점 정규화가 필요한 경우에 평점을 정규화합니다(40행~42행).

다음으로 ❹ EuclideanSimilarityMeasurer 클래스의 인스턴스를 생성하고(44행~48행) ❺ 확장 유클리드 거리 계산을 위한 가중치(환산계수)가 필요한 경우에 설정합니다(50행~52행). ❻평점 데이터를 전달하여 유사도를 계산합니다 (54행). 마지막으로 ❼ "직접 계산하기"에서 계산해 본 결과에 해당하는 기댓값(Expected)과 예제 코드의 실행 결과인 실제 값(Actual)의 소수 자릿수 7자리까지 비교합니다(70행).

4.4.3.3 실행 결과 확인하기

여기에서는 앞서 살펴본 테스트 클래스인 EuclideanSimilarityTest클래스의 테스트 메서드인 euclideanSimilarityExamples의 실행 결과를 살펴봅니다. 다음과 같이 명령줄 인터페이스( CLI, Command line interface)에서 빌드 도구인 Gradle Wrapper로 EuclideanSimilarityTest클래스의 테스트 메서드인 euclideanSimilarityExamples를 실행해 봅니다.

./gradlew :recommender-examples:test --tests com.r4tings.recommender.examples.ch04.EuclideanSimilarityTest.euclideanSimilarityExamples

테스트 메서드가 실행되면 직접 계산하기에서 다룬 결과를 확인하기 위해 설정한 테스트 인자 목록을 테스트 메서드의 매개변수에 대입해가며 반복 실행되어 결과가 출력됩니다.

다음은 반복 실행 테스트를 위한 테스트 인자 목록입니다

[테스트 인자 목록]

구분 데이터 경로 기준 실제척도 상세출력 좌변(LHS) 우변(RHS) 유사도
사용자 유클리드 유사도 dataset/r4tings/ratings.parquet USER - true $u_4$ $u_5$ 0.3090
10 true $u_4$ $u_5$ 0.1666
아이템 유클리드 유사도 ITEM - true $i_3$ $i_1$ 0.5857
5 true $i_3$ $i_1$ 0.4721

예제 코드의 실행 결과는 다음과 같습니다.

예제 코드 실행 결과더보기

원본 평점을 사용한 ❶ 사용자 유클리드 유사도 계산, ❷ 사용자 확장 유클리드 유사도 계산과 원본 평점을 사용한 ❸ 아이템 유클리드 유사도 계산, ❹ 아이템 확장 유클리드 유사도 계산에 대한 테스트 케이스가 성공적으로 종료(PASSED)되었음을 확인할 수 있습니다. 또한, 실행 결과는 "직접 계산하기"에서 계산해 본 내용을 쉽게 확인하기 위해 처리 과정에서 파생된 상세 출력 정보도 함께 보여주고 있습니다.

4.4.3.4 R 패키지로 확인해보기

다음은 R 패키지를 이용하여 "직접 계산하기"의 계산 결과를 확인하기 위해 작성된 R 스크립트입니다.

EuclideanSimilarity.R

이 R 스크립트는 코사인 유사도 계산을 위한 recommenderlab 패키지의 similarity함수를 실행하고 결과를 확인하기 위한 방법을 설명합니다. 소스 코드에서 볼 수 있듯이 기본 흐름은 매우 단순합니다. 먼저 ❶ data.table 패키지의 fread 함수를 이용하여 CSV 유형의 평점 데이터를 읽어 들이고 (14행) ❷ recommenderlab 패키지에서 사용하는 realRatingMatrix 유형으로 변환하여 읽어 들인 평점 데이터를 출력합니다((27행~29행). 다음으로 ❸ 원본 평점을 사용한 사용자 확장 유클리드 유사도 계산(114행~116행)과 ❹ 원본 평점을 사용한 아이템 확장 유클리드 유사도 계산(127행~129행) 결과를 matrix 유형으로 변환하여 출력합니다.

Tip:

R 패키지 recommenderlab의 dissimilarity함수는 내부적으로 환산계수가 적용된 확장 유클리드 거리 측도만 지원됩니다.

R 스크립트의 실행 결과는 다음과 같습니다.

R 스크립트 실행 결과더보기

이 실행 결과에서 볼 수 있듯이 ❶ 원본 평점을 사용한 사용자 확장 유클리드 유사도 계산과 ❷ 아이템 확장 유클리드 유사도 계산 결과를 확인할 수 있습니다. 또한, 실행 결과가 "직접 계산하기"의 계산 결과와 같음을 확인할 수 있습니다.

한글:5485 영어:7584 숫자:2752

추천 시스템: 워크북

Comments

Do you have a problem, want to share feedback, or discuss further ideas? Feel free to leave a comment here! Please follow Rust's code of conduct. This comment thread directly maps to a discussion on GitHub, so you can also comment there if you prefer.

Instead of authenticating the giscus application, you can also comment directly on GitHub.