4.2 코사인 유사도

코사인 유사도(Cosine Similarity)는 내적공간(Inner Product Space)에서의 두 벡터 사잇각의 코사인값을 사용하여 벡터의 크기는 고려하지 않고 두 벡터가 가리키는 방향으로 유사도를 측정하는 방법입니다. 즉, 벡터의 내적을 각 벡터 노름의 곱으로 나눈 코사인값이 유사도가 됩니다. 이렇게 계산된 유사도는 두 벡터가 이루는 각도가 ${0^ \circ }$이면 두 벡터의 방향이 완전히 동일한 경우로 1의 값(완전 일치)을 가지며, ${90^ \circ }$이면 0(독립), ${180^ \circ }$로 반대의 방향이면 -1(완전 불일치)의 값을 갖게 됩니다.

이처럼 코사인 유사도는 -1 이상 1 이하의 값을 가지지만 일반적으로 0보다 작고 -1보다 큰 값은 유사도로 사용하지 않습니다. 평점 데이터의 코사인 유사도 계산은 두 사용자 모두에게 평가된 아이템 집합의 평점 간의 유사도를 계산하는 사용자-사용자 유사도(이하 사용자 유사도)와 두 아이템 모두 평가한 사용자 집합의 평점 간의 유사도를 계산하는 아이템-아이템 유사도(이하 아이템 유사도) 계산의 두 가지 방법을 살펴봅니다.

4.2.1 수식 살펴보기

여기에서는 사용자-사용자 간 코사인 유사도 계산과 아이템-아이템 코사인 유사도 계산에 대한 수식을 살펴봅니다.

4.2.1.1 사용자 코사인 유사도

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

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

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

4.2.1.3 아이템 코사인 유사도

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

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

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

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

4.2.1 사용자 코사인 유사도

사용자 코사인 유사도는 평점 데이터뿐만 아니라 다음 정규화된 평점 데이터도 사용하여 계산해 볼 것입니다.

  • 평균 중심화된 평점
  • Z점수화된 평점

또한, 평균 중심화된 평점의 유사도 계산 시에 어느 한쪽만 평점이 매겨진 경우 다른 한쪽의 결측값을 0으로 대체(Zero Imputation)하여 계산해 볼 것입니다.

  • 평균 중심화 평점(결측값 0 대체)

4.2.1.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}입니다. 두 사용자의 내적은 $23.75$이고 사용자 $u_4$의 노름은 $6.10328$, 사용자 $u_5$의 노름은 $3.90512$입니다. 사용자 코사인 유사도는 평점 벡터의 내적을 각 평점 벡터의 노름을 곱한 값으로 나눈 $0.996$이 됩니다.

$$ \begin{flalign} \mathrm{sim} _{cosine} {(u_4,u_5)} & = \frac {23.75} { 6.10328 \times 3.90512 } \\ & \approx 0.996 \end{flalign} $$

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

계산 결과

내적 사용자 $u_4$의 노름 사용자 $u_5$의 노름 유사도
23.75 6.10328 3.90512 0.996

같은 방법으로 사용자 코사인 유사도를 모두 계산해 봅니다. 다음 표는 사용자 코사인 유사도 데이터를 사용자(LHS)는 행, 사용자 (RHS)는 열로 나타낸 것입니다.

사용자 코사인 유사도 데이터

사용자(RHS) 사용자(LHS) $u_1$ $u_2$ $u_3$ $u_4$ $u_5$
$u_1$ 1 0.7244371 0.9780612 0.9478988 0.8571429
$u_2$ 0.7244371 1 0.8637076 0.8288487 0.990024
$u_3$ 0.9780612 0.8637076 1 0.8245676 0.8055945
$u_4$ 0.9478988 0.8288487 0.8245676 1 0.996473
$u_5$ 0.8571429 0.990024 0.8055945 0.996473 1

4.2.1.2 사용자 평균 중심화 평점

다음 표는 사용자 평균 중심으로 정규화된 평점 데이터를 사용자는 행, 아이템은 열로 나타낸 것입니다.

평점 데이터

