推荐系统协同过滤-python实现(基于用户的协同过滤算法,基于物品的协同过滤算法,附数据集)

本文介绍了如何使用Python实现基于用户和物品的协同过滤算法,包括基于Jaccard和余弦相似度的用户相似度计算,以及改进后的物品相似度计算方法。实验数据来自DBLP公开数据集,详细展示了从数据预处理到推荐生成的完整过程。
摘要由CSDN通过智能技术生成

推荐系统协同过滤-python实现(基于用户的协同过滤算法,基于物品的协同过滤算法,附数据集)

本次课题算法实践的数据集来源于一篇论文BINE,十一篇顶会论文,这篇论文种使用了两个数据集,分别是dblp和wiki,分别来自两个公开免费数据集的权威网站,且这些数据都是来自于现实生活的。因为两个数据集的格式都是一样的,本次算法实践只使用其中一个进行实验。数据集博主已经上传到个人资源中,需要做该实验的可以自行下载

1.基于用户的协同过滤算法主要包括两个步骤。
(1) 找到和目标用户兴趣相似的用户集合。
(2) 找到这个集合中的用户喜欢的,且目标用户没有听说过的物品推荐给目标用户。
步骤(1)的关键就是计算两个用户的兴趣相似度。这里,协同过滤算法主要利用行为的相似度计算兴趣的相似度。给定用户u和用户v,令N(u)表示用户u曾经有过正反馈的物品集合,令N(v)为用户v曾经有过正反馈的物品集合。那么,我们可以通过如下的Jaccard公式简单地计算u和v的兴趣相似度或者通过余弦公式:
在这里插入图片描述
下面诗算法实现:


import os
import numpy as np
path="C:/学习数据/推荐系统大报告/BiNE-master/data/dblp/rating_train.dat"

r=open(path)#读取数据

#print(r.read())

u_item_dict={}
u_item_rating_dict={}

for line  in  r.readlines():
   # print(line[0])
    il=line.split()

    u_item_rating_dict[il[0]+"-"+il[2]]=il[2]
    print(il)
    if il[0] not in u_item_dict.keys():
        u_item_dict[il[0]]=[]#初始化用户字典
        u_item_dict[il[0]].append(il[1])#将item加入用户的item集合中
    else:  u_item_dict[il[0]].append(il[1])#将item加入用户的item集合中

r.close()#关闭文件

##测试结果

#print(u_item_dict)

#print(u_item_rating_dict)
#计算用户之间弦相似度

def user_cos_similar(u_item_rating_dict,u_item_dict):
    u_u_similar={}
    for u1 in u_item_dict.keys():
        u_u_similar[u1]={}
        for u2 in u_item_dict.keys():
            u_u_similar[u1][u2]=len(set(u_item_dict[u1])&set(u_item_dict[u2]))/(len(u_item_dict[u1])*len(u_item_dict[u2]))**0.5#计算用户与用户之间的余弦相似度


    return u_u_similar

#测试
u_u_similar1=user_cos_similar(u_item_rating_dict,u_item_dict)
#print(u_u_similar)
#计算用户之间jaccard相似度

def user_jaccard_similar(u_item_rating_dict,u_item_dict):
    u_u_similar={}
    for u1 in u_item_dict.keys():
        u_u_similar[u1]={}
        for u2 in u_item_dict.keys():
            u_u_similar[u1][u2]=len(set(u_item_dict[u1])&set(u_item_dict[u2]))/len(set(u_item_dict[u1])|set(u_item_dict[u2]))#计算用户与用户之间的jaccard相似度
    return u_u_similar

u_u_similar2=user_jaccard_similar(u_item_rating_dict,u_item_dict)
#print(u_u_similar)


for u in u_u_similar1.keys():
   # print(sorted(u_u_similar1[u].items(),key=lambda x : x[1],reverse=True))
    u_u_similar1[u]=sorted(u_u_similar1[u].items(),key=lambda x : x[1],reverse=True)

#print(u_u_similar1)`


def recommdation_k(k,u_u_similar,u_item_dict):
    recommdation_u={}
    for u in u_u_similar.keys():
        if u not in recommdation_u.keys():
            recommdation_u[u]=[]
            p=0
            for i in u_u_similar[u]:
                if p==k :break
                if  i[0] != u:
                    p=p+1
                    recommdation_u[u]=recommdation_u[u]+u_item_dict[i[0]]
            recommdation_u[u]= set(recommdation_u[u])-set(u_item_dict[u])

  
    return recommdation_u

recommdation_u=recommdation_k(5,u_u_similar1,u_item_dict)
print(recommdation_u)



def user_modify_similar(u_item_rating_dict,u_item_dict):
    u_u_similar={}
    for u1 in u_item_dict.keys():
        u_u_similar[u1]={}
        for u2 in u_item_dict.keys():
            a=len(set(u_item_dict[u1])&set(u_item_dict[u2]))
            u_u_similar[u1][u2]=(a/(1+np.log(2,a)))/len(set(u_item_dict[u1])|set(u_item_dict[u2]))#计算用户与用户之间的jaccard相似度
    return u_u_similar

