import numpy as np
from numpy import linalg as la
def loadExData():
return[[0, 0, 0, 2, 2],
[0, 0, 0, 3, 3],
[0, 0, 0, 1, 1],
[1, 1, 1, 0, 0],
[2, 2, 2, 0, 0],
[5, 5, 5, 0, 0],
[1, 1, 1, 0, 0]]
def loadExData2():
return[[0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5],
[0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 3],
[0, 0, 0, 0, 4, 0, 0, 1, 0, 4, 0],
[3, 3, 4, 0, 0, 0, 0, 2, 2, 0, 0],
[5, 4, 5, 0, 0, 0, 0, 5, 5, 0, 0],
[0, 0, 0, 0, 5, 0, 1, 0, 0, 5, 0],
[4, 3, 4, 0, 0, 0, 0, 5, 5, 0, 1],
[0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 4],
[0, 0, 0, 2, 0, 2, 5, 0, 0, 1, 2],
[0, 0, 0, 0, 5, 0, 0, 0, 0, 4, 0],
[1, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0]]
def eulidSim(inA, inB): #欧式距离
return 1 / (1 + la.norm(inA - inB))
def pearsSim(inA, inB):
if len(inA) < 3:
return 1#??
return 1 / (1 + la.norm(inA - inB))
def cosSim(inA, inB):
num = float(inA.T * inB)
denom = la.norm(inA) * la.norm(inB)
return 0.5 + 0.5*(num / denom)
#基于物品相似度的推荐系统
def standEst(dataMat, user, simMeas, item):
n = np.shape(dataMat)[1]
simTotal = 0
ratSimTotal = 0
for j in range(n):
userRating = dataMat[user, j]
if userRating == 0 or j==item:
continue
#https://blog.csdn.net/jningwei/article/details/78651535
overLap = np.nonzero(np.logical_and(dataMat[:, item] > 0,
dataMat[:, j] > 0))[0]#必须都有评分记录
if len(overLap) == 0:
similarity = 0
else:
similarity = simMeas(dataMat[overLap, item],
dataMat[overLap, j])
simTotal += similarity
ratSimTotal += similarity * userRating
if simTotal == 0:
return 0
return ratSimTotal / simTotal
def svdEst(dataMat, user, simMeas, item):
n = np.shape(dataMat)[1]
simTotal = 0.0; ratSimTotal = 0.0
U,Sigma,VT = la.svd(dataMat)
Sig4 = np.mat(np.eye(4)*Sigma[:4])
xformedItems = dataMat.T * U[:,:4] * Sig4.I
for j in range(n):
userRating = dataMat[user,j]
if userRating == 0 or j==item:
continue
similarity = simMeas(xformedItems[item,:].T,\
xformedItems[j,:].T)
simTotal += similarity
ratSimTotal += similarity * userRating
if simTotal == 0:
return 0
return ratSimTotal/simTotal
def recommend(dataMat, user, N = 3, simMeas = cosSim, estMethod = standEst):
unratedItems = np.nonzero(dataMat[user,:] == 0)[1]
if len(unratedItems) == 0:
return 'you rated everything'
itemScores = []
for item in unratedItems:
estimatedScore = estMethod(dataMat, user, simMeas, item)
itemScores.append((item, estimatedScore))
return sorted(itemScores, key = lambda jj: jj[1], reverse = True)[:N]
if __name__ == '__main__':
myMat = np.mat(loadExData())
myMat[0, 1] = myMat[0, 0] = myMat[1, 0] = myMat[2, 0] = 4
myMat[3, 3] = 2
res1 = recommend(myMat, 2)
res2 =recommend(myMat, 2, estMethod = svdEst)