다음과 같은 3명의 사용자와 4개의 영화에 대한 평점 데이터가 있다고 가정하겠습니다:
실제 평점 행렬 R (1-5점 척도):
어벤져스 타이타닉 인셉션 노트북
사용자A 5 3 4 2
사용자B ? 4 3 5
사용자C 4 ? 5 1
3x4 행렬
먼저 P와 Q 행렬을 작은 난수로 초기화합니다.
P (사용자 특성 행렬, 3×2):
사용자A: [0.1, 0.2]
사용자B: [0.2, 0.1]
사용자C: [0.1, 0.1]
Q (영화 특성 행렬, 4×2):
어벤져스: [0.2, 0.1]
타이타닉: [0.1, 0.2]
인셉션: [0.2, 0.2]
노트북: [0.1, 0.3]
(3x2) x (2x4) = 3x4 행렬
예측값은 P와 Q의 내적으로 계산됩니다. (matrix 계산)
예를 들어, 사용자A의 어벤져스 예측 평점:
예측값 = (0.1 × 0.2) + (0.2 × 0.1) = 0.04
실제값 = 5
오차 = 5 - 0.04 = 4.96
각 요소를 다음 공식으로 업데이트합니다:
예)
학습률 α = 0.01
정규화 계수 λ = 0.02
For each observed rating rui:
eui = rui - pui (실제값 - 예측값)
업데이트 공식:
P[u] = P[u] + α × (eui × Q[i] - λ × P[u])
Q[i] = Q[i] + α × (eui × P[u] - λ × Q[i])
예를 들어, 사용자A의 첫 번째 특성 업데이트:
e = 4.96
P[A,1]new = 0.1 + 0.01 × (4.96 × 0.2 - 0.02 × 0.1)
= 0.1 + 0.01 × (0.992 - 0.002)
= 0.1 + 0.0099
= 0.1099
*아래 자세한 내용 참고
이 과정을 모든 관찰된 평점에 대해 반복합니다. 예를 들어 20회 반복 후:
P (사용자 특성):
사용자A: [0.8, 0.3] # 액션 선호도 높음
사용자B: [0.3, 0.9] # 로맨스 선호도 높음
사용자C: [0.9, 0.2] # 액션 선호도 매우 높음
Q (영화 특성):
어벤져스: [0.9, 0.2] # 강한 액션 특성
타이타닉: [0.4, 0.8] # 강한 로맨스 특성
인셉션: [0.7, 0.5] # 액션과 로맨스 혼합
노트북: [0.2, 0.9] # 매우 강한 로맨스 특성
다음 중 하나를 만족할 때 학습을 종료합니다:
1. 전체 오차(RMSE)가 임계값(예: 0.001) 이하
2. 지정된 반복 횟수 도달
3. 오차 감소량이 매우 작아짐
학습이 완료된 후, 빈 값 예측:
사용자B의 어벤져스 평점 예측:
= [0.3, 0.9] · [0.9, 0.2]
= (0.3 × 0.9) + (0.9 × 0.2)
= 0.27 + 0.18
= 0.45
이를 1-5 척도로 변환하면 약 3.5점
이러한 과정을 통해 행렬 분해는 사용자와 아이템의 잠재적 특성을 학습하고, 이를 바탕으로 누락된 평점을 예측할 수 있게 됩니다.
먼저 우리가 최소화하려는 목적 함수를 정의합니다:
J = Σ(rui - p̂ui)² + λ(||P||² + ||Q||²)
여기서:
- rui: 사용자 u의 아이템 i에 대한 실제 평점
- p̂ui: 예측 평점 (P[u]와 Q[i]의 내적)
- λ: 정규화 계수 (과적합 방지)
- ||P||², ||Q||²: P와 Q 행렬의 프로베니우스 놈(L2 정규화)
목적 함수를 P와 Q의 각 요소에 대해 편미분합니다:
∂J/∂puk = -2Σ(rui - p̂ui)qik + 2λpuk
∂J/∂qik = -2Σ(rui - p̂ui)puk + 2λqik
여기서:
- puk: 사용자 u의 k번째 잠재 요인
- qik: 아이템 i의 k번째 잠재 요인
앞서 든 예시를 더 자세히 살펴보겠습니다:
초기값:
사용자A의 특성 벡터 P[A] = [0.1, 0.2]
어벤져스의 특성 벡터 Q[어벤져스] = [0.2, 0.1]
실제 평점 r = 5
학습률 α = 0.01
정규화 계수 λ = 0.02
p̂ = P[A] · Q[어벤져스]
= (0.1 × 0.2) + (0.2 × 0.1)
= 0.02 + 0.02
= 0.04
e = r - p̂
= 5 - 0.04
= 4.96
사용자A의 첫 번째 잠재 요인(p₁) 업데이트:
기울기 = -(r - p̂)q₁ + λp₁
= -(4.96 × 0.2) + 0.02 × 0.1
= -0.992 + 0.002
= -0.99
새로운 p₁ = 0.1 + α × (-기울기)
= 0.1 + 0.01 × 0.99
= 0.1099
사용자A의 두 번째 잠재 요인(p₂) 업데이트:
기울기 = -(4.96 × 0.1) + 0.02 × 0.2
= -0.496 + 0.004
= -0.492
새로운 p₂ = 0.2 + 0.01 × 0.492
= 0.2049
어벤져스의 잠재 요인들도 같은 방식으로 업데이트:
새로운 q₁ = 0.2 + 0.01 × (4.96 × 0.1 - 0.02 × 0.2)
= 0.2 + 0.01 × (0.496 - 0.004)
= 0.2049
새로운 q₂ = 0.1 + 0.01 × (4.96 × 0.2 - 0.02 × 0.1)
= 0.1 + 0.01 × (0.992 - 0.002)
= 0.1099
위 계산에서 정규화 항(λ)의 역할:
1. 과적합 방지: 너무 큰 값들이 나오는 것을 막음
2. 수치 안정성: 발산하는 것을 방지
3. 일반화 성능 향상: 보지 않은 데이터에 대한 예측 성능 개선
예를 들어, 정규화가 없다면(λ=0):
p₁의 업데이트 = 0.1 + 0.01 × (4.96 × 0.2)
= 0.1 + 0.00992
= 0.10992 // 더 큰 변화
정규화가 있을 때(λ=0.02):
p₁의 업데이트 = 0.1 + 0.01 × (4.96 × 0.2 - 0.02 × 0.1)
= 0.1 + 0.01 × (0.992 - 0.002)
= 0.1099 // 약간 더 작은 변화
학습률(α)과 정규화 계수(λ)의 선택이 중요합니다:
α = 0.1 일 때
새로운 p₁ = 0.1 + 0.1 × 0.99 = 0.199
// 한 번에 너무 큰 변화 → 발산 위험
α = 0.001 일 때
새로운 p₁ = 0.1 + 0.001 × 0.99 = 0.10099
// 수렴이 너무 느림
λ = 0.2 일 때
기울기 = -(4.96 × 0.2) + 0.2 × 0.1 = -0.992 + 0.02 = -0.972
// 업데이트가 너무 제한됨
이러한 세부적인 업데이트 과정이 모든 관찰된 평점에 대해 반복되며, 전체 시스템이 수렴할 때까지 계속됩니다.
Netflix를 예로 들어보겠습니다. 사용자 A가 로맨틱 코미디를 좋아하는데, 반드시 "로맨틱 코미디"라는 장르 태그가 있어서가 아닐 수 있습니다.
실제 사례로, 온라인 서점을 봅시다. 100만 권의 책이 있고 사용자는 평균적으로 10권 정도만 읽었다고 하면:
음악 스트리밍 서비스를 예로 들어보겠습니다:
온라인 패션몰 예시:
영화 추천의 예:
"당신이 좋아했던 인셉션과 비슷하게 이 영화도 복잡한 플롯과 SF적 요소가 있습니다."
다만, 이런 장점들을 최대한 활용하려면 적절한 양의 초기 데이터가 필요하며, 하이퍼파라미터 튜닝이 중요합니다.