u_u_similar3=user_jaccard_similar(u_item_rating_dict,u_item_dict)

print(u_u_similar3)
os.system("pause")

2.基于物品的协同过滤
计算物品之间的相似度,一般也有两种计算方法
设 ∣N(i)∣表示喜欢物品 i 的用户数, ∣ N ( i ) ⋂ N ( j ) ∣表示同时喜欢物品 i 物品 j 的用户数,则物品 i 物品 j 的相似度为:
在这里插入图片描述

上式有一个问题,当物品 j 是一个很热门的商品时,人人都喜欢,那么 w i j 就会很接近于1,即上式会让很多物品都和热门商品有一个很大的相似度,所以可以改进一下公式:

下面我们仍然编程实现一下上述算法思路
1.处理数据集,因为我们之前已经协议相关代码,所以可以直接在上面改
在这里插入图片描述
实现代码如下:

import os
import numpy as np
path="C:/学习数据/推荐系统大报告/BiNE-master/data/dblp/rating_train.dat"

r=open(path)#读取数据

#print(r.read())

v_item_dict={}
v_item_rating_dict={}


for line  in  r.readlines():
   # print(line[0])
    il=line.split()

    v_item_rating_dict[il[0]+"-"+il[2]]=il[2]
    print(il)
    if il[1] not in v_item_dict.keys():
        v_item_dict[il[1]]=[]#初始化用户字典
        v_item_dict[il[1]].append(il[0])#将item加入用户的item集合中
    else:  v_item_dict[il[1]].append(il[0])#将item加入用户的item集合中

r.close()#关闭文件
#print(v_item_dict)

print(v_item_dict)
print(v_item_rating_dict)

def item_1_similar(v_item_rating_dict,v_item_dict):
    v_v_similar={}
    for v1 in v_item_dict.keys():
        v_v_similar[v1]={}
        for v2 in v_item_dict.keys():
            v_v_similar[v1][v2]=len(set(v_item_dict[v1])&set(v_item_dict[v2]))/len(v_item_dict[v1])#计算用户与用户之间的余弦相似度

    return v_v_similar
v_v_similar=item_1_similar(v_item_rating_dict,v_item_dict)
print(v_v_similar) 



def item_2_similar(v_item_rating_dict,v_item_dict):
    v_v_similar={}
    for v1 in v_item_dict.keys():
        v_v_similar[v1]={}
        for v2 in v_item_dict.keys():
            v_v_similar[v1][v2]=len(set(v_item_dict[v1])&set(v_item_dict[v2]))/(len(v_item_dict[v1])*len(v_item_dict[v2]))**0.5#计算用户与用户之间的余弦相似度

    return v_v_similar
v_v_similar1=item_2_similar(v_item_rating_dict,v_item_dict)
#print(v_v_similar)





for v in v_v_similar1.keys():
   # print(sorted(u_u_similar1[u].items(),key=lambda x : x[1],reverse=True))
    v_v_similar1[v]=sorted(v_v_similar1[v].items(),key=lambda x : x[1],reverse=True)
print(v_v_similar1)
r=open(path)#读取数据

print(r.read())

u_item_dict={}
u_item_rating_dict={}

for line  in  r.readlines():
   # print(line[0])
    il=line.split()

    u_item_rating_dict[il[0]+"-"+il[2]]=il[2]
    print(il)
    if il[0] not in u_item_dict.keys():
        u_item_dict[il[0]]=[]#初始化用户字典
        u_item_dict[il[0]].append(il[1])#将item加入用户的item集合中
    else:  u_item_dict[il[0]].append(il[1])#将item加入用户的item集合中

r.close()#关闭文件


def recommdation_k(k,v_v_similar,u_item_dict):
    recommdation_u={}
    for u in u_item_dict.keys():
        for i in u_item_dict[u]:
            recommdation_u[u]=[]
            p=0
            for j in v_v_similar[i]:
                if p==k :break
                if  j[0] != i:
                    p=p+1
                    recommdation_u[u].append(j)
           
    return recommdation_u
##测试结果


def item_modify_similar(v_item_rating_dict,v_item_dict):
    v_v_similar={}
    for v1 in v_item_dict.keys():
        v_v_similar[v1]={}
        for v2 in v_item_dict.keys():
            a=len(set(v_item_dict[v1])&set(v_item_dict[v2]))
            v_v_similar[v1][v2]=(a/(1+np.math.log(1+a,2)))/len(set(v_item_dict[v1])|set(v_item_dict[v2]))#计算用户与用户之间的jaccard相似度
    return v_v_similar

v_v_similar1=item_modify_similar(v_item_rating_dict,v_item_dict)
print(v_v_similar1)



os.system("pause")
  • 3
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值