사용자/아이템 $i_1$ $i_2$ $i_3$ $i_4$ $i_5$ $i_6$ $i_7$ $i_8$ $i_9$ $i_{10}$
$u_1$ -2.4285714 2.0714286 -1.9285714 0.0714286 0.5714286 2.0714286 -0.4285714
$u_2$ 0.2142857 -0.7857143 0.7142857 -0.7857143 1.2142857 1.2142857 -1.7857143
$u_3$ 0.75 -1.75 0.75 1.25 -1.75 0.75
$u_4$ -0.3333333 1.6666667 -2.8333333 0.1666667 0.1666667 1.1666667
$u_5$ -0.375 0.625 -0.875 0.625

예를 들어 사용자 $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$ -0.3333333 1.6666667 -2.8333333 0.1666667 0.1666667 1.1666667
$u_5$ -0.375 0.625 -0.875 0.625

여기에서 사용자 $u_4$와 사용자 $u_5$가 공통으로 평가한 아이템 {$i_2$, $i_6$}에 대한 각 사용자의 평점은 {1.6666667, 0.1666667}과 {-0.375, -0.875}입니다. 두 사용자의 내적은 $-0.7708333$이고 사용자 $u_4$의 노름은 $1.6749793$, 사용자 $0.951972$입니다. 두 사용자의 유사도는 내적을 사용자 $u_4$와 사용자 $u_5$의 노름을 곱한 값으로 나눈 $-0.483$이 됩니다.

$$ \begin{flalign} \mathrm{sim} _{cosine} {(u_4,u_5)} & = \frac {-0.7708333} { 1.6749793 \times 0.951972 } \\ & \approx - 0.483 \end{flalign} $$

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

계산 결과

내적 사용자 $u_4$의 노름 사용자 $u_5$의 노름 유사도
-0.7708333 1.6749793 0.951972 -0.483

같은 방법으로 사용자 코사인 유사도를 모두 계산해 봅니다. 다음 표는 사용자 코사인 유사도 데이터를 사용자(LHS)는 행, 사용자 (RHS)는 열로 나타낸 것입니다.

사용자 코사인 유사도 데이터

사용자(RHS) 사용자(LHS) $u_1$ $u_2$ $u_3$ $u_4$ $u_5$
$u_1$ 1 -0.2252454 0.6730268 0.8499498 -0.4497706
$u_2$ -0.2252454 1 -0.2116711 0.2260608 0.9684968
$u_3$ 0.6730268 -0.2116711 1 -0.038323 0.0530566
$u_4$ 0.8499498 0.2260608 -0.038323 1 -0.4834227
$u_5$ -0.4497706 0.9684968 0.0530566 -0.4834227 1

4.2.1.3 사용자 평균 중심화 평점(결측값 0 대체)

다음 표는 사용자 평균 중심으로 정규화된 평점 데이터를 사용자는 행, 아이템은 열로 나타낸 것입니다.

평점 데이터

사용자/아이템 $i_1$ $i_2$ $i_3$ $i_4$ $i_5$ $i_6$ $i_7$ $i_8$ $i_9$ $i_{10}$
$u_1$ -2.4285714 2.0714286 -1.9285714 0.0714286 0.5714286 2.0714286 -0.4285714
$u_2$ 0.2142857 -0.7857143 0.7142857 -0.7857143 1.2142857 1.2142857 -1.7857143
$u_3$ 0.75 -1.75 0.75 1.25 -1.75 0.75
$u_4$ -0.3333333 1.6666667 -2.8333333 0.1666667 0.1666667 1.1666667
$u_5$ -0.375 0.625 -0.875 0.625

예를 들어 사용자 $u_4$와 사용자 $u_5$의 유사도를 코사인 유사도를 사용하여 계산해 봅니다. 여기에서는 유사도 계산 시에 두 사용자 중 어느 한쪽만 평점이 매겨진 경우, 다른 한쪽의 결측값을 0으로 대체(Zero Imputation)합니다. 다음 표는 사용자 $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$ -0.3333333 1.6666667 0 -2.8333333 0.1666667 0 0.1666667 1.1666667
$u_5$ 0 -0.375 0.625 0 -0.875 0.625 0 0

여기에서 사용자 $u_4$와 사용자 $u_5$가 공통으로 평가한 아이템 {$i_1$, $i_2$, $i_4$, $i_6$, $i_8$, $i_9$}에 대한 각 사용자의 평점은 {-0.3333333, 1.6666667, 0, -2.8333333, 0.1666667, 0, 0.1666667, 1.1666667}와 {0, -0.375, 0.625, 0, -0.875, 0.625, 0, 0}입니다. 두 사용자의 내적은 $-0.7708333$이고 사용자 $u_4$의 노름은 $3.5118846$, 사용자 $u_5$의 노름은 $1.29904$입니다. 사용자 코사인 유사도는 평점 벡터의 내적을 각 평점 벡터의 노름을 곱한 값으로 나눈 $-0.168$이 됩니다.

