검색
← 모듈 로드맵

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

강의 · 준전문가 · KAITABASE 정리

협업 필터링 · 행렬 분해(SGD · ALS) · 콘텐츠 기반 · 콜드 스타트 · 순위 지표를 손계산하는 추천 수업

먼저 알아야 할 것

벡터 내적 · 코사인 유사도경사 하강법L2 정규화저차원 근사(SVD)

다루는 내용

추천 시스템의 후보 생성 · 점수 매기기 · 재순위 구조와 사용자-항목 행렬을 설명합니다. 3×4 평점 표로 사용자 기반 협업 필터링을 계산하고, 행렬 분해의 목적 함수 선택(관측 칸 · SVD · 가중 행렬 분해)과 SGD · ALS 한 걸음을 손으로 계산합니다. 콘텐츠 기반 추천과 콜드 스타트 대처, RMSE · 정밀도@k · 재현율@k · nDCG 평가를 정리합니다.

해설

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

쇼핑몰의 "이 상품을 본 사람들이 함께 본 상품", 영상 서비스의 "다음 볼 영상" 뒤에는 추천 시스템이 있습니다. 이 수업은 사용자-항목 행렬에서 출발해, 비슷한 사용자의 취향을 빌려 오는 협업 필터링, 사용자와 항목을 짧은 벡터로 요약하는 행렬 분해(SGD · ALS), 항목 내용을 쓰는 콘텐츠 기반 추천, 콜드 스타트와 평가 지표까지 작은 표로 직접 계산합니다.

항목내용
참고 자료Google 'Recommendation Systems' 과정 · developers.google.com/machine-learning/recommendation · Koren · Bell · Volinsky, "Matrix Factorization Techniques for Recommender Systems", IEEE Computer 42(8), 2009
트랙 · 수준머신러닝 · 중급
이 수업의 범위추천 시스템의 단계(후보 생성 · 점수 매기기 · 재순위), 사용자-항목 행렬과 명시적 · 암묵적 피드백, 사용자 기반 협업 필터링, 코사인 유사도, 행렬 분해 목적 함수, SGD 한 걸음, ALS 한 걸음, 콘텐츠 기반 추천, 콜드 스타트, 평가 지표(RMSE · 정밀도@k · 재현율@k · nDCG)
먼저 알면 좋은 것벡터 내적 · 코사인 유사도, 경사 하강법, L2 정규화

들어가기 전에

한눈에 보기

  • 추천 시스템이 보통 후보 생성 → 점수 매기기 → 재순위의 단계로 이루어진다는 것을 압니다.
  • 비슷한 사용자의 평점으로 빈칸을 예측하는 협업 필터링을 3×4 표로 직접 계산합니다.
  • 행렬 분해가 사용자 · 항목을 짧은 벡터로 바꾸고 내적으로 평점을 예측한다는 것과, SGD · ALS로 학습하는 한 걸음을 손으로 계산합니다.
  • 콘텐츠 기반 추천과 협업 필터링의 장단점, 콜드 스타트 대처법을 압니다.
  • 평점 예측 지표(RMSE)와 순위 지표(정밀도@k · 재현율@k · nDCG)를 구분해 계산합니다.

1. 추천 시스템의 큰 그림

직관(해설용 비유): 서점 직원을 떠올려 보세요. 수십만 권 중에서 먼저 손님이 좋아할 만한 책 몇백 권을 추리고(후보 생성), 그중 무엇이 가장 맞을지 하나하나 점수를 매긴 뒤(점수 매기기), 같은 작가 책만 몰리지 않게 섞고 이미 산 책은 빼서 보여 줍니다(재순위). Google 추천 시스템 과정도 추천 시스템의 구성 요소를 후보 생성(candidate generation) · 점수 매기기(scoring) · 재순위(re-ranking)로 나눠 설명합니다.

용어뜻
항목(item)추천 대상(상품 · 영상 · 글 · 음악)
질의 · 문맥(query · context)추천을 받는 쪽 정보(사용자, 시간, 기기, 최근 본 것)
명시적 피드백(explicit feedback)별점 · 좋아요처럼 사용자가 직접 표현한 선호
암묵적 피드백(implicit feedback)클릭 · 시청 시간 · 구매처럼 행동에서 추정한 선호

