전처리된 데이터와 SVD 결과를 연다.
import joblib
svd = joblib.load('svd.pkl')
data = joblib.load('plot.pkl')
locals().update(data)
x_test
의 크기를 확인한다.
x_test.shape
(6978, 2000)
모든 문서 간의 코사인 유사도를 구한다.
from sklearn.metrics.pairwise import cosine_similarity
sim = cosine_similarity(x_test, x_test)
유사도 행렬의 크기를 확인한다.
sim.shape
(6978, 6978)
테스트 데이터의 2245번째 영화 제목을 확인한다.
title_test.iloc[2245]
'Batman'
유사도 행렬에서 2245번 행에서 각 값의 정렬된 순번을 확인한다.
import numpy as np
sim[2245]
array([0.04466556, 0.15782325, 0.01961735, ..., 0. , 0.04644104, 0.06694044])
rank = np.argsort(sim[2245])
rank
array([6243, 3327, 4030, ..., 3040, 3829, 2245], dtype=int64)
2245번을 제외하고 순위가 가장 높은 5개의 인덱스를 확인한다.
top5 = rank[-6:-1]
top5
array([3900, 5291, 687, 3040, 3829], dtype=int64)
'Batman'과 비슷한 내용의 영화 제목을 확인한다.
title_test.iloc[top5]
1277 Charlie Chan's Chance 9054 Lenny 17182 The Lego Batman Movie 4457 Forever Amber 23051 The Legend of Bruce Lee Name: Title, dtype: object
먼저 차원을 축소한다.
doc_emb = svd.transform(x_test)
유사도를 계산한다.
sim_emb = cosine_similarity(doc_emb, doc_emb)
rank = np.argsort(sim_emb[2245])
title_test.iloc[rank[-6:-1]]
21276 Tower Block 10952 Feds 20593 Death Machine 11381 Death Machine 21668 Unlocked Name: Title, dtype: object
doc_emb
에서 0번째 문서의 모든 값을 제곱하여 더하면 7.58 정도가 나온다.
sum(doc_emb[0] ** 2)
7.587460048291521
doc_emb
를 normalization 한다.
from sklearn.preprocessing import Normalizer
norm = Normalizer()
norm_emb = norm.fit_transform(doc_emb)
다시 계산해보면 1이 나온다.
sum(norm_emb[0] ** 2)
0.9999999999999999
다시 유사도를 구한다.
sim_norm = cosine_similarity(norm_emb, norm_emb)
원래의 유사도
sim_emb[0]
array([1. , 0.79345682, 0.96653332, ..., 0.91965926, 0.68183866, 0.69467919])
Normalization을 해도 유사도는 똑같다는 것을 알 수 있다.
sim_norm[0]
array([1. , 0.79345682, 0.96653332, ..., 0.91965926, 0.68183866, 0.69467919])
norm_emb
의 점곱을 구한다.
dp = norm_emb @ norm_emb.T
역시 유사도와 동일하다.
dp[0]
array([1. , 0.79345682, 0.96653332, ..., 0.91965926, 0.68183866, 0.69467919])