$$ \begin{flalign} \mathrm{sim} _{cosine} {(u_4,u_5)} & = \frac {-0.7708333} { 3.5118846 \times 1.29904 } \\ & \approx - 0.168 \end{flalign} $$

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

계산 결과

내적 사용자 $u_4$의 노름 사용자 $u_5$의 노름 유사도
-0.770833375 3.5118846 1.29904 -0.168

같은 방법으로 사용자 코사인 유사도를 모두 계산해 봅니다. 다음 표는 사용자 코사인 유사도 데이터를 사용자(LHS)는 행, 사용자 (RHS)는 열로 나타낸 것입니다.

사용자 코사인 유사도 데이터

사용자(RHS) 사용자(LHS) $u_1$ $u_2$ $u_3$ $u_4$ $u_5$
$u_1$ 1 -0.1696348 0.479943 0.4403826 -0.3002861
$u_2$ -0.1696348 1 -0.1056329 0.0854754 0.4100831
$u_3$ 0.479943 -0.1056329 1 -0.0271244 0.0392837
$u_4$ 0.4403826 0.0854754 -0.0271244 1 -0.1689656
$u_5$ -0.3002861 0.4100831 0.0392837 -0.1689656 1

다음 표는 사용자 $u_5$의 평균 중심화 평점과 평균 중심화 평점(유사도 결측값 0 대체)의 사용자 코사인 유사도를 유사도가 높은 순으로 비교하여 나타낸 것입니다.

사용자 $u_5$의 사용자 코사인 유사도 비교

순위 평균 중심화 평점 평균 중심화(유사도 결측값 0 대체)
사용자 유사도 사용자 유사도
1 $u_5$ 1 $u_5$ 1
2 $u_2$ 0.9684968 $u_2$ 0.4100831
3 $u_3$ 0.0530566 $u_3$ 0.0392837
4 $u_1$ -0.4497706 $u_4$ -0.1689656
5 $u_4$ -0.4834227 $u_1$ -0.3002861

평균 중심화 평점과 평균 중심화 평점(유사도 결측값 0 대체)의 유사도 순위가 4번째, 5번째에서 서로 다른 결과가 나오는 것을 확인할 수 있습니다.

4.2.1.4 사용자 Z점수화 평점

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

평점 데이터

사용자/아이템 $i_1$ $i_2$ $i_3$ $i_4$ $i_5$ $i_6$ $i_7$ $i_8$ $i_9$ $i_{10}$
$u_1$ -1.3751177 1.1728945 -1.0920052 0.0404446 0.3235571 1.1728945 -0.2426678
$u_2$ 0.1864109 -0.6835067 0.6213698 -0.6835067 1.0563286 1.0563286 -1.5534244
$u_3$ 0.5477226 -1.2780193 0.5477226 0.9128709 -1.2780193 0.5477226
$u_4$ -0.2122382 1.0611909 -1.8040245 0.1061191 0.1061191 0.7428336
$u_5$ -0.5 0.8333333 -1.1666667 0.8333333

예를 들어 사용자 $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$ -0.2122382 1.0611909 -1.8040245 0.1061191 0.1061191 0.7428336
$u_5$ -0.5 0.8333333 -1.1666667 0.8333333

여기에서 사용자 $u_4$와 사용자 $u_5$가 공통으로 평가한 아이템 {$i_2$, $i_6$}에 대한 각 사용자의 평점은 {1.0611909, 0.1061191}과 {-0.5, -1.1666667}입니다. 두 사용자의 내적은 $-0.654401$이고 사용자 $u_4$의 노름은 $1.0664837$, 사용자 $u_5$의 노름은 $1.269296$입니다. 두 사용자의 유사도는 내적을 사용자 $u_4$와 사용자 $u_5$의 노름을 곱한 값으로 나눈 $-0.483$이 됩니다.

$$ \begin{flalign} \mathrm{sim} _{cosine} {(u_4,u_5)} & = \frac {-0.654401} { 1.0664837 \times 1.269296} \\ & \approx -0.483 \end{flalign} $$

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

계산 결과

내적 사용자 $u_4$의 노름 사용자 $u_5$의 노름 유사도
-0.654401 1.0664837 1.269296 -0.483

