개인화 추천 시스템 설계: 협업 필터링·행렬 분해·콘텐츠 기반 필터링

협업 필터링, 행렬 분해, 콘텐츠 기반 필터링의 특성과 추천 시스템 데이터·서빙·평가 설계 원칙을 정리한다.

2026-08-14 · 최초 발행 2024-04-29

추천 모델은 데이터 상태에 따라 역할이 달라진다

추천 시스템은 개인화 경험을 만드는 인프라다. 대표적인 접근은 협업 필터링(Collaborative Filtering), 행렬 분해(Matrix Factorization), 콘텐츠 기반 필터링(Content-Based Filtering)으로 나뉜다. 각 방식은 사용자-아이템 상호작용의 밀도, 메타데이터 품질, 콜드스타트 조건에서 서로 다른 강점과 제약을 보인다.

협업 필터링은 사용자-아이템 상호작용(user–item interactions)에서 유사한 패턴을 찾아 선호를 추론한다. 메모리 기반 KNN과 잠재 요인, neural CF 등을 활용하는 모델 기반 방식으로 구분할 수 있다.

행렬 분해는 사용자-아이템 평점 행렬을 저차원 잠재 요인(latent factors)으로 나누고, 그 내적으로 선호도를 예측한다. SVD, ALS, BPR 같은 최적화 방식을 사용하며 희소성과 확장성에 강점이 있다.

콘텐츠 기반 필터링은 텍스트, 카테고리, 임베딩 같은 아이템 메타데이터로 사용자 프로필을 만들고 콘텐츠 간 유사성으로 추천한다. 신규 아이템을 다루기 좋고, 추천 이유를 설명하기에도 유리하다.

학습 데이터와 온라인 경로를 함께 설계한다

입력 데이터에는 뷰·클릭·구매 로그, 평점, 아이템 메타데이터, 사용자 프로필이 포함된다. 배치와 스트리밍으로 함께 수집한 뒤 정규화, 희소 행렬 구성, TF-IDF 또는 토큰화 같은 텍스트 전처리를 수행한다. 시간 분할 스냅샷은 일 단위 파티션으로 적용할 수 있다.

모델 선택은 데이터 특성에 맞춘다. 협업 필터링은 이웃 기반 KNN 또는 신경망·요인모형 기반으로 구성하며, 근접 탐색에는 ANN(Vector DB)을 사용할 수 있다. 행렬 분해에서는 잠재 요인 차원, 정규화, 회귀·순위 손실함수를 결정해야 하고, 암묵적 피드백에는 ALS/BPR을 채택한다. 콘텐츠 기반 필터링은 BoW, TF-IDF, Transformer 임베딩 중 아이템 표현을 고르고 시간감가와 최근성을 반영한 사용자 프로필 가중치를 설계한다.

서빙은 오프라인 학습 결과를 모델 레지스트리에 등록하고, 온라인 피처 스토어와 캐시에 Top-N·임베딩을 배치한 뒤 실시간 랭킹으로 연결하는 형태가 일반적이다. 장애나 콜드스타트에는 인기·신규·콘텐츠 기반 추천을 대체 경로로 둔다.

평가는 오프라인과 온라인으로 나뉜다. 오프라인에서는 RMSE/MAE, MAP/NDCG/Recall@K, Coverage/Diversity를 보고, 온라인에서는 CTR/CVR, Revenue per Session, Latency/Timeout, Drift(분포 변화)를 관찰한다. 희소 행렬은 CSR/CSC로 압축하고, ANN은 HNSW/IVF로 구성할 수 있다. 유저·세션 Top-N 캐시와 비동기 재랭킹을 조합하면서 메모리와 지연의 상충을 관리하고, 일/시간 배치와 근실시간 업데이트를 혼합한다.

추천 결과가 만들어지는 경로

주기적 갱신에러/콜드스타트입력 데이터- 상호작용 로그- 평점/클릭/구매- 아이템 메타데이터전처리/특징화- 정규화/필터링- 희소행렬/TF-IDF- 스냅샷 파티션알고리즘 선택Collaborative Filtering(KNN/모델 기반)Matrix Factorization(ALS/BPR/SVD)Content-Based Filtering(TF-IDF/임베딩)오프라인 학습모델/아티팩트 레지스트리- 요인벡터/유사도 인덱스온라인 서빙 레이어- 피처 스토어/캐시- 근접탐색(ANN)랭킹/규칙 조합- 개인화 점수- 비즈니스 제약출력: Top-N 추천피드백 수집/로그대체 경로- 인기/CBF/신규

