Python 주제 분석


수강중

11. 유사도 실습

전처리된 데이터와 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

Normalization

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])