같은 방법으로 사용자 코사인 유사도를 모두 계산해 봅니다. 다음 표는 사용자 코사인 유사도 데이터를 사용자(LHS)는 행, 사용자 (RHS)는 열로 나타낸 것입니다.

사용자 코사인 유사도 데이터

사용자(RHS) 사용자(LHS) $u_1$ $u_2$ $u_3$ $u_4$ $u_5$
$u_1$ 1 -0.2252454 0.6730268 0.8499498 -0.4497706
$u_2$ -0.2252454 1 -0.2116711 0.2260608 0.9684968
$u_3$ 0.6730268 -0.2116711 1 -0.038323 0.0530566
$u_4$ 0.8499498 0.2260608 -0.038323 1 -0.4834227
$u_5$ -0.4497706 0.9684968 0.0530566 -0.4834227 1

4.2.2 아이템 코사인 유사도

아이템 코사인 유사도는 평점 데이터뿐만 아니라 다음 정규화된 평점 데이터도 사용하여 계산해 볼 것입니다.

  • 평균 중심화된 평점
  • Z점수화된 평점

또한, 평균 중심화된 평점의 유사도 계산 시에 어느 한쪽만 평점이 매겨진 경우, 다른 한쪽의 결측값을 0으로 대체(Zero Imputation)하여 계산해 볼 것입니다.

  • 평균 중심화 평점(결측값 0 대체)

4.2.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

예를 들어 사용자 아이템 $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_1$, $u_2$)에 대한 각 아이템의 평점은 {1, 3.5}와 {0.5, 3}입니다. 두 아이템의 내적은 $11$이고 아이템 $i_3$의 노름은 $3.64005$, 아이템 $i_1$의 노름은 $3.0413813$입니다. 두 아이템의 유사도는 내적을 아이템 $i_3$과 아이템 $i_1$의 노름을 곱한 값으로 나눈 $0.993$이 됩니다.

$$ \begin{flalign} \mathrm{sim} _{cosine} {(i_3,i_1)} & = \frac {11} { 3.64005 \times 3.0413813} \\ & \approx 0.993 \end{flalign} $$

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

계산 결과

내적 아이템 $i_3$의 노름 아이템 $i_1$의 노름 유사도
11 3.64005 3.0413813 0.993

