'나와 비슷하게 별점을 매긴 사람이 좋아한 영화'를 빌려오는 추천의 원리 — 유튜브·넷플릭스 추천의 뼈대예요. 별점을 남기고 추천을 받아 보세요.
🖱️ 맨 오른쪽 파란 나 열의 칸을 클릭하면 ▢ → ★ → ★★ → … → ★★★★★ → ▢ 순서로 내 별점이 바뀌어요. 친구들 별점은 고정이에요.
| 영화 | 민준 SF파 | 서연 SF파 | 지호 SF파 | 하은 로맨스파 | 도윤 로맨스파 | 유나 로맨스파 | 나 👤 클릭! |
|---|---|---|---|---|---|---|---|
| 🚀 우주 해적단 | ★★★★★ | ★★★★ | ★★★★★ | ★★ | ▢ | ★ | |
| 🤖 로봇 전쟁 | ★★★★ | ★★★★★ | ★★★★ | ★ | ★★ | ▢ | |
| 🪐 화성 탈출 | ★★★★★ | ▢ | ★★★★ | ★★ | ★ | ▢ | |
| ⏳ 시간 여행자 | ★★★★ | ★★★★ | ★★★★★ | ▢ | ★★ | ★★★ | |
| 🥐 봄날의 빵집 | ★★ | ★ | ★ | ★★★★★ | ★★★★ | ★★★★★ | |
| 📚 첫사랑 도서관 | ▢ | ★★ | ▢ | ★★★★ | ★★★★★ | ★★★★ | |
| 🐱 고양이와 나 | ★★★ | ★★ | ★★ | ★★★★★ | ★★★★★ | ★★★★ | |
| 🌊 바닷가 편지 | ★ | ★★ | ★ | ★★★★ | ▢ | ★★★★★ |
읽는 법: 행 = 영화(위 4편은 SF, 아래 4편은 로맨스), 열 = 친구들의 별점(★ 1~5개), 연한 ▢ = 아직 안 봄. 친구들의 별점만 보고 취향 그룹이 나뉘는 게 보이나요? 추천 시스템이 가진 정보는 이 표가 전부예요.
표의 나 열에 별점을 남긴 뒤 추천을 받아 보세요. 별점을 바꾸면 이전 결과는 사라져요.
내 별점이 바뀔 때마다 유사도와 추천이 함께 달라져요. SF와 로맨스에 번갈아 별점을 주며 추천이 뒤집히는 순간을 찾아 보세요.
import numpy as np
# 영화 8편: 앞 4편은 SF/액션, 뒤 4편은 로맨스/일상 (R의 열 순서와 같아요)
MOVIES = ["우주 해적단", "로봇 전쟁", "화성 탈출", "시간 여행자",
"봄날의 빵집", "첫사랑 도서관", "고양이와 나", "바닷가 편지"]
# 별점 행렬: 행=친구, 열=영화 8편 (0 = 안 봄)
R = np.array([
[5, 4, 5, 4, 2, 0, 3, 1], # 민준 (SF파)
[4, 5, 0, 4, 1, 2, 2, 2], # 서연 (SF파)
[5, 4, 4, 5, 1, 0, 2, 1], # 지호 (SF파)
[2, 1, 2, 0, 5, 4, 5, 4], # 하은 (로맨스파)
[0, 2, 1, 2, 4, 5, 5, 0], # 도윤 (로맨스파)
[1, 0, 0, 3, 5, 4, 4, 5], # 유나 (로맨스파)
])
me = np.array([5, 5, 0, 0, 0, 0, 0, 0]) # 내 별점
def cos_sim(a, b):
both = (a > 0) & (b > 0) # 둘 다 본 영화만 비교
if both.sum() < 2: return 0.0 # 2편 미만 겹치면 못 믿어요
x, y = a[both], b[both]
return x @ y / (np.linalg.norm(x) * np.linalg.norm(y))
sims = np.array([cos_sim(me, r) for r in R]) # 나 vs 친구들 유사도
for m in np.where(me == 0)[0]: # 내가 안 본 영화마다
seen = R[:, m] > 0 # 그 영화를 본 친구들의
w = sims[seen] # 유사도를 가중치로 삼아
if w.sum() > 0: # 가중 평균 = 예측 별점
print(MOVIES[m], (w @ R[seen, m]) / w.sum())