이 정보를 사용자-항목 행렬(user-item matrix) AA로 정리합니다. 행이 사용자, 열이 항목이고, 칸에는 평점이나 상호작용 여부가 들어갑니다. 실제 행렬은 대부분이 빈칸인 희소 행렬(sparse matrix)입니다. 추천은 결국 "빈칸 중 무엇이 높을까"를 예측하는 일입니다.

2. 협업 필터링: 비슷한 사람의 취향 빌리기

직관: 나와 영화 취향이 비슷한 친구가 재밌게 본 영화라면 나도 좋아할 가능성이 큽니다. 협업 필터링(collaborative filtering)은 항목의 내용을 몰라도, 사용자들의 행동 패턴만으로 추천합니다.

단계(사용자 기반, 설명용 단순화)

  1. 대상 사용자와 다른 사용자들의 유사도를 계산합니다(둘 다 평가한 항목만으로).
  2. 예측하려는 항목을 평가한 사용자들의 평점을, 유사도로 가중 평균합니다.
  3. 예측 평점이 높은 항목을 추천합니다.
cos⁡(a,b)=∑i∈Iabrai rbi∑i∈Iabrai2 ∑i∈Iabrbi2,r^aj=∑bsim⁡(a,b) rbj∑b∣sim⁡(a,b)∣\cos(a, b) = \frac{\sum_{i \in I_{ab}} r_{ai}\, r_{bi}}{\sqrt{\sum_{i \in I_{ab}} r_{ai}^2}\,\sqrt{\sum_{i \in I_{ab}} r_{bi}^2}}, \qquad \hat r_{aj} = \frac{\sum_{b} \operatorname{sim}(a, b)\, r_{bj}}{\sum_{b} \lvert \operatorname{sim}(a, b) \rvert}
기호뜻
rair_{ai}사용자 aa가 항목 ii에 준 평점
IabI_{ab}aa와 bb가 둘 다 평가한 항목 집합
r^aj\hat r_{aj}사용자 aa의 항목 jj 예측 평점

숫자로 해 보기(해설용, 파이썬으로 확인): 사용자 3명, 영화 4편, 빈칸은 "-"입니다.

영화1영화2영화3영화4
A54-1
B451-
C1-54
  • A–B 유사도: 둘 다 본 영화1 · 2: (5⋅4+4⋅5)/(25+16)(16+25)=40/41≈0.976(5 \cdot 4 + 4 \cdot 5)/\sqrt{(25+16)(16+25)} = 40/41 \approx 0.976
  • A–C 유사도: 둘 다 본 영화1 · 4: (5⋅1+1⋅4)/(25+1)(1+16)=9/442≈0.428(5 \cdot 1 + 1 \cdot 4)/\sqrt{(25+1)(1+16)} = 9/\sqrt{442} \approx 0.428
  • A의 영화3 예측: (0.976×1+0.428×5)/(0.976+0.428)≈2.22(0.976 \times 1 + 0.428 \times 5)/(0.976 + 0.428) \approx 2.22

A와 취향이 꼭 닮은 B가 영화3을 1점 줬기 때문에 예측이 낮게 나옵니다. 다만 C와의 유사도 0.428은 실제로는 취향이 반대인데도 양수입니다. 평점이 모두 양수라 코사인이 높게 나오는 문제로, 실무에서는 사용자별 평균을 빼고(평균 중심화) 유사도를 계산하는 경우가 많습니다.

사용자 기반 vs 항목 기반: 사용자끼리 대신 항목끼리 유사도를 계산하는 항목 기반(item-based) 방식도 있습니다("이 상품을 산 사람들이 산 다른 상품"). 항목 수가 사용자 수보다 적고 항목 취향이 더 안정적인 서비스에서 많이 씁니다.

3. 행렬 분해: 사용자와 항목을 짧은 벡터로