알고리즘별 운영상 차이

알고리즘 성능(정확도) 확장성 일관성(오프라인-온라인) 안정성(콜드스타트/희소성) 운영 편의
Collaborative Filtering 데이터 밀집 시 우수, 이웃 품질에 민감 KNN은 대규모 시 부담, ANN로 완화 특징/유사도 정의 일치 시 양호 사용자/아이템 콜드스타트 취약 구현 단순, 피쳐 의존 낮음
Matrix Factorization 대체로 높은 Top-N 품질, RMSE 안정 선형 스케일, 분산 ALS 적합 동일 파이프라인 유지 시 높음 아이템 콜드스타트 보통, 사용자 신규 취약 모델 관리 필요, 주기 학습 용이
Content-Based Filtering 메타 품질 의존, 설명가능성 높음 메타 임베딩 인덱스화로 우수 피쳐 생성 파이프라인 중요 신규 아이템 강점, 사용자 신규 보통 규정 준수/컨트롤 용이

이웃, 잠재 요인, 메타데이터를 다루는 방식

Collaborative Filtering

협업 필터링은 사용자 또는 아이템의 유사도를 기반으로 가까운 이웃을 찾는다. 코사인, 피어슨, 제이카드 등의 거리 척도를 사용할 수 있다. 메모리 기반 방식은 단순하지만 대규모 환경에서는 계산 비용이 문제가 되므로 ANN 인덱스(HNSW)로 보완한다. 스파스 데이터에서는 이웃 품질이 떨어질 수 있어 최소 공통 상호작용 임계치를 설정해야 한다.

Matrix Factorization

행렬 분해는 선호도를 잠재 요인의 내적으로 근사하고 정규화로 과적합을 막는다. 암묵적 피드백에서는 신뢰도 가중(α) 설계가 중요하며, 시간 감가(temporal weighting)를 함께 적용할 수 있다. 재학습 비용을 예측하기 쉽고, 요인 캐싱으로 서빙 지연을 줄일 수 있다.

Content-Based Filtering

콘텐츠 기반 필터링의 성능은 텍스트·이미지·카테고리로 표현한 아이템 품질에 크게 좌우된다. 도메인 스키마와의 정합성도 필요하다. 사용자 프로필은 선호 아이템 표현의 가중 평균으로 구성하며 최근성·세션 가중치를 적용한다. 개인화 근거를 설명하기 쉽고 규칙 기반 조합으로 통제성을 확보할 수 있다.

서비스별 조합 방식

이커머스에서는 재방문 사용자에게 MF 기반 개인화 Top-N을 제공하고 재랭킹에서 재고·마진·프로모션을 반영할 수 있다. 신규 아이템은 CBF로 초기 노출을 확보한 뒤 성과가 쌓이면 MF로 전환한다.

콘텐츠 스트리밍에서는 시청 시간 가중 암묵 피드백으로 MF를 학습하고, 시즌·에피소드 관계는 CBF로 보강한다. 검색·디스커버리에서는 검색 결과 재랭킹에 CF/MF 점수를 융합하고 쿼리-아이템 임베딩으로 CBF 쿼리 확장을 적용한다.

광고 추천은 콜드스타트와 규정 준수 요구를 고려해야 한다. 맥락 CBF와 합법적 1st-party 데이터로 제한해 운용하며 최신 정책 확인이 필요하다.

성과 지표와 운영 조건

CTR 520%p, CVR 15%p 개선 범위를 기대할 수 있으나 트래픽과 카탈로그 규모에 따라 편차가 있다. 일 PV 100만, 베이스 CTR 4%에서 5% 향상 시 클릭은 4만→5만(+1만, +25%)이 된다. 평균 전환율 2%를 유지하면 추가 구매는 200건이다.

개인화는 사용자 만족도와 체류시간을 높이고 탐색 비용을 낮추며, 신규 아이템의 롱테일 노출을 넓힌다. 운영에서는 규정 준수와 설명가능성을 확보하고 실험 기반 의사결정을 정착시키는 효과도 있다.

Python으로 확인하는 추천 모델

