import numpy as np
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity
ratings_dict = {
'User1': [5, 3, np.nan, 1],
'User2': [4, np.nan, np.nan, 1],
'User3': [1, 1, np.nan, 5],
'User4': [1, np.nan, 5, 4],
'User5': [np.nan, 1, 5, 4]
}
df = pd.DataFrame(ratings_dict, index=['Item1', 'Item2', 'Item3', 'Item4']).T
print("평점 데이터프레임:\n", df)
NaN은 아직 평점이 없는 항목 출력
Item1 Item2 Item3 Item4
User1 5.0 3.0 NaN 1.0
User2 4.0 NaN NaN 1.0
User3 1.0 1.0 NaN 5.0
User4 1.0 NaN 5.0 4.0
User5 NaN 1.0 5.0 4.0
rating_matrix = df.fillna(0).to_numpy()
user_similarity = cosine_similarity(rating_matrix)
fillna(0)으로 결측치는 0 처리 def predict_rating(user_index, item_index, k=2):
sim_scores = user_similarity[user_index]
# 현재 사용자와 다른 사용자 간 유사도 벡터
neighbor_indices = [i for i in range(len(df))
if not np.isnan(df.iloc[i, item_index]) and i != user_index]
# 해당 아이템에 대해 실제로 평가를 남긴 이웃 사용자 인덱스 추출
neighbors = sorted(neighbor_indices, key=lambda i: sim_scores[i], reverse=True)[:k]
# 유사도가 높은 순으로 K명의 이웃 추출
numerator = 0
denominator = 0
for neighbor in neighbors:
sim = sim_scores[neighbor]
rating = df.iloc[neighbor, item_index]
numerator += sim * rating
denominator += sim
if denominator == 0:
return np.nan # 유사한 이웃이 없을 경우 NaN 반환
return round(numerator / denominator, 2)
user_similarity[user_index] 통해 대상 사용자와 다른 사용자 간 유사도 추출 neighbor_indices로 해당 아이템에 평점을 남긴 사용자 중 자기 자신 제외 neighbors로 유사도 높은 K명의 사용자 선택 user_idx = df.index.get_loc("User2") # User2 인덱스 찾기
item_idx = df.columns.get_loc("Item2") # Item2 인덱스 찾기
predict_result = predict_rating(user_idx, item_idx, k=2)
print(f'User2의 Item2에 대한 예측 평점: {predict_result}')
출력
User2의 Item2에 대한 예측 평점: 2.34
| 항목 | 내용 |
|---|---|
| 목적 | 평가하지 않은 항목의 평점을 예측하고 추천 시스템에 활용 |
| 이유 | 협업 필터링 핵심은 '비슷한 이웃의 의견 참고'이며 이는 KNN 개념과 동일 |
| 방식 | 1) 평점 행렬 생성 → 2) 코사인 유사도 계산 → 3) 이웃 선택 → 4) 가중 평균으로 예측 |
| 활용 분야 | 넷플릭스, 왓챠, 유튜브, 쿠팡, 무신사 등 추천 시스템 전반 |