직관: 영화 취향을 "액션을 얼마나 좋아하나", "로맨스를 얼마나 좋아하나" 같은 몇 개 숫자로 요약하고, 영화도 "액션이 얼마나 많나", "로맨스가 얼마나 많나"로 요약하면, 둘의 내적이 곧 "이 사람이 이 영화를 얼마나 좋아할까"가 됩니다. 행렬 분해(matrix factorization)는 이런 숨은 요인(latent factor)을 데이터에서 자동으로 찾습니다. Koren · Bell · Volinsky(2009)는 Netflix Prize 경험을 바탕으로 행렬 분해 모델이 고전적인 최근접 이웃 방법보다 나은 추천을 낸다고 정리했습니다.

A≈UV⊤,r^ij=⟨Ui,Vj⟩A \approx U V^\top, \qquad \hat r_{ij} = \langle U_i, V_j \rangle
기호뜻
AAm×nm \times n 사용자-항목 행렬
UUm×dm \times d 사용자 임베딩 행렬. UiU_i는 사용자 ii의 벡터
VVn×dn \times d 항목 임베딩 행렬. VjV_j는 항목 jj의 벡터
dd임베딩 차원(숨은 요인 수). 보통 m,nm, n보다 훨씬 작음

무엇을 최소화하나 — 빈칸을 어떻게 다룰까

Google 과정은 목적 함수 세 가지를 비교합니다.

목적식(요지)문제점 · 특징
관측된 칸만∑(i,j)∈obs(Aij−⟨Ui,Vj⟩)2\sum_{(i,j)\in\text{obs}} (A_{ij} - \langle U_i, V_j\rangle)^2모든 예측을 1로 내는 모델도 손실이 작아져 일반화가 나쁨(암묵적 피드백에서 특히)
빈칸을 0으로(SVD)∥A−UV⊤∥F2\lVert A - UV^\top \rVert_F^2행렬이 매우 희소하면 예측이 0 쪽으로 쏠림
가중 행렬 분해관측 칸 오차 + w0∑(i,j)∉obs⟨Ui,Vj⟩2+\ w_0 \sum_{(i,j)\notin\text{obs}} \langle U_i, V_j\rangle^2w0w_0로 두 항의 균형을 조절, 신중한 튜닝 필요

명시적 평점(별점)만 예측할 때는 관측된 칸만 쓰되 L2 정규화를 더한 형태가 흔합니다.

min⁡U,V∑(i,j)∈obs(rij−⟨Ui,Vj⟩)2+λ(∥Ui∥2+∥Vj∥2)\min_{U, V} \sum_{(i,j) \in \text{obs}} \big(r_{ij} - \langle U_i, V_j \rangle\big)^2 + \lambda\big(\lVert U_i \rVert^2 + \lVert V_j \rVert^2\big)

SGD로 한 걸음

관측된 평점 하나 rijr_{ij}를 뽑아 오차 e=rij−⟨Ui,Vj⟩e = r_{ij} - \langle U_i, V_j\rangle를 계산하고, 두 벡터를 동시에 조금 움직입니다(상수 2는 학습률에 흡수).

Ui←Ui+η (e Vj−λUi),Vj←Vj+η (e Ui−λVj)U_i \leftarrow U_i + \eta\,(e\, V_j - \lambda U_i), \qquad V_j \leftarrow V_j + \eta\,(e\, U_i - \lambda V_j)

숫자로 해 보기(해설용, 파이썬으로 확인): d=2d = 2, Ui=(1.0,0.5)U_i = (1.0, 0.5), Vj=(0.8,1.0)V_j = (0.8, 1.0), 실제 평점 5, η=0.1\eta = 0.1, λ=0.1\lambda = 0.1입니다.

  1. 예측 =1.0×0.8+0.5×1.0=1.3= 1.0 \times 0.8 + 0.5 \times 1.0 = 1.3, 오차 e=3.7e = 3.7
  2. Ui←(1.0,0.5)+0.1×(3.7×(0.8,1.0)−0.1×(1.0,0.5))=(1.286,0.865)U_i \leftarrow (1.0, 0.5) + 0.1 \times (3.7 \times (0.8, 1.0) - 0.1 \times (1.0, 0.5)) = (1.286, 0.865)
  3. Vj←(0.8,1.0)+0.1×(3.7×(1.0,0.5)−0.1×(0.8,1.0))=(1.162,1.175)V_j \leftarrow (0.8, 1.0) + 0.1 \times (3.7 \times (1.0, 0.5) - 0.1 \times (0.8, 1.0)) = (1.162, 1.175) (갱신 전 UiU_i를 사용)
  4. 새 예측 =1.286×1.162+0.865×1.175≈2.51= 1.286 \times 1.162 + 0.865 \times 1.175 \approx 2.51로, 5에 가까워졌습니다.