전제조건은 다음과 같다.

  • Python 3.10+, pip, 인터넷 연결
  • 데이터: Surprise 내장 MovieLens-100k 또는 자체 CSV

설치:

pip install scikit-learn==1.4.2 scikit-surprise==1.1.3 numpy==1.26.4

Matrix Factorization(SVD)와 User-based CF(KNN)를 Surprise로 실행하는 예시다.

# 실행 환경: Python 3.10, scikit-surprise 1.1.3
from surprise import Dataset, SVD, KNNBasic
from surprise.model_selection import train_test_split
from surprise import accuracy
from collections import defaultdict

# 데이터 로드 (MovieLens 100k)
data = Dataset.load_builtin('ml-100k')
trainset, testset = train_test_split(data, test_size=0.2, random_state=42)

# 1) MF: SVD
mf = SVD(n_factors=50, reg_all=0.02, n_epochs=20, random_state=42)
mf.fit(trainset)
preds_mf = mf.test(testset)
print("MF RMSE:", accuracy.rmse(preds_mf, verbose=False))

# 2) CF: User-based KNN (Cosine)
sim_options = {"name": "cosine", "user_based": True, "min_support": 3}
cf = KNNBasic(k=40, min_k=3, sim_options=sim_options)
cf.fit(trainset)
preds_cf = cf.test(testset)
print("CF RMSE:", accuracy.rmse(preds_cf, verbose=False))

# Top-N 추천 함수
def get_top_n(predictions, n=10, min_rating=3.5):
    top_n = defaultdict(list)
    for uid, iid, true_r, est, _ in predictions:
        if est >= min_rating:
            top_n[uid].append((iid, est))
    for uid, user_ratings in top_n.items():
        user_ratings.sort(key=lambda x: x[1], reverse=True)
        top_n[uid] = user_ratings[:n]
    return top_n

# 신규 사용자 평가셋 기준 Top-N 생성 예시
topn_mf = get_top_n(preds_mf, n=10)
any_uid = list(topn_mf.keys())[0]
print("Sample Top-N (MF) for user:", any_uid, topn_mf[any_uid][:5])

콘텐츠 기반 필터링은 TF-IDF와 코사인 유사도로 구성할 수 있다.

# 실행 환경: Python 3.10, scikit-learn 1.4.2
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity

# 예시 아이템 메타데이터
items = {
    "i1": "romantic comedy college life",
    "i2": "space opera sci-fi adventure",
    "i3": "dark crime thriller detective",
    "i4": "comedy family daily life",
    "i5": "sci-fi time travel adventure"
}

# 사용자가 좋아한 아이템
liked = ["i2", "i5"]  # sci-fi 성향 가정

# TF-IDF 임베딩
vectorizer = TfidfVectorizer()
corpus = [items[iid] for iid in items]
X = vectorizer.fit_transform(corpus)
id2idx = {iid: idx for idx, iid in enumerate(items.keys())}
idx2id = {idx: iid for iid, idx in id2idx.items()}

# 사용자 프로필 = 선호 아이템 벡터 평균
user_vec = np.mean([X[id2idx[i]] for i in liked], axis=0)

# 유사도 계산 및 Top-N
sims = cosine_similarity(user_vec, X).ravel()
rank_idx = sims.argsort()[::-1]
top_n = [(idx2id[i], float(sims[i])) for i in rank_idx if idx2id[i] not in liked][:5]
print("CBF Top-N:", top_n)

학습과 서빙에는 같은 파티션 컷오버 시점을 적용해 쓰기-읽기 경합을 최소화한다. 사용자 Top-N 캐시의 TTL은 5~30분으로 두고 세션 이벤트가 발생하면 부분 무효화한다. 추천 요청이 실패하면 CBF→인기→랜덤 순으로 폴백해 SLA를 유지한다. 개인정보는 최소 수집·가명처리, 목적 제한, 보존 기간을 준수하며 최신 규제를 확인한다.

초기에는 CBF와 인기 기반 하이브리드로 시작하고, 데이터가 축적되면 MF로 전환할 수 있다. 이후 세그먼트별 CF/MF/CBF 앙상블로 고도화한다. 이 과정에서 일관된 피쳐와 스냅샷, A/B 실험 프레임워크, 성능과 지연의 트레이드오프를 함께 관리한다.

추천 시스템협업 필터링행렬 분해콘텐츠 기반 필터링개인화