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

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

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

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


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.处理数据集,因为我们之前已经协议相关代码,所以可以直接在上面改
推荐系统协同过滤-python实现(基于用户的协同过滤算法,基于物品的协同过滤算法,附数据集)_第2张图片
实现代码如下:

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

你可能感兴趣的:(python,数据分析,推荐系统,python,机器学习)