ALS로 한 걸음

직관: UU와 VV를 동시에 풀면 볼록하지 않은 문제지만, 한쪽을 고정하면 다른 쪽은 그냥 릿지 회귀라 정확한 해를 바로 구할 수 있습니다. 교대 최소제곱(ALS, alternating least squares)은 VV 고정 → UU 풀기 → UU 고정 → VV 풀기를 번갈아 합니다. Google 과정은 가중 버전(WALS)을 소개하며, 각 단계가 손실을 줄여 수렴이 보장되고 병렬화가 쉽다고 설명합니다.

1차원(d=1d = 1)이면 사용자 ii의 해는 다음과 같습니다.

ui=∑jvj rij∑jvj2+λu_i = \frac{\sum_j v_j\, r_{ij}}{\sum_j v_j^2 + \lambda}

숫자로 해 보기(해설용): 사용자가 평가한 항목 3개의 요인이 v=(1,2,0.5)v = (1, 2, 0.5), 평점이 (2,4,1)(2, 4, 1), λ=0.1\lambda = 0.1이면 분자 2+8+0.5=10.52 + 8 + 0.5 = 10.5, 분모 1+4+0.25+0.1=5.351 + 4 + 0.25 + 0.1 = 5.35 → ui≈1.963u_i \approx 1.963입니다.

비교(Google 과정 정리)SGDWALS
유연성다른 손실 함수도 가능제곱 손실 전용
병렬화가능가능
수렴느림빠름
빈칸 처리어려움(음성 샘플링 등 필요)쉬움
mermaid
flowchart LR
  A[행동 로그 · 평점] --> B[사용자-항목 희소 행렬]
  B --> C[행렬 분해: U, V 학습 - SGD 또는 ALS]
  C --> D[후보 생성: 사용자 벡터와 내적 큰 항목 수백 개]
  E[항목 내용 · 사용자 특성] --> F[점수 모델: 후보마다 클릭 · 구매 확률]
  D --> F
  F --> G[재순위: 이미 본 것 제외 · 다양성 · 신선도]
  G --> H[추천 목록]
  H --> I[클릭 · 시청 피드백]
  I --> A

4. 콘텐츠 기반 추천과 콜드 스타트

콘텐츠 기반 추천(content-based filtering): 항목의 특성(장르 · 키워드 · 가격 · 글 내용의 임베딩)과 사용자가 과거에 좋아한 항목의 특성을 비교해 비슷한 것을 추천합니다. 다른 사용자의 데이터가 없어도 되고, 새 항목도 특성만 있으면 바로 추천할 수 있습니다. 대신 사용자가 이미 좋아하던 것과 비슷한 것만 나와, 뜻밖의 발견(serendipity)이 적습니다.

콜드 스타트(cold start): 학습 때 없던 새 항목 · 새 사용자는 임베딩이 없어 협업 필터링으로 점수를 매길 수 없습니다. Google 과정이 소개하는 대처법은 다음과 같습니다.

  • 새 항목이 받은 몇 개의 상호작용으로, 전체를 다시 학습하지 않고 그 항목의 임베딩만 계산합니다(ALS의 한쪽 풀기와 같은 원리).
  • 같은 범주 · 같은 업로더 항목들의 임베딩 평균으로 새 항목 임베딩을 어림합니다.

실무에서는 여기에 인기 항목 · 콘텐츠 기반 추천을 섞어 초기 공백을 메우는 경우가 많습니다.

