협업 필터링, 비슷한 취향의 사용자로 추천을 만드는 법
협업 필터링이 사용자·아이템 유사도로 추천을 만드는 원리와 구현 절차, 냉시동·희소성 문제 해결법, 아마존·넷플릭스·스포티파이의 실제 구현 사례를 정리한다.
2026-08-13 · 최초 발행 2025-05-23
취향이 비슷한 사람들이 좋아하는 것을 추천한다는 발상
협업 필터링은 사용자 간의 유사성 또는 아이템 간의 유사성을 기반으로 추천을 제공하는 기술이다. "비슷한 취향을 가진 사용자들은 비슷한 항목을 선호할 것"이라는 가정에서 출발해, 사용자 행동 데이터(평점, 클릭, 구매 이력 등)를 분석하고 패턴을 발견해 예측에 활용한다. 넷플릭스, 아마존, 유튜브 등 많은 기업이 사용자에게 개인화된 경험을 제공하는 데 이 방식을 쓴다.
메모리 속 이웃을 찾을 것인가, 모델로 학습할 것인가
메모리 기반 협업 필터링은 전체 사용자-아이템 상호작용 데이터를 메모리에 유지하고 직접 계산하는 방식이다. 사용자 기반(User-based) 협업 필터링은 타겟 사용자와 유사한 취향을 가진 다른 사용자들을 찾아 추천한다 — A와 B가 비슷한 영화를 좋아한다면 A가 좋아하는 새 영화를 B에게 추천하는 식이다. 아이템 기반(Item-based) 협업 필터링은 아이템 간 유사성을 계산해 사용자가 좋아했던 아이템과 유사한 아이템을 추천한다 — 사용자가 '매트릭스'를 좋아했다면 유사한 SF 영화 '인셉션'을 추천하는 식이다.
모델 기반 협업 필터링은 기계학습 알고리즘으로 사용자 행동을 모델링한다. 행렬 분해(Matrix Factorization) 방식은 SVD(Singular Value Decomposition)·NMF(Non-negative Matrix Factorization) 등으로 사용자-아이템 평점 행렬을 저차원 잠재 요인(latent factor) 행렬로 분해한다. 딥러닝 기반 접근법은 오토인코더·NCF(Neural Collaborative Filtering) 등으로 복잡한 사용자-아이템 상호작용 패턴을 학습한다.
행렬을 채우고 유사도를 계산하는 절차
사용자 기반 협업 필터링은 사용자-아이템 평점 행렬을 구성하고, 코사인 유사도·피어슨 상관계수·자카드 유사도 등으로 사용자 간 유사도를 계산한 뒤, 유사 사용자를 식별하고, 예측 평점을 계산해 Top-N 추천 아이템을 생성하는 순서로 진행된다.
아이템 기반 협업 필터링은 사용자-아이템 평점 행렬을 구성하고 아이템 간 유사도를 계산한 뒤, 사용자가 평가한 아이템을 기반으로 다른 아이템의 예측 평점을 계산해 Top-N 추천 아이템을 생성한다.
행렬 분해 기반 협업 필터링은 사용자-아이템 평점 행렬 R을 사용자 행렬 P와 아이템 행렬 Q로 분해한다(R ≈ P × Q^T). SGD·ALS 등으로 P와 Q 행렬을 최적화한 뒤, 최적화된 행렬로 평점을 예측한다.
유사도를 재는 방법들: 코사인부터 자카드까지
코사인 유사도는 두 벡터 간의 각도를 기반으로 유사도를 측정한다. 범위는 -1(완전 반대)에서 1(완전 유사)이고, 수식은 cos(θ) = (A·B) / (||A|| × ||B||)다. 사용자 A와 B의 영화 평점 벡터 간 각도가 작을수록 취향이 유사하다는 뜻이다.
피어슨 상관계수는 두 변수 간의 선형 관계를 측정한다. 범위는 -1(완전 부적 상관)에서 1(완전 정적 상관)이며, 평균을 중심으로 편차를 고려하므로 사용자 평점 경향(관대함/엄격함)을 보정한다.
자카드 유사도는 구매/미구매, 클릭/미클릭 같은 이진 데이터에 적합하다. 두 집합의 교집합 크기를 합집합 크기로 나눈 값으로, 범위는 0(공통 요소 없음)에서 1(완전 동일)이다.
냉시동 문제, 데이터가 없는 사용자와 아이템을 다루는 법
신규 사용자는 행동 데이터가 없어 정확한 추천이 어렵고, 신규 아이템은 초기 평가가 부족해 추천 시스템에 노출되기 어렵다 — 이것이 냉시동(Cold Start) 문제다. 사용자 프로필 정보·아이템 메타데이터를 활용하는 콘텐츠 기반 필터링 병행, 협업 필터링에 콘텐츠 기반·지식 기반 필터링을 결합하는 하이브리드 접근법, 신규 사용자에게 전략적 문항으로 선호도를 파악하는 액티브 러닝(Active Learning), 연령·성별 등 인구통계학적 정보를 활용한 초기 추천으로 대응한다.
희소성 문제와 해결 방안
대부분의 사용자는 전체 아이템 중 일부만 평가하며 보통 1% 미만이다. 이런 데이터 희소성 때문에 유사도 계산 정확도가 떨어진다. SVD·PCA 등으로 밀집된 저차원 표현을 추출하는 차원 축소 기법, MF·SVD++·Factorization Machines 등의 잠재 요인 모델, 사용자-아이템 이분 그래프에서 경로 기반 유사도를 계산하는 그래프 기반 방법으로 해결한다.
아마존·넷플릭스·스포티파이가 구현한 방식
아마존은 "이 상품을 구매한 사용자들이 구매한 다른 상품"을 추천하는 아이템 기반 협업 필터링을 쓴다. 아이템 간 유사도를 미리 계산해 실시간 추천에 활용하며, 대규모 카탈로그에서도 효율적으로 추천을 제공한다.
넷플릭스는 영화 추천 정확도 향상을 위해 넷플릭스 프라이즈 대회를 개최했고, SVD·Restricted Boltzmann Machines 등 다양한 기법을 활용해 하이브리드 앙상블 모델로 최종 추천 시스템을 구축했다.
스포티파이는 음악 소비 패턴 분석을 통한 협업 필터링에 오디오 특성·가사·장르 등 콘텐츠 메타데이터를 결합해 주간 개인화 플레이리스트 'Discover Weekly'를 제공한다.
무엇으로 추천 품질을 평가하는가
정확도 지표로는 예측 평점과 실제 평점 간 차이를 측정하는 RMSE(Root Mean Square Error), 예측 오차의 절대값 평균인 MAE(Mean Absolute Error)가 쓰인다.
랭킹 기반 지표로는 추천된 아이템 중 관련 있는 아이템 비율인 정밀도(Precision), 관련 있는 모든 아이템 중 추천된 아이템 비율인 재현율(Recall), 정밀도와 재현율의 조화평균인 F1 점수, 순위를 고려한 정밀도 평균인 MAP(Mean Average Precision), 순위와 관련성을 고려한 NDCG(Normalized Discounted Cumulative Gain)가 있다.
비즈니스 관련 지표로는 추천된 아이템 클릭률인 CTR(Click-Through Rate), 추천으로 인한 구매·가입 비율인 전환율(Conversion Rate), 설문조사·이탈률 등으로 측정하는 사용자 만족도가 쓰인다.
딥러닝과 시퀀스, 강화학습으로 넘어가는 흐름
딥러닝 기반 협업 필터링은 비선형 잠재 특성을 학습하는 오토인코더, MLP와 행렬 분해를 결합한 신경망 협업 필터링(NCF), 사용자-아이템 상호작용을 그래프로 모델링하는 그래프 신경망(GNN)으로 발전하고 있다.
시퀀셜 추천 시스템은 RNN·LSTM·Transformer로 사용자 행동 시퀀스를 고려해 시간적 컨텍스트와 사용자 취향 변화를 반영한다.
강화학습 기반 추천은 추천 시스템을 MDP(Markov Decision Process)로 모델링해 장기적 사용자 만족도를 최적화하고, 탐색(exploration)과 활용(exploitation) 간 균형을 조정한다.
파이썬으로 구현해보기
사용자 기반 협업 필터링은 사용자 간 코사인 유사도를 계산해 예측 평점을 구하는 방식으로 구현할 수 있다.
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
# 사용자-아이템 평점 행렬
ratings = np.array([
[5, 4, 0, 0, 1],
[0, 0, 5, 4, 0],
[4, 5, 0, 0, 2],
[0, 0, 4, 5, 0]
])
# 사용자 간 유사도 계산
user_similarity = cosine_similarity(ratings)
# 특정 사용자에 대한 예측 평점 계산
def predict_ratings(user_id, item_id):
sim_scores = user_similarity[user_id]
item_ratings = ratings[:, item_id]
# 해당 아이템에 대한 평점이 있는 사용자만 고려
mask = item_ratings > 0
# 유사도 가중 평균 계산
if np.sum(mask) > 0:
weighted_sum = np.sum(sim_scores[mask] * item_ratings[mask])
sim_sum = np.sum(np.abs(sim_scores[mask]))
if sim_sum > 0:
return weighted_sum / sim_sum
return 0
행렬 분해 기반 협업 필터링은 surprise 라이브러리의 SVD로 구현할 수 있다.
from surprise import SVD, Dataset, Reader
from surprise.model_selection import cross_validate
# 데이터 로드 및 전처리
reader = Reader(rating_scale=(1, 5))
data = Dataset.load_from_df(ratings_df[['user_id', 'item_id', 'rating']], reader)
# SVD 모델 학습
svd = SVD(n_factors=50, n_epochs=20, lr_all=0.005, reg_all=0.02)
cross_validate(svd, data, measures=['RMSE', 'MAE'], cv=5, verbose=True)
# 전체 데이터셋으로 학습
trainset = data.build_full_trainset()
svd.fit(trainset)
# 예측 평점 계산
user_id = 1
item_id = 42
pred = svd.predict(user_id, item_id)
print(f"예측 평점: {pred.est:.2f}")
확장성과 프라이버시, 실제 도입에서 부딪히는 것들
대규모 사용자와 아이템을 처리하려면 근사 최근접 이웃(Approximate Nearest Neighbors) 알고리즘과 Spark·Hadoop 같은 분산 처리 프레임워크가 필요한 확장성(Scalability) 문제를 풀어야 한다. 사용자 행동을 즉시 반영하려면 증분 업데이트(Incremental Updates)와 온라인 학습(Online Learning)을 구현해야 하는 실시간 처리 과제도 있다.
프라이버시 측면에서는 GDPR·CCPA 등 개인정보 보호 규정을 준수해야 하고, 연합 학습(Federated Learning)이나 차분 프라이버시(Differential Privacy) 기법을 고려할 수 있다. 인기 아이템 쏠림 현상(Filter Bubble)을 막고 추천 다양성(Diversity)과 공정성(Fairness)을 고려한 알고리즘 설계도 도입 시 함께 풀어야 할 과제다.