- 특정 사이트에 평점이 매겨지지 않은 식당의 평점을 협업필터링으로 예측해보았다.
- 가령 구글, 네이버 등엔 있는데, 카카오에는 평점이 없는 식당이 있을 때,
- 카카오에선 몇 점이 부여될까를 예측해보는 것이다.
- 표본 수(사이트 수)가 적어 제대로 된 예측결과가 나오진 않았지만 협업필터링 프로세스를 살펴볼 수 있었다.
import pandas as pd
import numpy as np
mango = pd.read_csv('mango_revise.csv')
kakao = pd.read_csv('kao_revise.csv')
google = pd.read_csv('google_stores.csv')
print(mango.shape)
print(kakao.shape)
print(google.shape)
(200, 7)
(94, 5)
(261, 6)
mango['Site'] = 'mango'
mango.head()
|
Title |
Point |
Review |
View |
Star |
Type |
Site |
0 |
비비비당 |
4.6 |
74 |
136578 |
3782 |
카페 디저트 오늘의 차 우전녹차 특말차 복분자 냉 오미자차 |
mango |
1 |
톤쇼우 |
4.6 |
38 |
26176 |
867 |
까스 요리 |
mango |
2 |
해목 |
4.5 |
157 |
324680 |
5477 |
정통 일식 일반 일식 특히츠마부시 민물장어덮밥 특카이센동 해산물덮밥 카이센동 해... |
mango |
3 |
신발원 |
4.5 |
166 |
259881 |
5903 |
딤섬 만두 |
mango |
4 |
할매국밥 |
4.5 |
88 |
128996 |
2812 |
탕 찌개 전골 |
mango |
kakao.head()
|
Title |
Point_kao |
Review_kao |
Type_kao |
Site_kao |
0 |
종각집 |
2.3 |
15건 |
국수 |
kakao |
1 |
다리집 |
2.4 |
123건 |
떡볶이 |
kakao |
2 |
백설대학 |
2.5 |
25건 |
분식 |
kakao |
3 |
이름난기장산곰장어 |
2.6 |
34건 |
장어 |
kakao |
4 |
마루팥빙수단팥죽 |
2.6 |
10건 |
디저트카페 |
kakao |
google.head()
|
Unnamed: 0 |
Title |
Point |
Review |
Type |
Site |
0 |
0 |
영진어묵 본점 |
5.0 |
6 |
식품가공업체 |
google |
1 |
1 |
다무치아 |
5.0 |
3 |
음식점 |
google |
2 |
2 |
부산식당 |
5.0 |
2 |
한식당 |
google |
3 |
3 |
산수맛집 |
5.0 |
1 |
음식점 |
google |
4 |
4 |
자성화맛집코다리네부산수정점 |
5.0 |
1 |
음식점 |
google |
사용자-아이템 평점 행렬로 변환
mango2 = mango2[['Site', 'Title', 'Point']]
kakao = kakao[['Site_kao', 'Title', 'Point_kao']]
google = google[['Site', 'Title', 'Point']]
mango2.head()
|
Site |
Title |
Point |
0 |
mango |
비비비당 |
4.6 |
1 |
mango |
톤쇼우 |
4.6 |
2 |
mango |
해목 |
4.5 |
3 |
mango |
신발원 |
4.5 |
4 |
mango |
할매국밥 |
4.5 |
kakao.head()
|
Site_kao |
Title |
Point_kao |
0 |
kakao |
종각집 |
2.3 |
1 |
kakao |
다리집 |
2.4 |
2 |
kakao |
백설대학 |
2.5 |
3 |
kakao |
이름난기장산곰장어 |
2.6 |
4 |
kakao |
마루팥빙수단팥죽 |
2.6 |
google.head()
|
Site |
Title |
Point |
0 |
google |
영진어묵 본점 |
5.0 |
1 |
google |
다무치아 |
5.0 |
2 |
google |
부산식당 |
5.0 |
3 |
google |
산수맛집 |
5.0 |
4 |
google |
자성화맛집코다리네부산수정점 |
5.0 |
kakao.rename(columns={'Site_kao':'Site', 'Point_kao':'Point'}, inplace=True)
kakao.head()
|
Site |
Title |
Point |
0 |
kakao |
종각집 |
2.3 |
1 |
kakao |
다리집 |
2.4 |
2 |
kakao |
백설대학 |
2.5 |
3 |
kakao |
이름난기장산곰장어 |
2.6 |
4 |
kakao |
마루팥빙수단팥죽 |
2.6 |
ratings = pd.concat([mango2, kakao, google]).reset_index(drop=True)
ratings
|
Site |
Title |
Point |
0 |
mango |
비비비당 |
4.6 |
1 |
mango |
톤쇼우 |
4.6 |
2 |
mango |
해목 |
4.5 |
3 |
mango |
신발원 |
4.5 |
4 |
mango |
할매국밥 |
4.5 |
... |
... |
... |
... |
550 |
google |
키친보이즈 |
3.0 |
551 |
google |
진맛집 |
2.7 |
552 |
google |
풍성한칼국수 |
2.5 |
553 |
google |
남천할매떡볶이 부산역점 |
2.4 |
554 |
google |
진식당 |
1.0 |
555 rows × 3 columns
ratings.rename(columns={'Site':'userId', 'Point':'rating'}, inplace=True)
ratings
|
userId |
Title |
rating |
0 |
mango |
비비비당 |
4.6 |
1 |
mango |
톤쇼우 |
4.6 |
2 |
mango |
해목 |
4.5 |
3 |
mango |
신발원 |
4.5 |
4 |
mango |
할매국밥 |
4.5 |
... |
... |
... |
... |
550 |
google |
키친보이즈 |
3.0 |
551 |
google |
진맛집 |
2.7 |
552 |
google |
풍성한칼국수 |
2.5 |
553 |
google |
남천할매떡볶이 부산역점 |
2.4 |
554 |
google |
진식당 |
1.0 |
555 rows × 3 columns
stores = mango[['Title', 'Type']]
stores
|
Title |
Type |
0 |
비비비당 |
카페 디저트 오늘의 차 우전녹차 특말차 복분자 냉 오미자차 |
1 |
톤쇼우 |
까스 요리 |
2 |
해목 |
정통 일식 일반 일식 특히츠마부시 민물장어덮밥 특카이센동 해산물덮밥 카이센동 해... |
3 |
신발원 |
딤섬 만두 |
4 |
할매국밥 |
탕 찌개 전골 |
... |
... |
... |
195 |
모던테이블 |
카페 디저트 |
196 |
화국반점 |
정통 중식 일반 중식 |
197 |
맛찬들왕소금구이 |
고기 요리 |
198 |
겐짱카레 |
돈부리 일본 카레 벤토 |
199 |
파크하얏트라운지 |
칵테일 와인 |
200 rows × 2 columns
ratings_matrix = ratings.pivot_table('rating', index='userId', columns='Title')
ratings_matrix
Title |
(주)대한민국맛집 |
(주)원조개금밀면 |
168도시락국{168계단도시락국} |
1984나폴리 |
303화덕 |
50년전통할매국밥 |
Cafe de 220VOLT |
LA북창동순두부 |
NTM부산 |
SANT EUSTACHIO IL CAFE |
... |
호찐빵 |
홍성방 |
홍성방 본관 |
홍콩반점0410 부산역점 |
화교대반점 |
화국반점 |
화국반점(華國飯店) |
황산밀면집 |
희와제과 |
흰여울비치 |
userId |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
google |
4.2 |
3.9 |
3.8 |
NaN |
NaN |
4.2 |
NaN |
3.8 |
4.0 |
NaN |
... |
NaN |
3.6 |
3.5 |
4.0 |
3.9 |
NaN |
3.6 |
3.9 |
NaN |
NaN |
kakao |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
3.6 |
... |
2.9 |
NaN |
NaN |
NaN |
NaN |
2.6 |
NaN |
NaN |
3.3 |
NaN |
mango |
NaN |
NaN |
NaN |
4.0 |
4.1 |
NaN |
4.0 |
NaN |
NaN |
3.9 |
... |
4.2 |
NaN |
NaN |
NaN |
NaN |
3.8 |
NaN |
NaN |
4.0 |
4.3 |
3 rows × 429 columns
ratings_stores = pd.merge(ratings, stores, on='Title')
ratings_stores = ratings_stores.drop_duplicates(['userId','Title']).reset_index(drop=True)
ratings_stores
ratings_stores
|
userId |
Title |
rating |
Type |
0 |
mango |
비비비당 |
4.6 |
카페 디저트 오늘의 차 우전녹차 특말차 복분자 냉 오미자차 |
1 |
kakao |
비비비당 |
3.7 |
카페 디저트 오늘의 차 우전녹차 특말차 복분자 냉 오미자차 |
2 |
mango |
톤쇼우 |
4.6 |
까스 요리 |
3 |
mango |
해목 |
4.5 |
정통 일식 일반 일식 특히츠마부시 민물장어덮밥 특카이센동 해산물덮밥 카이센동 해... |
4 |
kakao |
해목 |
3.9 |
정통 일식 일반 일식 특히츠마부시 민물장어덮밥 특카이센동 해산물덮밥 카이센동 해... |
... |
... |
... |
... |
... |
302 |
kakao |
화국반점 |
2.6 |
정통 중식 일반 중식 |
303 |
mango |
맛찬들왕소금구이 |
3.8 |
고기 요리 |
304 |
mango |
겐짱카레 |
3.8 |
돈부리 일본 카레 벤토 |
305 |
mango |
파크하얏트라운지 |
3.8 |
칵테일 와인 |
306 |
kakao |
파크하얏트라운지 |
4.7 |
칵테일 와인 |
307 rows × 4 columns
ratings_matrix = ratings_stores.pivot_table('rating', index='userId', columns='Title')
ratings_matrix
Title |
1984나폴리 |
303화덕 |
Cafe de 220VOLT |
SANT EUSTACHIO IL CAFE |
가내수공업양식당비토 |
거대갈비 |
거대곰탕 |
겐짱카레 |
고래사 |
고릴라브루잉 |
... |
해성막창집 |
해운대31cm해물칼국수 |
해운대밀면 |
해운대소문난암소갈비집 |
해운대원조할매국밥 |
호랑이젤라떡 |
호찐빵 |
화국반점 |
희와제과 |
흰여울비치 |
userId |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
google |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
... |
NaN |
NaN |
NaN |
NaN |
4.0 |
NaN |
NaN |
NaN |
NaN |
NaN |
kakao |
NaN |
NaN |
NaN |
3.6 |
4.4 |
NaN |
NaN |
NaN |
4.1 |
NaN |
... |
NaN |
NaN |
NaN |
3.0 |
NaN |
3.8 |
2.9 |
2.6 |
3.3 |
NaN |
mango |
4.0 |
4.1 |
4.0 |
3.9 |
3.8 |
4.3 |
4.3 |
3.8 |
4.0 |
4.0 |
... |
3.9 |
3.9 |
3.9 |
4.3 |
3.9 |
3.9 |
4.2 |
3.8 |
4.0 |
4.3 |
3 rows × 193 columns
ratings_matrix = ratings_matrix.fillna(0)
ratings_matrix
Title |
1984나폴리 |
303화덕 |
Cafe de 220VOLT |
SANT EUSTACHIO IL CAFE |
가내수공업양식당비토 |
거대갈비 |
거대곰탕 |
겐짱카레 |
고래사 |
고릴라브루잉 |
... |
해성막창집 |
해운대31cm해물칼국수 |
해운대밀면 |
해운대소문난암소갈비집 |
해운대원조할매국밥 |
호랑이젤라떡 |
호찐빵 |
화국반점 |
희와제과 |
흰여울비치 |
userId |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
google |
0.0 |
0.0 |
0.0 |
0.0 |
0.0 |
0.0 |
0.0 |
0.0 |
0.0 |
0.0 |
... |
0.0 |
0.0 |
0.0 |
0.0 |
4.0 |
0.0 |
0.0 |
0.0 |
0.0 |
0.0 |
kakao |
0.0 |
0.0 |
0.0 |
3.6 |
4.4 |
0.0 |
0.0 |
0.0 |
4.1 |
0.0 |
... |
0.0 |
0.0 |
0.0 |
3.0 |
0.0 |
3.8 |
2.9 |
2.6 |
3.3 |
0.0 |
mango |
4.0 |
4.1 |
4.0 |
3.9 |
3.8 |
4.3 |
4.3 |
3.8 |
4.0 |
4.0 |
... |
3.9 |
3.9 |
3.9 |
4.3 |
3.9 |
3.9 |
4.2 |
3.8 |
4.0 |
4.3 |
3 rows × 193 columns
-> 사용자-아이템 행렬이 만들어졌다.
ratings_matrix_T = ratings_matrix.transpose()
print(ratings_matrix_T.shape)
ratings_matrix_T.head(3)
(193, 3)
userId |
google |
kakao |
mango |
Title |
|
|
|
1984나폴리 |
0.0 |
0.0 |
4.0 |
303화덕 |
0.0 |
0.0 |
4.1 |
Cafe de 220VOLT |
0.0 |
0.0 |
4.0 |
from sklearn.metrics.pairwise import cosine_similarity
item_sim = cosine_similarity(ratings_matrix_T, ratings_matrix_T)
item_sim_df = pd.DataFrame(data=item_sim, index=ratings_matrix.columns,
columns=ratings_matrix.columns)
print(item_sim_df.shape)
item_sim_df.head(3)
(193, 193)
Title |
1984나폴리 |
303화덕 |
Cafe de 220VOLT |
SANT EUSTACHIO IL CAFE |
가내수공업양식당비토 |
거대갈비 |
거대곰탕 |
겐짱카레 |
고래사 |
고릴라브루잉 |
... |
해성막창집 |
해운대31cm해물칼국수 |
해운대밀면 |
해운대소문난암소갈비집 |
해운대원조할매국밥 |
호랑이젤라떡 |
호찐빵 |
화국반점 |
희와제과 |
흰여울비치 |
Title |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1984나폴리 |
1.0 |
1.0 |
1.0 |
0.734803 |
0.65362 |
1.0 |
1.0 |
1.0 |
0.698324 |
1.0 |
... |
1.0 |
1.0 |
1.0 |
0.820127 |
0.6981 |
0.71623 |
0.822897 |
0.825307 |
0.771373 |
1.0 |
303화덕 |
1.0 |
1.0 |
1.0 |
0.734803 |
0.65362 |
1.0 |
1.0 |
1.0 |
0.698324 |
1.0 |
... |
1.0 |
1.0 |
1.0 |
0.820127 |
0.6981 |
0.71623 |
0.822897 |
0.825307 |
0.771373 |
1.0 |
Cafe de 220VOLT |
1.0 |
1.0 |
1.0 |
0.734803 |
0.65362 |
1.0 |
1.0 |
1.0 |
0.698324 |
1.0 |
... |
1.0 |
1.0 |
1.0 |
0.820127 |
0.6981 |
0.71623 |
0.822897 |
0.825307 |
0.771373 |
1.0 |
3 rows × 193 columns
item_sim_df["고래사"].sort_values(ascending=False)[1:10]
Title
그라치에 1.000000
유일한식탁 1.000000
어바웃제이 1.000000
나이브브류어스 0.999934
베르크로스터스 0.999928
삼진어묵 0.999928
바로해장 0.999924
다케다야 0.999924
국이네낙지볶음 0.999737
Name: 고래사, dtype: float64
def predict_rating(ratings_arr, item_sim_arr):
ratings_pred = ratings_arr.dot(item_sim_arr)/ np.array([np.abs(item_sim_arr).sum(axis=1)])
return ratings_pred
ratings_pred = predict_rating(ratings_matrix.values , item_sim_df.values)
ratings_pred
array([[0.33567509, 0.33567509, 0.33567509, 0.35889099, 0.36302472,
0.33567509, 0.33567509, 0.33567509, 0.36074923, 0.33567509,
0.60970209, 0.36162415, 0.33567509, 0.33567509, 0.33567509,
0.36159255, 0.33567509, 0.36074923, 0.36162415, 0.35943587,
0.35741782, 0.33567509, 0.33567509, 0.62851446, 0.35803633,
0.35905444, 0.36116826, 0.56840223, 0.35756435, 0.36165734,
0.35939193, 0.35294904, 0.35814517, 0.36030291, 0.35487799,
0.33567509, 0.35896125, 0.33567509, 0.3598722 , 0.35691247,
0.58276719, 0.35355391, 0.35988228, 0.35936824, 0.33567509,
0.62869203, 0.35845565, 0.33567509, 0.33567509, 0.36209664,
0.35694639, 0.58349083, 0.33567509, 0.33567509, 0.35899382,
0.56235501, 0.35371873, 0.33567509, 0.35741782, 0.35986162,
0.33567509, 0.33567509, 0.36501339, 0.33567509, 0.36162415,
0.33567509, 0.33567509, 0.33567509, 0.33567509, 0.36295771,
0.33567509, 0.33567509, 0.33567509, 0.35896125, 0.33567509,
0.36253006, 0.36030291, 0.35769672, 0.36209664, 0.35708585,
0.35280292, 0.57801209, 0.33567509, 0.33567509, 0.33567509,
0.36118961, 0.33567509, 0.36295771, 0.33567509, 0.33567509,
0.59219754, 0.36402742, 0.35889099, 0.61496548, 0.33567509,
0.3598919 , 0.35659007, 0.33567509, 0.33567509, 0.33567509,
0.33567509, 0.33567509, 0.36118961, 0.33567509, 0.33567509,
0.33567509, 0.33567509, 0.35936824, 0.33567509, 0.33567509,
0.33567509, 0.35700144, 0.36201139, 0.33567509, 0.62834575,
0.36205298, 0.33567509, 0.35741782, 0.35781688, 0.61496548,
0.33567509, 0.33567509, 0.33567509, 0.33567509, 0.33567509,
0.33567509, 0.35840693, 0.3607606 , 0.3559971 , 0.59463007,
0.33567509, 0.35650285, 0.33567509, 0.35983884, 0.33567509,
0.33567509, 0.64052246, 0.33567509, 0.35427113, 0.55738783,
0.33567509, 0.3607606 , 0.35691247, 0.33567509, 0.33567509,
0.35371873, 0.35947577, 0.35814517, 0.35854593, 0.63491314,
0.33567509, 0.33567509, 0.35167319, 0.33567509, 0.58303518,
0.35481525, 0.33567509, 0.33567509, 0.33567509, 0.33567509,
0.33567509, 0.35791593, 0.33567509, 0.35775822, 0.35650285,
0.36337972, 0.35896125, 0.33567509, 0.35896125, 0.33567509,
0.36430377, 0.33567509, 0.56154835, 0.33567509, 0.33567509,
0.33567509, 0.33567509, 0.33567509, 0.33567509, 0.33567509,
0.33567509, 0.58200684, 0.56799497, 0.33567509, 0.33567509,
0.33567509, 0.3543857 , 0.62851446, 0.35983884, 0.35423195,
0.35409759, 0.35700144, 0.33567509],
[1.50234426, 1.50234426, 1.50234426, 2.08292339, 2.18629908,
1.50234426, 1.50234426, 1.50234426, 2.12939415, 1.50234426,
1.53210213, 2.15127393, 1.50234426, 1.50234426, 1.50234426,
2.15048367, 1.50234426, 2.12939415, 2.15127393, 2.09654983,
2.04608281, 1.50234426, 1.50234426, 1.53414505, 2.06155035,
2.0870111 , 2.13987315, 2.02845143, 2.0497472 , 2.1521039 ,
2.09545085, 1.93432825, 2.06427225, 2.11823257, 1.98256697,
1.50234426, 2.08468053, 1.50234426, 2.1074614 , 2.03344496,
2.09529069, 1.94945468, 2.10771347, 2.09485849, 1.50234426,
1.53416433, 2.07203648, 1.50234426, 1.50234426, 2.16308989,
2.0342932 , 1.97473892, 1.50234426, 1.50234426, 2.08549511,
2.05692442, 1.95357654, 1.50234426, 2.04608281, 2.10719694,
1.50234426, 1.50234426, 2.23603143, 1.50234426, 2.15127393,
1.50234426, 1.50234426, 1.50234426, 1.50234426, 2.18462344,
1.50234426, 1.50234426, 1.50234426, 2.08468053, 1.50234426,
2.17392876, 2.11823257, 2.05305736, 2.16308989, 2.03778096,
1.93067398, 2.03793209, 1.50234426, 1.50234426, 1.50234426,
2.14040695, 1.50234426, 2.18462344, 1.50234426, 1.50234426,
2.0594169 , 2.21137438, 2.08292339, 1.5326737 , 1.50234426,
2.10795402, 2.0253826 , 1.50234426, 1.50234426, 1.50234426,
1.50234426, 1.50234426, 2.14040695, 1.50234426, 1.50234426,
1.50234426, 1.50234426, 2.09485849, 1.50234426, 1.50234426,
1.50234426, 2.03566985, 2.16095793, 1.50234426, 1.53412673,
2.16199796, 1.50234426, 2.04608281, 2.05606229, 1.5326737 ,
1.50234426, 1.50234426, 1.50234426, 1.50234426, 1.50234426,
1.50234426, 2.0708182 , 2.12967838, 2.01055359, 2.0830747 ,
1.50234426, 2.02320139, 1.50234426, 2.10662706, 1.50234426,
1.50234426, 1.53544906, 1.50234426, 1.96739086, 2.04216679,
1.50234426, 2.12967838, 2.03344496, 1.50234426, 1.50234426,
1.95357654, 2.09754766, 2.06427225, 2.07429439, 1.53483991,
1.50234426, 1.50234426, 1.90242192, 1.50234426, 2.09501473,
1.98099798, 1.50234426, 1.50234426, 1.50234426, 1.50234426,
1.50234426, 2.05853926, 1.50234426, 2.05459528, 2.02320139,
2.19517679, 2.08468053, 1.50234426, 2.08468053, 1.50234426,
2.21828542, 1.50234426, 2.06719049, 1.50234426, 1.50234426,
1.50234426, 1.50234426, 1.50234426, 1.50234426, 1.50234426,
1.50234426, 2.05096151, 2.04773167, 1.50234426, 1.50234426,
1.50234426, 1.97025585, 1.53414505, 2.10662706, 1.96641105,
1.96305105, 2.03566985, 1.50234426],
[4.06516071, 4.06516071, 4.06516071, 4.06331156, 4.06298231,
4.06516071, 4.06516071, 4.06516071, 4.06316355, 4.06516071,
4.06437318, 4.06309386, 4.06516071, 4.06516071, 4.06516071,
4.06309638, 4.06516071, 4.06316355, 4.06309386, 4.06326816,
4.0634289 , 4.06516071, 4.06516071, 4.06431912, 4.06337963,
4.06329854, 4.06313018, 4.06294756, 4.06341723, 4.06309122,
4.06327166, 4.06378484, 4.06337097, 4.0631991 , 4.0636312 ,
4.06516071, 4.06330596, 4.06516071, 4.06323341, 4.06346915,
4.06270499, 4.06373666, 4.0632326 , 4.06327355, 4.06516071,
4.06431861, 4.06334624, 4.06516071, 4.06516071, 4.06305623,
4.06346645, 4.06307487, 4.06516071, 4.06516071, 4.06330337,
4.06287512, 4.06372353, 4.06516071, 4.0634289 , 4.06323425,
4.06516071, 4.06516071, 4.06282391, 4.06516071, 4.06309386,
4.06516071, 4.06516071, 4.06516071, 4.06516071, 4.06298765,
4.06516071, 4.06516071, 4.06516071, 4.06330596, 4.06516071,
4.06302171, 4.0631991 , 4.06340668, 4.06305623, 4.06345534,
4.06379648, 4.06289393, 4.06516071, 4.06516071, 4.06516071,
4.06312848, 4.06516071, 4.06298765, 4.06516071, 4.06516071,
4.06279166, 4.06290244, 4.06331156, 4.06435806, 4.06516071,
4.06323184, 4.06349483, 4.06516071, 4.06516071, 4.06516071,
4.06516071, 4.06516071, 4.06312848, 4.06516071, 4.06516071,
4.06516071, 4.06516071, 4.06327355, 4.06516071, 4.06516071,
4.06516071, 4.06346206, 4.06306302, 4.06516071, 4.0643196 ,
4.06305971, 4.06516071, 4.0634289 , 4.06339711, 4.06435806,
4.06516071, 4.06516071, 4.06516071, 4.06516071, 4.06516071,
4.06516071, 4.06335012, 4.06316265, 4.06354206, 4.06271254,
4.06516071, 4.06350178, 4.06516071, 4.06323606, 4.06516071,
4.06516071, 4.06428461, 4.06516071, 4.06367953, 4.06293324,
4.06516071, 4.06316265, 4.06346915, 4.06516071, 4.06516071,
4.06372353, 4.06326498, 4.06337097, 4.06333904, 4.06430073,
4.06516071, 4.06516071, 4.06388646, 4.06516071, 4.06270516,
4.06363619, 4.06516071, 4.06516071, 4.06516071, 4.06516071,
4.06516071, 4.06338923, 4.06516071, 4.06340179, 4.06350178,
4.06295403, 4.06330596, 4.06516071, 4.06330596, 4.06516071,
4.06288043, 4.06516071, 4.06284552, 4.06516071, 4.06516071,
4.06516071, 4.06516071, 4.06516071, 4.06516071, 4.06516071,
4.06516071, 4.06284361, 4.06288915, 4.06516071, 4.06516071,
4.06516071, 4.06367041, 4.06431912, 4.06323606, 4.06368265,
4.06369336, 4.06346206, 4.06516071]])
ratings_pred_matrix = pd.DataFrame(data=ratings_pred, index= ratings_matrix.index,
columns = ratings_matrix.columns)
print(ratings_pred_matrix.shape)
ratings_pred_matrix.head(10)
(3, 193)
Title |
1984나폴리 |
303화덕 |
Cafe de 220VOLT |
SANT EUSTACHIO IL CAFE |
가내수공업양식당비토 |
거대갈비 |
거대곰탕 |
겐짱카레 |
고래사 |
고릴라브루잉 |
... |
해성막창집 |
해운대31cm해물칼국수 |
해운대밀면 |
해운대소문난암소갈비집 |
해운대원조할매국밥 |
호랑이젤라떡 |
호찐빵 |
화국반점 |
희와제과 |
흰여울비치 |
userId |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
google |
0.335675 |
0.335675 |
0.335675 |
0.358891 |
0.363025 |
0.335675 |
0.335675 |
0.335675 |
0.360749 |
0.335675 |
... |
0.335675 |
0.335675 |
0.335675 |
0.354386 |
0.628514 |
0.359839 |
0.354232 |
0.354098 |
0.357001 |
0.335675 |
kakao |
1.502344 |
1.502344 |
1.502344 |
2.082923 |
2.186299 |
1.502344 |
1.502344 |
1.502344 |
2.129394 |
1.502344 |
... |
1.502344 |
1.502344 |
1.502344 |
1.970256 |
1.534145 |
2.106627 |
1.966411 |
1.963051 |
2.035670 |
1.502344 |
mango |
4.065161 |
4.065161 |
4.065161 |
4.063312 |
4.062982 |
4.065161 |
4.065161 |
4.065161 |
4.063164 |
4.065161 |
... |
4.065161 |
4.065161 |
4.065161 |
4.063670 |
4.064319 |
4.063236 |
4.063683 |
4.063693 |
4.063462 |
4.065161 |
3 rows × 193 columns
from sklearn.metrics import mean_squared_error
def get_mse(pred, actual):
pred = pred[actual.nonzero()].flatten()
actual = actual[actual.nonzero()].flatten()
return mean_squared_error(pred, actual)
print('아이템 기반 모든 인접 이웃 MSE: ', get_mse(ratings_pred, ratings_matrix.values ))
아이템 기반 모든 인접 이웃 MSE: 1.755633561085019
top-n 유사도를 가진 데이터들에 대해서만 예측 평점 계산
def predict_rating_topsim(ratings_arr, item_sim_arr, n=20):
pred = np.zeros(ratings_arr.shape)
for col in range(ratings_arr.shape[1]):
top_n_items = [np.argsort(item_sim_arr[:, col])[:-n-1:-1]]
for row in range(ratings_arr.shape[0]):
pred[row, col] = item_sim_arr[col, :][top_n_items].dot(ratings_arr[row, :][top_n_items].T)
pred[row, col] /= np.sum(np.abs(item_sim_arr[col, :][top_n_items]))
return pred
ratings_pred = predict_rating_topsim(ratings_matrix.values , item_sim_df.values, n=20)
print('아이템 기반 인접 TOP-20 이웃 MSE: ', get_mse(ratings_pred, ratings_matrix.values ))
ratings_pred_matrix = pd.DataFrame(data=ratings_pred, index= ratings_matrix.index,
columns = ratings_matrix.columns)
아이템 기반 인접 TOP-20 이웃 MSE: 0.10567727070048756
C:\Users\dyj42\AppData\Local\Temp/ipykernel_9080/2382315358.py:11: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.
pred[row, col] = item_sim_arr[col, :][top_n_items].dot(ratings_arr[row, :][top_n_items].T)
C:\Users\dyj42\AppData\Local\Temp/ipykernel_9080/2382315358.py:12: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.
pred[row, col] /= np.sum(np.abs(item_sim_arr[col, :][top_n_items]))
user_rating_id = ratings_matrix.loc['kakao']
user_rating_id[user_rating_id > 0].sort_values(ascending=False)[:5]
Title
모루비 5.0
봉샌드 5.0
파크하얏트라운지 4.7
쿠루미과자점 4.6
문화공감 수정 4.5
Name: kakao, dtype: float64
평점이 매겨지지 않은 식당의 평점을 예측해보자
def get_unseen_movies(ratings_matrix, userId):
user_rating = ratings_matrix.loc[userId,:]
already_seen = user_rating[ user_rating > 0].index.tolist()
movies_list = ratings_matrix.columns.tolist()
unseen_list = [ movie for movie in movies_list if movie not in already_seen]
return unseen_list
def recomm_movie_by_userid(pred_df, userId, unseen_list, top_n=10):
recomm_movies = pred_df.loc[userId, unseen_list].sort_values(ascending=False)[:top_n]
return recomm_movies
unseen_list = get_unseen_movies(ratings_matrix, 'kakao')
recomm_movies = recomm_movie_by_userid(ratings_pred_matrix, 'kakao', unseen_list, top_n=5)
recomm_movies = pd.DataFrame(data=recomm_movies.values,index=recomm_movies.index, columns=['pred_score'])
recomm_movies
|
pred_score |
Title |
|
고옥 |
1.822692 |
부산족발 |
1.822584 |
신창국밥 |
1.822584 |
스완양분식 |
1.822319 |
기장손칼국수 |
1.822315 |