협업 필터링 · 행렬 분해콘텐츠 기반
필요한 것많은 사용자의 행동항목 특성
도메인 지식필요 없음(임베딩 자동 학습)특성 설계가 필요
뜻밖의 발견있음적음
새 항목어려움(콜드 스타트)쉬움
부가 특성(나이 · 국가 등)기본 행렬 분해에 넣기 어려움자연스럽게 사용

5. 추천은 어떻게 평가하나

지표질문계산
RMSE평점을 얼마나 정확히 맞히나1N∑(r−r^)2\sqrt{\frac1N\sum(r - \hat r)^2}
정밀도@k(precision@k)상위 kk개 중 맞는 것의 비율맞힌 수 / kk
재현율@k(recall@k)사용자가 좋아할 항목 중 상위 kk에 들어온 비율맞힌 수 / 전체 관련 항목 수
nDCG@k맞는 항목이 위쪽에 있을수록 높은 점수DCG/IDCG\text{DCG}/\text{IDCG}, DCG=∑relilog⁡2(i+1)\text{DCG} = \sum \frac{rel_i}{\log_2(i+1)}

숫자로 해 보기(해설용, 파이썬으로 확인): 추천 5개가 (a,b,c,d,e)(a, b, c, d, e)이고 실제로 사용자가 좋아한 항목이 {b,d,x}\{b, d, x\}입니다.

  • 정밀도@5 =2/5=0.4= 2/5 = 0.4, 재현율@5 =2/3≈0.667= 2/3 \approx 0.667
  • DCG =1/log⁡23+1/log⁡25≈0.631+0.431=1.062= 1/\log_2 3 + 1/\log_2 5 \approx 0.631 + 0.431 = 1.062
  • 이상적 순서(관련 3개가 1~3위)의 IDCG =1+0.631+0.5=2.131= 1 + 0.631 + 0.5 = 2.131 → nDCG@5 ≈0.498\approx 0.498

평점 3개 (4,3,5)(4, 3, 5)를 (3.5,3,4)(3.5, 3, 4)로 예측했다면 RMSE =(0.25+0+1)/3≈0.645= \sqrt{(0.25 + 0 + 1)/3} \approx 0.645입니다.

오프라인 지표의 한계: 과거 로그는 "이전 추천 시스템이 보여 준 것" 위주라 편향되어 있습니다. 실제 개선 여부는 온라인 A/B 테스트로 확인하는 것이 일반적입니다. 순위 지표 계산은 검색의 기초에서 본 nDCG · MRR과 같습니다.

연습 문제

1. 2절 표에서 B와 C의 유사도(둘 다 본 영화만)는?

풀이: 둘 다 본 영화는 1과 3. (4⋅1+1⋅5)/(16+1)(1+25)=9/442≈0.428(4 \cdot 1 + 1 \cdot 5)/\sqrt{(16+1)(1+25)} = 9/\sqrt{442} \approx 0.428입니다.

2. Ui=(1,1)U_i = (1, 1), Vj=(1,0)V_j = (1, 0), 실제 평점 3, η=0.5\eta = 0.5, λ=0\lambda = 0일 때 SGD 한 걸음 뒤의 UiU_i, VjV_j와 새 예측은?

풀이: 예측 1, 오차 2. Ui←(1,1)+0.5×2×(1,0)=(2,1)U_i \leftarrow (1,1) + 0.5 \times 2 \times (1, 0) = (2, 1), Vj←(1,0)+0.5×2×(1,1)=(2,1)V_j \leftarrow (1, 0) + 0.5 \times 2 \times (1, 1) = (2, 1). 새 예측 =4+1=5= 4 + 1 = 5로 지나쳤습니다. 학습률이 너무 크면 오히려 멀어질 수 있습니다.

3. 추천 10개 중 관련 항목이 3개, 사용자의 전체 관련 항목이 6개라면 정밀도@10과 재현율@10은?

풀이: 3/10=0.33/10 = 0.3, 3/6=0.53/6 = 0.5입니다.

