svd推荐

#准备工作,调入相关的库

import numpyas np

from numpyimport linalgas la

import pandasas pd

#第1部分:加载测试数据集,形成loadExData()函数。

#用户-物品矩阵行代表用户user,列代表物品item,其中的值代表用户对物品的打分。该矩阵存放在评分.csv文件中,使用前需要加载。由movie数据集生成该评分.csv的具体实现见6.9节。

#行:代表用户

#列:代表电影

#值:代表用户对电影的评分,0表示未评分

#记载数据集

def loadExData():

return np.array(pd.read_csv("评分.csv",sep=",",header=None))

#第2部分:计算相似度,形成ecludSim()函数、pearsSim()函数、cosSim()函数。

'''

以下是三种计算相似度的算法,分别是欧式距离、皮尔逊相关系数和余弦相似度

注意三种计算方式的参数X和Y都是采用一维数组。

'''

# 利用欧式距离计算相似度 0~1之间

def ecludSim(X, Y):

return 1.0 / (1.0 + la.norm(X - Y))# linalg.norm()是向量A的模(2阶范数)计算方法,

#1/(1+ norm)表示将相似度归一到0与1之间。

# 利用皮尔逊相关系数计算相似度 0~1之间

def pearsSim(X, Y):

if len(X) <3:return 1.0

    return 0.5 +0.5 * np.corrcoef(X, Y,rowvar=1)[0][1]

# corrcoef()表示皮尔逊相关系数的计算方法

#corrcoef() 在 -1 ~ 1之间,0.5 + 0.5*corrcoef()把其取值范围归一化到0到1之间。

#利用余弦相似度计算相似度0~1之间

def cosSim(X, Y):

XY =float(X.dot(Y))# 向量 X*Y

    XYnorm= la.norm(X) * la.norm(Y)#向量A的模(2阶范数) * 向量B的模(2阶范数)

    return 0.5 +0.5 * (XY / XYnorm)#向量A 与 向量B 的夹角余弦 A*B / (||A||*||B||)

#范围在-1~1 ,将相似度归一到0与1之间。

#第3部分:对矩阵降维处理,形成svd_item()函数。

#本部分首先确定要选取的奇异值个数,然后进行降维计算矩阵的近似值。

#1.计算选取的奇异值数目k值,形成SigmaPct函数。

'''

按照前k个奇异值的平方和占总奇异值的平方和的百分比percentage确定k的值。

后续计算SVD时需要将item原始矩阵降维

'''

def SigmaPct(sigma, percentage):

sum_sigma =sum(sigma **2)

sum_sigma1 = sum_sigma * percentage# 求所有奇异值sigma的平方和的百分比

    sum_sigma2 =0  # sum_sigma2是前k个奇异值的平方和

    k =0  # 计数

    for iin sigma:

sum_sigma2 += i **2  # 计算每个奇异值的平方

        k +=1  # 计数增加1

        if sum_sigma2 >= sum_sigma1:# 判断是否已达到percentage

            return k

#2.降维处理,形成svd_item()函数。

#(1)调用SigmaPct()函数,确定k值。

#(2)利用 ,求出降维后的 。

# 返回降维的物品数据

def svd_item(data, percentage):

n = np.shape(data)[1]# 物品种类数据

    U, s, VT = la.svd(data)# 数据集进行奇异值分解,返回的s为对角线上的值

    k = SigmaPct(s, percentage)# 确定了k的值,前k个已经包含了percentage的能力

    Sigma = np.eye(k) * s[:k]# 构建对角矩阵

# 将数据转换到k维空间(低维),构建转换后的物品

    FormedItems = data.T.dot(U[:, :k].dot(la.inv(Sigma)))

return FormedItems# 返回降维的物品数据

#第4部分:在已经降维的数据中,对用户未打分的一个物品进行评分预测,形成svd_predict()函数。

'''

参数包含:数据矩阵、用户编号、物品编号和奇异值占比的阈值,

数据矩阵的行对应用户,列对应物品

函数的作用:基于item的相似性对用户未评过分的物品进行预测评分

'''

def svd_predict(data, user, simMeas, FormedItems, item,percentage):

n = np.shape(data)[1]# 得到数据集中的物品种类数据

    Totalsim =0.0  # 初始化两个评分值

    TotalratSim =0.0  # 相似性总和变量初始化

# 遍历给定的用户行中的每个物品

# 即(对用户评过分的物品进行遍历,并将它与其他物品进行比较),计算相似度

    for jin range(n):

# 得到给定的用户user对商品的评分

        Rating_user = data[user, j]

# 只对评价过的商品和不是自己的商品求相似度

        if Rating_user !=0 and j != item:

# 计算 svd转换过后矩阵的相似度,物品item与物品j之间的相似度

# 相似度的计算方法也会作为一个参数传递给该函数

            Similarity = simMeas(FormedItems[item, :], FormedItems[j, :])

Totalsim += Similarity# 对相似度不断累加求和

            TotalratSim += Similarity * Rating_user# 对相似度及对应评分值乘积求和

    if Totalsim ==0:

return 0

    else:

return TotalratSim / Totalsim# 得到对物品的预测评分,返回后用于分数的排序

#第5部分:产生前N个评分值高的物品,返回物品编号以及预测评分值,形成recommend()函数。

'''

函数recommend()产生预测评分最高的N个推荐结果,默认返回5个;

参数包括:数据矩阵、用户编号、相似度衡量的方法、预测评分的方法、以及奇异值占比的阈值。

'''

def recommend(data, user, FormedItems, N, simMeas, percentage):

# 为未评价的物品建立一个用户未评分item的列表

    unratedItems = np.array(np.nonzero(data[user, :] ==0))[0]

if len(unratedItems) ==0:

return "你已评价完所有物品"  # 若都已经评过分,则退出

    Scoresitem = []

for itemin unratedItems:# 对未评分的物品item,都计算其预测评分

# 计算评价值

        estimatedScore = svd_predict(data, user, simMeas, FormedItems, item, percentage)

Scoresitem.append((item, estimatedScore))# 记录商品及评价值

    Scoresitem =sorted(Scoresitem,key=lambda x: x[1],reverse=True)# 按照得分逆序排序

    return Scoresitem[:N]# 返回前N个评分的物品名

#第6部分:对指定用户进行商品推荐,形成recommend_predict函数。

def recommend_predict():

user_item = loadExData()

percentage=0.9 #奇异值平方和的百分比

    n=4  #推荐个数

    FormedItems = svd_item(user_item, percentage)# 获得SVD降维后的物品

    print('利用余弦相似度计算距离,进行的奇异值分解推荐:')

simMeas=cosSim#相似度

    for iin range(0,np.shape(user_item)[0]):

print("对第",i,"个用户进行推荐:")

print("按相似度推荐的物品编号为:", recommend(user_item, i, FormedItems, n, simMeas, percentage))

print('利用欧式距离相似度计算距离,进行的奇异值分解推荐:')

simMeas = ecludSim

for iin range(0,np.shape(mymat1)[0]):

print("对第",i,"个用户进行推荐:")

print("按相似度推荐的物品编号为:", recommend(user_item, i, FormedItems, n, simMeas, percentage))

print('利用皮尔逊相似度计算距离,进行的奇异值分解推荐:')

simMeas= pearsSim

for iin range(0,np.shape(mymat1)[0]):

print("对第",i,"个用户进行推荐:")

print("按相似度推荐的物品编号为:", recommend(user_item, user, FormedItems, n, simMeas, percentage))

#第7部分:调用recommend_predict()函数,获得结果。

#主程序

recommend_predict()

其他文章:协同过滤

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355

推荐阅读更多精彩内容