같은 방법으로 아이템 코사인 유사도를 모두 계산해 봅니다. 다음 표는 아이템 코사인 유사도 데이터를 아이템 (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.7485823 0.9936053 0.8574929 0 0.8559155 0.8505946 0 0.7820596 0.5189781
$i_2$ 0.7485823 1 0.7053456 0.7186995 0.9647638 0.9653269 0.9144982 0 0.9986983 1
$i_3$ 0.9936053 0.7053456 1 0.7155742 0.8741573 0.8185875 0.931162 NaN 0.9847836 0.6121732
$i_4$ 0.8574929 0.7186995 0.7155742 1 0.9647638 0.4079401 0 0 0.7194015 0
$i_5$ 0 0.9647638 0.8741573 0.9647638 1 0 0 NaN 0 0
$i_6$ 0.8559155 0.9653269 0.8185875 0.4079401 0 1 0.9876651 0 0.9575504 0
$i_7$ 0.8505946 0.9144982 0.931162 0 0 0.9876651 1 NaN 0 0.8909061
$i_8$ 0 0 NaN 0 NaN 0 NaN 1 0 NaN
$i_9$ 0.7820596 0.9986983 0.9847836 0.7194015 0 0.9575504 0 0 1 0
$i_{10}$ 0.5189781 1 0.6121732 0 0 0 0.8909061 NaN 0 1

NaN에 대한 설명 추가 필요

4.2.2.2 아이템 평균 중심화 평점

다음 표는 아이템 평균 중심으로 정규화된 평점 데이터를 사용자는 행, 아이템은 열로 나타낸 것입니다.

평점 데이터

사용자/아이템 $i_1$ $i_2$ $i_3$ $i_4$ $i_5$ $i_6$ $i_7$ $i_8$ $i_9$ $i_{10}$
$u_1$ -1.6666667 1.3 -1.375 0.5 -0.3333333 0.6666667 0.75
$u_2$ 0.8333333 -1.7 1.125 0 0 0.1666667 -0.75
$u_3$ -0.2 -1.375 1.5 0 -1.5 -0.8333333
$u_4$ 0.8333333 1.3 -1.5 1 0 0.1666667
$u_5$ -0.7 1.625 0 0.1666667

예를 들어 아이템 $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.375 1.125 -1.375 1.625
$i_1$ -1.6666667 0.8333333 0.8333333

여기에서 아이템 $i_3$과 아이템 $i_1$을 공통으로 평가한 사용자 ($u_1$, $u_2$)에 대한 각 아이템의 평점은 {-1.375, 1.125}와 {-1.6666667, 0.8333333}입니다. 두 아이템의 내적은 ${3.2291666}$이고 아이템 $i_3$의 노름은 ${1.77658}$, 아이템 $i_1$의 노름은 ${1.86339}$입니다. 두 아이템의 유사도는 내적을 아이템 $i_3$과 아이템 $i_1$의 노름을 곱한 값으로 나눈 ${0.975}$이 됩니다.

$$ \begin{flalign} \mathrm{sim} _{cosine} {(i_3,i_1)} & = \frac {3.2291666} { 1.777658 \times 1.86339 } \\ & \approx 0.975 \end{flalign} $$

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

계산 결과

내적 아이템 $i_3$의 노름 아이템 $i_1$의 노름 유사도
3.2291666 1.777658 1.86339 0.975

같은 방법으로 아이템 코사인 유사도를 모두 계산해 봅니다. 다음 표는 아이템 코사인 유사도 데이터를 아이템(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.489116 0.975441 -0.7071068 0 0 1 0 -0.7592566 -0.9486833
$i_2$ -0.489116 1 -0.7279472 -0.4934638 NaN 0.6082192 -0.9065472 0 0.6257827 0.9912279
$i_3$ 0.975441 -0.7279472 1 -0.7739573 NaN 0.343164 0.9325886 NaN 0.1104315 -0.9950372
$i_4$ -0.7071068 -0.4934638 -0.7739573 1 NaN -0.9805807 0 0 -0.8320503 0
$i_5$ 0 NaN NaN NaN 1 0 0 NaN 0 0
$i_6$ 0 0.6082192 0.343164 -0.9805807 0 1 -0.8944272 0 0.8660254 0
$i_7$ 1 -0.9065472 0.9325886 0 0 -0.8944272 1 NaN 0 -0.9486833
$i_8$ 0 0 NaN 0 NaN 0 NaN 1 0 NaN
$i_9$ -0.7592566 0.6257827 0.1104315 -0.8320503 0 0.8660254 0 0 1 0
$i_{10}$ -0.9486833 0.9912279 -0.9950372 0 0 0 -0.9486833 NaN 0 1

NaN에 대한 설명 추가 필요

4.2.2.3 아이템 평균 중심화 평점(결측값 0 대체)

다음 표는 아이템 평균 중심으로 정규화된 평점 데이터를 사용자는 행, 아이템은 열로 나타낸 것입니다.

평점 데이터

사용자/아이템 $i_1$ $i_2$ $i_3$ $i_4$ $i_5$ $i_6$ $i_7$ $i_8$ $i_9$ $i_{10}$
$u_1$ -1.6666667 1.3 -1.375 0.5 -0.3333333 0.6666667 0.75
$u_2$ 0.8333333 -1.7 1.125 0 0 0.1666667 -0.75
$u_3$ -0.2 -1.375 1.5 0 -1.5 -0.8333333
$u_4$ 0.8333333 1.3 -1.5 1 0 0.1666667
$u_5$ -0.7 1.625 0 0.1666667

예를 들어 아이템 $i_3$과 아이템 $i_1$의 유사도를 코사인 유사도를 사용하여 계산해 봅니다. 여기에서는 유사도 계산 시에 두 아이템 중 어느 한쪽만 평점이 매겨진 경우, 다른 한쪽의 결측값을 0으로 대체(Zero Imputation)합니다. 다음 표는 아이템 $i_3$과 아이템 $i_1$의 사용자 평균 중심화 평점 데이터를 사용자는 행, 아이템은 열로 나타낸 것입니다.

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

사용자 아이템 $u_1$ $u_2$ $u_3$ $u_4$ $u_5$
$i_3$ -1.375 1.125 -1.375 0 1.625
$i_1$ -1.6666667 0.8333333 0 0.8333333 0

여기에서 아이템 $i_3$과 아이템 $i_1$을 공통으로 평가한 사용자 {$u_1$, $u_2$, $u_3$, $u_4$, $u_5$}에 대한 각 아이템의 평점은 {-1.375, 1.125, -1.375, 0, 1.625}와 {-1.6666667, 0.8333333, 0, 0.8333333, 0}입니다. 두 아이템의 내적은 $3.2291666$이고 아이템 $i_3$의 노름은$2.77263$, 아이템 $i_1$의 노름은 $2.041241$입니다. 두 아이템의 유사도는 내적을 아이템 $i_3$과 아이템 $i_1$의 노름을 곱한 값으로 나눈 $0.5705$가 됩니다.

$$ \begin{flalign} \mathrm{sim} _{cosine} {(i_3,i_1)} & = \frac {3.2291666} {{ 2.77263 \times 2.041241}} \\ & \approx 0.5705 \end{flalign} $$

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

계산 결과

내적 아이템 $i_3$의 노름 아이템 $i_1$의 노름 유사도
3.2291666 2.77263 2.041241 0.5705

같은 방법으로 아이템 코사인 유사도를 모두 계산해 봅니다. 다음 표는 아이템 코사인 유사도 데이터를 아이템(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.4696682 0.5705629 -0.2886751 NaN 0 0.8333333 NaN -0.4409586 -0.8660254
$i_2$ -0.4696682 1 -0.6310385 -0.4067446 NaN 0.461205 -0.7827804 NaN 0.4437948 0.8134892
$i_3$ 0.5705629 -0.6310385 1 -0.3506672 NaN 0.2650795 0.8098312 NaN 0.0765219 -0.6375767
$i_4$ -0.2886751 -0.4067446 -0.3506672 1 NaN -0.9449112 0 NaN -0.6546537 0
$i_5$ NaN NaN NaN NaN 1 NaN NaN NaN NaN NaN
$i_6$ 0 0.461205 0.2650795 -0.9449112 NaN 1 -0.2182179 NaN 0.8660254 0.1889822
$i_7$ 0.8333333 -0.7827804 0.8098312 0 NaN -0.2182179 1 NaN -0.5039526 -0.8660254
$i_8$ NaN NaN NaN NaN NaN NaN NaN 1 NaN NaN
$i_9$ -0.4409586 0.4437948 0.0765219 -0.6546537 NaN 0.8660254 -0.5039526 NaN 1 0.4364358
$i_{10}$ -0.8660254 0.8134892 -0.6375767 0 NaN 0.1889822 -0.8660254 NaN 0.4364358 1

NaN에 대한 설명 추가 필요

다음 표는 아이템 $i_3$의 평균 중심화 평점과 평균 중심화 평점(유사도 결측값 0 대체)의 사용자 코사인 유사도를 유사도가 높은 순으로 비교하여 나타낸 것입니다.

아이템 $i_3$의 아이템 코사인 유사도 비교

순위 평균 중심화 평점 평균 중심화(유사도 결측값 0 대체)
아이템 유사도 아이템 유사도
1 3 1 3 1
2 1 0.975441 7 0.8098312
3 7 0.9325886 1 0.5705629
4 6 0.343164 6 0.2650795
5 9 0.1104315 9 0.0765219
6 2 -0.7279472 4 -0.3506672
7 4 -0.7739573 2 -0.6310385
8 10 -0.9950372 10 -0.6375767
9 5 NaN 5 NaN
10 8 NaN 8 NaN

평균 중심화 평점과 평균 중심화 평점(유사도 결측값 0 대체)의 유사도 순위가 2번째, 3번째, 6번째, 7번째에서 서로 다른 결과가 나오는 것을 확인할 수 있습니다.

4.2.2.4 아이템 Z점수화 평점

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

평점 데이터

사용자/아이템 $i_1$ $i_2$ $i_3$ $i_4$ $i_5$ $i_6$ $i_7$ $i_8$ $i_9$ $i_{10}$
$u_1$ -1.1547005 0.9970545 -0.8589557 0.46291 -1.1547005 0.8728716 0.7071068
$u_2$ 0.5773503 -1.3038405 0.7027819 0 NaN 0.5773503 -0.7071068
$u_3$ -0.153393 -0.8589557 1 NaN -1.3887301 -1.0910895
$u_4$ 0.5773503 0.9970545 -1 0.9258201 NaN 0.2182179
$u_5$ -0.5368755 1.0151295 0 0.5773503

NaN에 대한 설명 추가 필요 -> 정규화

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

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

사용자 아이템 $u_1$ $u_2$ $u_3$ $u_4$ $u_5$
$i_3$ -0.8589557 0.7027819 -0.8589557 1.0151295
$i_1$ -1.1547005 0.5773503 0.5773503

여기에서 아이템 $i_3$과 아이템 $i_1$을 공통으로 평가한 사용자 {$u_3$, $u_1$}에 대한 각 아이템의 평점은 {-0.8589557, 0.7027819}와 {-1.1547005, 0.5773503}입니다. 두 아이템의 내적은 $1.3975879$이고 아이템 $i_3$의 노름은 $1.109823$, 아이템 $i_1$의 노름은 $1.2909944$입니다. 두 아이템의 유사도는 내적을 아이템 $i_3$과 아이템 $i_1$의 노름을 곱한 값으로 나눈 $0.9754$이 됩니다.

$$ \begin{flalign} \mathrm{sim} _{cosine} {(i_3,i_1)} & = \frac {1.3975879} {1.109823 \times 1.2909944 } \\ & \approx 0.9754 \end{flalign} $$

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

계산 결과

내적 아이템 $i_3$의 노름 아이템 $i_1$의 노름 유사도
1.3975879 1.109823 1.2909944 0.9754

같은 방법으로 아이템 코사인 유사도를 모두 계산해 봅니다. 다음 표는 아이템 코사인 유사도 데이터를 아이템(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.489116 0.975441 -0.7071068 NaN 0 1 NaN -0.7592566 -0.9486833
$i_2$ -0.489116 1 -0.7279472 -0.4934638 NaN 0.6082192 -0.9065472 NaN 0.6257827 0.9912279
$i_3$ 0.975441 -0.7279472 1 -0.7739573 NaN 0.343164 0.9325886 NaN 0.1104315 -0.9950372
$i_4$ -0.7071068 -0.4934638 -0.7739573 1 NaN -0.9805807 0 NaN -0.8320503 0
$i_5$ NaN NaN NaN NaN 1 NaN NaN NaN NaN NaN
$i_6$ 0 0.6082192 0.343164 -0.9805807 NaN 1 -0.8944272 NaN 0.8660254 0
$i_7$ 1 -0.9065472 0.9325886 0 NaN -0.8944272 1 NaN 0 -0.9486833
$i_8$ NaN NaN NaN NaN NaN NaN NaN 1 NaN NaN
$i_9$ -0.7592566 0.6257827 0.1104315 -0.8320503 NaN 0.8660254 0 NaN 1 0
$i_{10}$ -0.9486833 0.9912279 -0.9950372 0 NaN 0 -0.9486833 NaN 0 1

4.2.3 예제 코드 실행해보기

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

"직접 계산하기"의 결과

구분 평점 정규화 결측값 처리 좌변 우변 유사도 설명
사용자 유사도 없음 쌍대 열 제외 $u_4$ $u_5$ 0.9964 두 사용자 모두에게 평가된 아이템 집합의 평점간 유사도
사용자 평균 중심화 쌍대 열 제외 -0.4834
사용자 평균 중심화 0 대체 -0.1689
사용자 기준 Z점수 쌍대 열 제외 -0.4834
아이템 유사도 없음 쌍대 열 제외 $i_3$ $i_1$ 0.9936 두 아이템을 모두 평가한 사용자 집합의 평점간 유사도
아이템 평균 중심화 쌍대 열 제외 0.9754
아이템 평균 중심화 0 대체 0.5705
아이템 Z점수화 쌍대 열 제외 0.9754

4.2.3.1 구현 클래스 살펴보기

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

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

Download

[UML 클래스 다이어그램]

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

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

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

주요 매개변수

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

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

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

4.2.3.2 예제 코드 살펴보기

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

CosineSimilarityTest.java

소스 코드에서 볼 수 있듯이 대부분 코드는 테스트를 처리하기 위한 것이지만 기본 흐름은 매우 단순합니다. 먼저 ❶ 매개변수를 바꿔가면서 실행하고 결과를 확인하기 위한 CSV 형식의 인자 목록을 설정합니다( 23~32행). 반복 실행되는 cosineSimilarityExamples 메서드에서는 테스트 인자들을 매개변수로 받습니다. 다음으로 ❷ Parquet 유형의 평점 데이터를 읽어 들이고(41행) ❸ 평점 정규화가 필요한 경우에 평점을 정규화합니다(43행~45행). 다음으로 ❹ CosineSimilarityMeasurer 클래스의 인스턴스를 생성하고(47행~51행) ❺ 평점 데이터를 전달하여 유사도를 계산합니다 (45행). 마지막으로 ❻ "직접 계산하기"에서 계산해 본 결과에 해당하는 기댓값(Expected)과 예제 코드의 실행 결과인 실제 값(Actual)의 소수 자릿수 7자리까지 비교합니다(67행).

4.2.3.3 실행 결과 확인하기

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

./gradlew :recommender-examples:test --tests com.r4tings.recommender.examples.ch04.CosineSimilarityTest.cosineSimilarityExamples

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

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

테스트 인자 목록

구분 데이터 경로 평점 정규화 기준 결측값 0 대체 상세출력 좌변(LHS) 우변(RHS) 유사도
기준 정규화 방법 상세출력

사용자

코사인

유사도

원본 평점 dataset/r4tings/ratings.parquet USER false true $u_4$ $u_5$ 0.996473
사용자 평균 중심화 평점 USER MEAN_CENTERING false USER false true $u_4$ $u_5$ -0.4834227
사용자 평균 중심화 평점(결측값 0 대체) USER MEAN_CENTERING false USER true true $u_4$ $u_5$ -0.1689656
사용자 Z점수화 평점 USER Z_SCORE false USER false true $u_4$ $u_5$ -0.4834227

아이템

코사인

유사도

원본 평점 dataset/r4tings/ratings.parquet ITEM false true $i_3$ $i_1$ 0.9936053
아이템 평균 중심화 평점 ITEM MEAN_CENTERING false ITEM false true $u_4$ $u_5$ 0.975441 '
아이템 평균 중심화 평점(결측값 0 대체) ITEM MEAN_CENTERING false ITEM true true $u_4$ $u_5$ 0.5705628'
아이템 Z점수화 평점 ITEM Z_SCORE false ITEM false true $u_4$ $u_5$ 0.975441 '

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

예제 코드 실행 결과더보기

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

4.2.3.4 R 패키지로 확인해보기

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

CosineSimilarity.R

이 R 스크립트는 코사인 유사도 계산을 위한 recommenderlab 패키지의 similarity함수를 실행하고 결과를 확인하기 위한 방법을 설명합니다. 소스 코드에서 볼 수 있듯이 기본 흐름은 매우 단순합니다. 먼저 ❶ data.table 패키지의 fread 함수를 이용하여 CSV 유형의 평점 데이터를 읽어 들이고 (14행) ❷ recommenderlab 패키지에서 사용하는 realRatingMatrix 유형으로 변환하여 읽어 들인 평점 데이터를 출력합니다((27행~29행). 다음으로 ❸ 원본 평점(39행~45행), ❹ 사용자 평균 중심화 평점(48행~57행), ❺사용자 평균 중심화 평점(결측값 0 대체) (60행~68행), ❻ 사용자 Z점수화 평점(71행~80행)을 사용한 사용자 코사인 유사도 계산과 ❼ 원본 평점( 86행~92행), ❽ 아이템 평균 중심화 평점(95행~104행), ❾ 아이템 평균 중심화 평점(결측값 0 대체) (107행~115행), ❿ 아이템 Z점수화 평점(118행~127행)을 사용한 아이템 코사인 유사도 계산 결과를 matrix 유형으로 변환하여 출력합니다.

Tip:

R 패키지 recommenderlab의 similarity함수는 코사인 유사도, 피어슨 유사도, 자카드 유사도만 지원됩니다.

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

이 실행 결과에서 볼 수 있듯이 ❶ 원본 평점, ❷ 사용자 평균 중심화 평점, ❸ 사용자 평균 중심화 평점(결측값 0 대체), ❹ 사용자 Z점수화 평점을 사용한 사용자 코사인 유사도 계산과 ❺ 원본 평점, ❻ 아이템 평균 중심화 평점, ❼ 아이템 평균 중심화 평점(결측값 0 대체), ❽ 아이템 Z점수화 평점을 사용한 아이템 코사인 유사도 계산 결과를 확인할 수 있습니다. 또한, 실행 결과가 "직접 계산하기"의 계산 결과와 같음을 확인할 수 있습니다.

한글:6541 영어:8034 숫자:7535

추천 시스템: 워크북

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.