4. 새로 등록한 상품을 첫날부터 추천하고 싶습니다. 어떤 방법이 알맞나요?

풀이: 상호작용이 없으므로 협업 필터링은 어렵습니다. 상품 특성으로 콘텐츠 기반 추천을 하거나, 같은 범주 상품 임베딩의 평균으로 초기 임베딩을 어림하고, 상호작용이 쌓이면 그 항목 임베딩만 다시 계산합니다.

스스로 점검

  1. 협업 필터링과 콘텐츠 기반 추천의 가장 큰 차이는?
    • 답: 협업 필터링은 사용자들의 행동 패턴만 쓰고 항목 내용을 몰라도 되며, 콘텐츠 기반은 항목 특성으로 비슷한 것을 찾습니다.
  2. ALS가 한쪽을 고정하면 쉽게 풀리는 이유는?
    • 답: 한쪽 행렬을 고정하면 다른 쪽에 대한 목적 함수가 이차식(릿지 회귀)이 되어 선형 방정식으로 정확히 풀리기 때문입니다.
  3. 암묵적 피드백에서 관측된 칸만으로 학습하면 무엇이 문제인가요?
    • 답: 관측된 칸이 거의 모두 "상호작용 있음(1)"이라, 모든 예측을 1로 내는 모델도 손실이 작아 일반화가 나빠집니다. 빈칸에 가중치 w0w_0를 둔 가중 행렬 분해나 음성 샘플링을 씁니다.

용어 정리

용어쉬운 뜻
추천 시스템(recommender system)사용자에게 맞을 항목을 골라 보여 주는 시스템
후보 생성 · 점수 매기기 · 재순위많이 추리기 → 하나씩 점수 → 최종 목록 다듬기
명시적 · 암묵적 피드백별점처럼 직접 표현한 선호 · 클릭처럼 행동에서 추정한 선호
사용자-항목 행렬(user-item matrix)행 = 사용자, 열 = 항목, 칸 = 평점 · 상호작용
협업 필터링(collaborative filtering)비슷한 사용자 · 항목의 행동으로 추천
행렬 분해(matrix factorization)큰 행렬을 두 작은 행렬의 곱으로 근사
숨은 요인 · 임베딩(latent factor · embedding)사용자 · 항목을 요약한 짧은 벡터
교대 최소제곱(ALS)한쪽을 고정하고 다른 쪽을 정확히 푸는 것을 번갈아 하는 학습
콘텐츠 기반 추천(content-based filtering)항목 특성의 유사도로 추천
콜드 스타트(cold start)새 사용자 · 항목에 데이터가 없어 추천이 어려운 문제
nDCG관련 항목이 위에 있을수록 높은, 0~1로 정규화한 순위 지표

더 깊이 보려면

Google 'Recommendation Systems' 과정은 배경 · 후보 생성 개요 · 콘텐츠 기반 필터링 · 협업 필터링과 행렬 분해 · 심층 신경망 추천(소프트맥스 모델) · 검색 · 점수 매기기 · 재순위 순서로 구성되어 있고, 행렬 분해 목적 함수 비교와 SGD · WALS 비교, 콜드 스타트 대처를 자세히 설명합니다. 행렬 분해에 편향 항 · 암묵적 피드백 · 시간 변화를 넣는 방법은 Koren 외(2009)가 잘 정리되어 있습니다.

다음에 볼 것

라이선스

이 글은 원문 번역이 아니라 KAITABASE가 직접 쓴 해설이며, 평점 표와 숫자 예는 모두 설명용으로 만든 것입니다(파이썬으로 다시 계산해 확인). 참고 자료 Google 과정 본문은 별도 표기가 없는 한 CC BY 4.0입니다.

출처

AI 원리부터 이해하기 · 머신러닝 모듈

머신러닝 모듈 학습

이 글은 머신러닝 모듈의 학습 자료입니다. 전체 17개 자료 중 13번째입니다.

AI 기초 과정은 현재 진도 저장을 지원하지 않습니다.

출처·원문

원문 보기

요약만

본문 자체 작성 · 참고 자료 Google 추천 시스템 과정(CC BY 4.0)