본 포스팅에선 실습 시 사용했던 파이썬 기본 추천 알고리즘 코드를 공유합니다.
# 높은 인기도, 평저을 갖는 item을 추천 # 모두에게 동일한 item이 추천된다.
In [1]:
ratings = { 'Dave': {'달콤한인생':5, '범죄도시':3, '샤인':3}, 'David': {'달콤한인생':5, '범죄도시':1, '샤인':4}, 'Alex': {'달콤한인생':0, '범죄도시':4, '샤인':5}, 'Andy': {'달콤한인생':2, '범죄도시':1, '샤인':5}, }
In [4]:
#평점이 가장 높은 두 영화 출력하기 movie_dict = dict() for rating in ratings: for movie in ratings[rating].keys(): if movie not in movie_dict: movie_dict[movie] = ratings[rating][movie] else: movie_dict[movie] = (movie_dict[movie]+ratings[rating][movie]) for movie in ratings[rating].keys(): movie_dict[movie] = movie_dict[movie] / 4 import operator sorted_x = sorted(movie_dict.items(), key=operator.itemgetter(1), reverse=True) print(sorted_x[:2])
[('샤인', 4.25), ('달콤한인생', 3.0)]
In [ ]:
#Collaborative Filtering #1. 데이터 구성 : 사용자가 입력한 선호도를 평가하여 사용자 항목 선호도 행렬을 만든다 #2. 유사도 계산 : 1단계에서 만들어진 행렬을 사용하여 사용자들 간의 유사도를 계산한다. #3. 예측 값 계산 및 추천 목록 생성 # : 사용자들 간의 유사도를 바탕으로 모든 항목에 대해 예측값을 계산하고 # 높은 예측값을 갖는 상위 N개의 추천 목록을 생성한다.
In [5]:
ratings.get('Dave')
Out[5]:
{'달콤한인생': 5, '범죄도시': 3, '샤인': 3}
In [6]:
ratings.get('Dave').get('샤인')
Out[6]:
3
In [7]:
#유사도를 구한다.(피타고라스 공식을 사용해 거리계산) import math def sim(i,j): return math.sqrt(pow(i,2)+pow(j,2))
In [11]:
var1 = ratings['Alex']['범죄도시'] - ratings['Andy']['범죄도시']
In [12]:
var1
Out[12]:
3
In [13]:
var2 = ratings['Alex']['샤인'] - ratings['Andy']['샤인']
In [14]:
var2
Out[14]:
0
In [15]:
sim(var1,var2)
Out[15]:
3.0
In [18]:
#Alex가 평가한 범죄도시, 샤인을 모두 평가한 사용자와 모두 거리 구하기 for i in ratings: if i!='Alex': num1 = ratings.get('Alex').get('범죄도시') - ratings.get(i).get('범죄도시') num2 = ratings.get('Alex').get('샤인') - ratings.get(i).get('샤인') print(i, ": ", sim(num1,num2))
Dave : 2.23606797749979 David : 3.1622776601683795 Andy : 3.0
In [20]:
#정규화를 통해 유사도 범위를 0과 1사이로 가두고, 1에 가까울수록 유사도가 높아진다. for i in ratings: if i != 'Alex': num1 = ratings.get('Alex').get('범죄도시') - ratings.get(i).get('범죄도시') num2 = ratings.get('Alex').get('샤인') - ratings.get(i).get("샤인") print(i," : ",1/(1+sim(num1,num2)))
Dave : 0.3090169943749474 David : 0.2402530733520421 Andy : 0.25
In [22]:
#DAVE가 평가한 범죄도시와 샤인 모두 평가한 사용자와의 거리를 구해서, 가장 DAVE와 유사한 사용자 구하기 for i in ratings: if i!='Dave': num1 = ratings.get('Dave').get('범죄도시') - ratings.get(i).get('범죄도시') num2 = ratings.get('Dave').get('샤인') - ratings.get(i).get('샤인') print(i," : ",1/(1+sim(num1,num2)))
David : 0.3090169943749474 Alex : 0.3090169943749474 Andy : 0.2612038749637414