협업 필터링(Collaborative Filtering): K-NN부터 행렬 분해까지 핵심 원리 파헤치기
지난번 차원 축소에 이어, 오늘은 방대한 정보 속에서 사용자의 숨겨진 취향을 발견해내는 추천 시스템의 핵심 기술, 협업 필터링(Collaborative Filtering, CF)에 대해 공유하고자 한다. 머신러닝, 특히 추천 시스템 분야는 이미 삶에 깊숙히 들어와 있기에, CF의 근본적인 아이디어부터 주요 접근 방식인 K-최근접 이웃(K-NN)과 행렬 분해(Matrix Factorization)까지, 그 핵심 원리를 심도 있게 파헤쳐 보자.
1. 협업 필터링(CF)이란 무엇인가? 함께 걸러내는 집단 지성의 힘
협업 필터링(Collaborative Filtering), 이름 그대로 '여러 사용자의 협력적인 경험을 통해 필터링한다'는 의미를 담고 있다. 이 기법의 핵심 아이디어는 놀랍게 직관적이다.
"나와 비슷한 취향을 가진 사람들은 내가 아직 모르는 좋은 것을 이미 알고 있을 가능성이 높다."
"내가 좋아했던 A라는 아이템과 비슷한 패턴으로 사람들의 사랑을 받은 B라는 아이템은 나도 좋아할 가능성이 높다."
이것이 바로 CF의 출발점이다. Amazon.com에서 내가 구매했던 책과 비슷한 책을 다른 구매자들이 많이 샀다면, 그 책들을 나에게 추천해주는 것이 대표적인 예시다. CF는 사용자와 아이템 간의 상호작용 데이터(예: 평점, 구매 이력, 클릭 기록 등)를 분석하여 패턴을 학습하고, 이를 통해 특정 사용자가 아직 경험하지 않은 아이템에 대한 선호도를 예측한다.
CF example |
데이터를 본격적으로 활용하기 전에, 종종 데이터의 편향을 줄이고 사용자 간 또는 아이템 간 비교를 용이하게 하기 위해 데이터 정규화(Data Normalization) 과정을 거치는데, 그중 하나로 각 사용자의 평균 평점을 빼서 데이터를 중앙에 맞추는 '데이터 센터링(Centering Data)' 기법 등이 언급되기도 한다. 이는 사용자들이 평점을 매기는 경향성(후하게 주거나 짜게 주는)을 보정하는 데 도움을 줄 수 있다.
2. K-최근접 이웃 (K-Nearest Neighbors, K-NN) 방식: '나와 비슷한 너'를 찾아서 🧑🤝🧑
K-최근접 이웃(K-NN) 방식은 협업 필터링의 가장 초기 형태 중 하나로, 그 직관성 덕분에 여전히 많이 활용된다. 핵심은 '유사한 이웃'을 찾아 그들의 행동을 바탕으로 예측하는 것이다. K-NN은 크게 두 가지 접근 방식으로 나뉜다. (K-NN 소개글 참조)
가. 사용자 기반 K-NN (User-based K-NN)
- 원리: 현재 사용자(A)와 유사한 선호 패턴을 보인 다른 사용자들(이웃들)을 K명 찾는다. 여기서 '유사한 선호 패턴'이란, 과거에 A와 이웃들이 동일하거나 유사한 아이템에 대해 비슷한 평점을 매겼거나, 비슷한 아이템들을 구매/클릭한 경우를 의미한다.
- 예측: 이 K명의 이웃들이 특정 아이템 X에 대해 내린 평가(또는 구매 여부)를 종합하여, 사용자 A가 아이템 X를 얼마나 선호할지 예측한다. 예를 들어, 이웃들의 평점을 단순히 평균 내거나, 유사도가 높을수록 더 큰 가중치를 주어 가중 평균을 계산할 수 있다.
나. 아이템 기반 K-NN (Item-based K-NN)
- 원리: 특정 아이템(X)과 유사한 평가 패턴을 보이는 다른 아이템들(이웃 아이템들)을 K개 찾는다. 여기서 '유사한 평가 패턴'이란, 많은 사용자들이 아이템 X와 이웃 아이템들에 대해 공통적으로 유사한 평가를 내린 경우를 의미한다. 예를 들어, 영화 A를 높게 평가한 사용자들이 영화 B도 높게 평가했다면 A와 B는 유사하다고 볼 수 있다.
- 예측: 현재 사용자가 아이템 X에 대해 긍정적인 반응을 보였다면(예: 높은 평점, 구매), 아이템 X와 유사한 K개의 다른 아이템들을 추천한다. 아마존의 "이 상품을 구매한 고객이 함께 구매한 상품" 추천이 아이템 기반 CF의 대표적인 예시다. 아이템 기반 방식은 사용자 기반 방식에 비해 사용자 수가 아이템 수보다 훨씬 많은 경우(대부분의 현실적인 상황) 계산 효율성이 좋고, 아이템 간의 유사성은 사용자 취향보다 상대적으로 안정적이라는 장점이 있다.
다. 유사도 계산의 핵심 (K-NN: Computing Similarity) 📐
K-NN 방법의 성패는 '유사도(Similarity)'를 얼마나 잘 정의하고 계산하느냐에 달려있다. 사용자-사용자 간, 또는 아이템-아이템 간 유사도를 측정하기 위해 다양한 지표가 사용된다.
-
코사인 유사도 (Cosine Similarity):
두 벡터 간의 코사인 각도를 이용하여 계산한다. 평점 벡터를 공간상의 한 점으로 보고, 두 사용자(또는 아이템)의 평점 벡터가 이루는 각도가 작을수록(코사인 값이 1에 가까울수록) 유사하다고 판단한다. 평점의 절대적인 크기보다는 평가 경향의 방향성에 초점을 맞춘다.
사용자 \(u\)와 \(v\) 간의 코사인 유사도는 다음과 같이 계산된다 (여기서 \(I_{uv}\)는 \(u\)와 \(v\) 모두가 평가한 아이템 집합, \(r_{ui}\)는 사용자 \(u\)의 아이템 \(i\)에 대한 평점이다):
\[sim(u,v)=\frac{\sum_{i\in I_{uv}}^{}r_{ui}\cdot r_{vi}}{\sqrt{\sum_{i\in I_{uv}}^{}r_{ui}^{2}}\cdot\sqrt{\sum_{i\in I_{uv}}^{}r_{vi}^{2}}}\]
-
피어슨 상관 계수 (Pearson Correlation Coefficient):
두 변수 간의 선형 상관 관계를 측정한다. -1에서 1 사이의 값을 가지며, 1에 가까울수록 강한 양의 상관관계, -1에 가까울수록 강한 음의 상관관계를 의미한다. 각 사용자의 평균 평점을 고려하여 평점의 상대적인 높낮이를 비교한다. 즉, 각 사용자의 평점 스타일(평균적으로 점수를 후하게 주는지, 짜게 주는지)을 보정하는 효과가 있다. (이는 앞서 언급된 '데이터 센터링'과 밀접한 관련이 있다.)
사용자 \(u\)와 \(v\) 간의 피어슨 상관 계수는 다음과 같이 계산된다 (\(\bar{r_{u}}\)는 사용자 \(u\)의 평균 평점):
\[sim(u,v)=\frac{\sum_{i\in I_{uv}}^{}(r_{ui}-\bar{r_{u}})(r_{vi}-\bar{r_{v}})}{\sqrt{\sum_{i\in I_{uv}}^{}(r_{ui}-\bar{r_{u}})^{2}}\cdot\sqrt{\sum_{i\in I_{uv}}^{}(r_{vi}-\bar{r_{v}})^{2}}}\]
이 외에도 자카드 유사도(Jaccard Similarity), 평균 제곱 차이(Mean Squared Difference, MSD) 등 다양한 유사도 척도가 활용될 수 있다.
라. K-NN 방식 요약 (K-NN: Summary)
- 장점: 개념이 단순하고 직관적이며, 구현이 비교적 쉽다. 새로운 사용자나 아이템이 추가되어도 기존 모델을 크게 변경할 필요 없이 유사도 계산을 통해 추천이 가능하다 (데이터가 충분하다면). 결과에 대한 해석이 용이하다.
- 단점: 데이터가 희소(Sparse)할 경우(대부분의 사용자가 소수의 아이템에만 평가하는 경우) 유사도 계산의 신뢰도가 떨어진다. 사용자나 아이템 수가 매우 많을 경우 모든 쌍에 대한 유사도 계산 비용이 커진다 (Scalability 문제). 인기 있는 아이템만 추천되는 경향(Popularity Bias)이 나타날 수 있으며, 새로운 사용자나 아이템에 대한 추천이 어려운 콜드 스타트(Cold Start) 문제가 있다.
3. 행렬 분해 (Matrix Factorization): 숨겨진 취향을 벡터로 표현하다 🌌
K-NN 방식이 명시적인 유사도에 기반한다면, 행렬 분해(Matrix Factorization, MF)는 사용자-아이템 상호작용 데이터에 내재된 잠재 요인(Latent Factors)을 찾아내어 추천에 활용하는 모델 기반 접근 방식이다.
가. 기본 아이디어와 희소 행렬 문제
사용자-아이템 상호작용 데이터는 보통 사용자-아이템 평점 행렬 (Rating Matrix, R) 형태로 표현된다. 이 행렬의 행은 사용자, 열은 아이템, 각 원소 \(r_{ui}\)는 사용자 \(u\)가 아이템 \(i\)에 매긴 평점을 나타낸다.
하지만 현실에서는 대부분의 사용자가 전체 아이템 중 극히 일부에 대해서만 평점을 매기므로, 이 행렬 R은 매우 희소(Sparse)하다. 즉, 대부분의 칸이 비어있다(Missing Values).
행렬 분해의 목표는 이 거대하고 희소한 평점 행렬 R (m×n 크기, m: 사용자 수, n: 아이템 수)을 두 개의 저차원 잠재 요인 행렬, 즉 사용자 잠재 요인 행렬 A (m×k)와 아이템 잠재 요인 행렬 B (n×k)의 곱으로 근사하는 것이다.
\[R\approx A\cdot B^{T}\]
여기서 k는 잠재 요인의 차원 수로, 원본 차원보다 훨씬 작다 (k≪m,k≪n). 이것이 바로 '저차원 행렬 분해(Low Dimensional Matrix Factorization)'의 핵심이다.
Low Dimensional Matrix Factorization |
나. SVD와 결측값 문제 (SVD with Missing Values)
행렬 분해의 대표적인 기법 중 하나는 특이값 분해(Singular Value Decomposition, SVD)이다. SVD는 행렬 \(R\)을 \(U\sum V^{T}\) 세 행렬의 곱으로 분해한다. 여기서 \(U\)와 \(V\)는 직교 행렬이고, \(\sum)는 특이값들을 대각 원소로 갖는 대각 행렬이다. CF 맥락에서 \(U\)는 사용자 특성, \(V\)는 아이템 특성, \(\sum)는 각 특성의 중요도를 나타낸다고 해석할 수 있다.
하지만 표준 SVD는 결측값이 없는 완전한 행렬(Dense Matrix)에 대해서만 정의된다. 우리의 평점 행렬 R은 대부분 비어있기 때문에, SVD를 직접 적용하기 어렵다. 이것이 'SVD with Missing Values' 문제이다.
이를 해결하기 위한 접근 방식들은 다음과 같다:
- 단순한 방법 (Naive Approach): 비어있는 값들을 특정 값(예: 전체 평균 평점, 사용자별 평균 평점, 아이템별 평균 평점)으로 채우고 SVD를 적용한다. 하지만 이는 데이터에 편향을 야기하고 부정확한 결과를 초래할 수 있다.
- 최적화 기반 접근 (Optimization-based Approach): SVD의 아이디어를 차용하되, 관측된 평점에 대해서만 예측 오차를 최소화하도록 사용자 잠재 요인 행렬 \(A\)와 아이템 잠재 요인 행렬 \(B\)를 학습한다.
사용자 \(u\)의 잠재 벡터를 \(a_{u}\) (행렬 A의 u번째 행), 아이템 \(i\)의 잠재 벡터를 \(b_{i}\) (행렬 B의 i번째 행)라고 하자. 사용자 \(u\)의 아이템 \(i\)에 대한 예측 평점 \(\hat{r}_{ui}\)는 두 잠재 벡터의 내적으로 계산된다:
\[\hat{r}_{ui}=a_{u}^{T}b_{i}=\sum_{l=1}^{k}a_{ul}b_{il}\]
학습 목표는 실제 평점 \(r_{ui}\)와 예측 평점 \(\hat{r}_{ui}\) 간의 차이(오차)를 최소화하는 \(A\)와 \(B\)를 찾는 것이다. 여기에 과적합을 방지하기 위한 정규화(Regularization) 항을 추가하여 다음과 같은 손실 함수(Loss Function)를 정의한다:
\[L=\sum _{(u,i)\in ObservedRatings}(r_{ui}-a_{u}^{T}b_{i})^{2}+\lambda(\sum _{u}\left\|a_{u}\right\|^{2}+\sum _{i}\left\|b_{i}\right\|^{2})\]
여기서 ObservedRatings는 실제 평점이 있는 (u,i) 쌍들의 집합이고, λ는 정규화 강도를 조절하는 하이퍼파라미터이다. 이 손실 함수 L을 최소화하기 위해 경사 하강법(Gradient Descent)이나 교대 최소 제곱법(Alternating Least Squares, ALS)과 같은 최적화 알고리즘이 사용된다.ALS optimization
다. 잠재 요인의 의미와 예측
행렬 분해를 통해 얻어진 k차원의 잠재 벡터 \(a_{u}\)와 \(b_{i}\)는 사용자의 숨겨진 취향과 아이템의 숨겨진 특성을 함축적으로 나타낸다. 예를 들어 영화 추천 시스템이라면, 잠재 벡터의 각 차원은 '액션 선호도', '코미디 선호도', '특정 배우 선호도' 등 우리가 명시적으로 알지 못했던 추상적인 특징들을 나타낼 수 있다.
- \(a_{u}=(a_{u1},a_{u2},...,a_{uk})\): 사용자 \(u\)가 각 \(k\)개의 잠재 요인을 얼마나 선호하는지.
- \(b_{i}=(b_{i1},b_{i2},...,b_{ik})\): 아이템 \(i\)가 각 \(k\)개의 잠재 요인을 얼마나 포함하고 있는지.
이렇게 학습된 잠재 벡터들의 내적 \(\hat{r}_{ui}=a_{u}^{T}b_{i}\)를 통해 사용자가 아직 평가하지 않은 아이템에 대한 선호도를 예측하고, 가장 높은 예측 평점을 갖는 아이템들을 추천한다.
라. 행렬 분해의 장점
- 희소성 문제 해결: 관측된 데이터만으로도 전체적인 패턴을 학습하여 비어있는 평점을 예측할 수 있다.
- 일반화 성능: 단순히 표면적인 유사도만 보는 것이 아니라, 데이터 이면의 잠재적인 구조를 학습하므로 더 나은 일반화 성능을 기대할 수 있다.
- 모델 크기: 사용자 및 아이템 수에 비해 잠재 요인의 차원 k가 작기 때문에 모델 크기가 상대적으로 작고, 예측 속도도 빠르다.
4. 결론: 데이터 속 숨겨진 취향을 발견하는 협업 필터링의 지혜
협업 필터링은 사용자와 아이템 간의 복잡한 상호작용 속에서 개인의 취향을 발견하고 맞춤형 추천을 제공하는 강력한 방법론이다. K-NN 방식은 유사한 이웃들의 지혜를 빌려 직관적인 추천을 제공하며, 행렬 분해 방식은 데이터 이면의 잠재적인 구조를 학습하여 보다 정교한 예측을 가능하게 한다.
이 두 핵심 접근 방식은 오늘날 수많은 추천 시스템의 근간을 이루고 있으며, 딥러닝과 결합된 하이브리드 모델 등 더욱 발전된 형태로 진화하고 있다. 머신러닝 분야를 깊이 탐구하는 우리에게 협업 필터링의 원리를 이해하는 것은, 단순히 추천 기술을 넘어 데이터의 패턴을 읽고 예측 모델을 구축하는 데 필요한 핵심적인 역량을 길러줄 것이다.
추천글:
[기계학습개론] Dimensionality Reduction - PCA, Kernel PCA, Auto-Encoder