Skip to content

Instantly share code, notes, and snippets.

@evfro
Last active June 9, 2020 20:20
Show Gist options
  • Save evfro/c6ec2b954adfff6aaa356f9b3124b1d2 to your computer and use it in GitHub Desktop.
Save evfro/c6ec2b954adfff6aaa356f9b3124b1d2 to your computer and use it in GitHub Desktop.
HybridSVD example
from scipy.sparse import csr_matrix
import scipy as sp
import numpy as np
from scipy.sparse.linalg import spsolve_triangular
# rating matrix
a = np.array([[1, 0, 1, 1, 0],
[1, 1, 0, 1, 0],
[1, 0, 0, 1, 0]])
# vector of a new user's preferences
p = np.array([1, 0, 0, 1, 1])
# ========== Standard Model ==========
rank = 2
u, s, vt = np.linalg.svd(a, full_matrices=False)
v = vt.T[:, :rank]
# recommendations for the user with standard folding-in approach
recs = p.dot(v).dot(v.T)
recs
# output: [ 0.8904344 , 0.31234752, 0.31234752, 0.8904344 , 0. ]
# ========== Hybrid Model ==========
d = 0.5 # off-diagonal similarity factor
# item similarity matrix
# non-zero off-diagonal values denote similarity between items 3 and 5
s = np.array([[1, 0, 0, 0, 0],
[0, 1, 0, 0, 0],
[0, 0, 1, 0, d],
[0, 0, 0, 1, 0],
[0, 0, d, 0 ,1]])
# finding Cholesky factors
L = np.linalg.cholesky(s)
u2, s2, v2 = np.linalg.svd(a.dot(L), full_matrices=False)
v2 = v2.T[:, :rank]
# preparing for hybrid folding-in calculation
lv = L.dot(v2)
rv = spsolve_triangular(csr_matrix(L.T), v2, lower=False)
# recommendations for the user with hybrid model
recs2 = p.dot(lv).dot(rv.T)
recs2
# output: [0.96852129, 0.08973892, 0.58973892, 0.96852129, 0. ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment