基于物品的协同过滤推荐笔记(附源代码)

基于物品的协同过滤算法

1. 数据

使用movielens-100k数据集中的u1.base文件作为实验集

2.实验

在demo1中建立用户-评分矩阵和用户看过的电影id列表,根据用户看过的电影计算电影间相似度,根据项亮的《推荐系统实践》中方法计算用户相似度。
相似度公式:
在这里插入图片描述

import pandas as pd
import numpy as np
import math


#建立用户-评分矩阵
user_rating = np.zeros((944, 1683))#数据集共943个用户,1682部电影,0行0列不用
#print(user_rating)
def Create_User_rating_Table(data):
    for it in data:
        user_rating[it[0]][it[1]]=it[2]
    print(user_rating)
    #outfile = "F:\\协同过滤推荐算法\\基于物品\\user_rating.csv"
    #data1=pd.DataFrame(user_rating)
    #print(data1.shape)
    #data1.to_csv(outfile, index=False, header=False)
#建立用户看过的电影id列表
def Create_User_items(user_rating):
    user_item=[]
    for user in range(1,944):
        items=[]
        for item in  range(1,1683):
            if user_rating[user][item] != 0:
                items.append(item)
        user_item.append(items)
    print(user_item)
    outfile = "F:\\协同过滤推荐算法\\基于物品\\user_item.csv"
    data = pd.DataFrame(user_item)
    data.to_csv(outfile, index=False, header=False)
    return user_item
#计算物品相似度
def Create_Item_Sim(user_item):
    Item_Sim = np.zeros((1683, 1683))  # 数据集共1682部电影,0行0列不用
    N=np.zeros(1683)
    for items in user_item:
        for it1 in items:
            N[it1] += 1
            for it2 in items:
                if it1 == it2:
                    continue
                Item_Sim[it1][it2] += 1
                Item_Sim[it2][it1] += 1
    print(Item_Sim)
    W = np.zeros((1683, 1683))
    for it1 in range(1,1683):
        for it2 in range(1,1683):
            if it1 == it2 :
                continue
            if math.sqrt(N[it1]*N[it2]) == 0:
                W[it1][it2] = 0.0
                continue
            W[it1][it2]=Item_Sim[it1][it2]/math.sqrt(N[it1]*N[it2])
    print(W)
    return W
file="F:\\协同过滤推荐算法\\ml-100k\\u1.base"
lieming=["用户id", "电影id", "评分", "时间"]
data = pd.read_table(file, names=lieming)
#print(data)
list_data = np.array(data)#转换数组
#print(list_data)
data=list_data.tolist()#转换list
#创建用户评分矩阵
Create_User_rating_Table(data)
#创建用户看过的电影id的列表
user_items=Create_User_items(user_rating)
#根据用户看过的电影id计算电影间的相似度
Item_sim = Create_Item_Sim(user_items)
#输出
outfile = "F:\\协同过滤推荐算法\\基于物品\\item_sim.csv"
data1 = pd.DataFrame(Item_sim)
data1.to_csv(outfile, index=False, header=False)

用户评分矩阵
在这里插入图片描述
物品相似度矩阵:
在这里插入图片描述

在demo2中利用物品间的相似度,计算用户u对电影i的感兴趣值。
根据用户u看过的电影列表,找到看过电影的K个最近邻,计算用户u对这K个最近邻的感兴趣值,最后根据感兴趣值排序得到推荐列表。

计算用户u对电影j的感兴趣值公式:
在这里插入图片描述
用户看过的电影i与未看过的电影j的相似度*用户u对电影i的评分。

import pandas as pd
import numpy as np
import xlwt

def Create_User_items(user_rating):
    user_item=[]
    for user in range(1,944):
        items=[]
        for item in  range(1,1683):
            if user_rating[user][item] != 0:
                items.append(item)
        user_item.append(items)
    #print(user_item)
    return user_item
#计算电影u相关的所有电影
def Count_User_Interest(Sim_W,K,user_item,user_rating):
    userid = 0
    Recommend = {}
    for items in user_item:
        userid += 1
        cur_recommend = []
        for item in items:
            cur = []
            cur_rating=user_rating[userid][item]
            cur_item_sim = Sim_W[item]
            for it1 in range(1,1683):
                if cur_item_sim[it1] != 0:
                    cur.append([it1,cur_item_sim[it1]])
            cur.sort(key=(lambda x:x[1]), reverse=True)
            cur_sort=cur[0:K]
            for item2 in cur_sort:
                if item2 in items:
                    continue
                item2[1]*=cur_rating
                #去重
                flag = 0
                for cur_re in cur_recommend:
                    if item2[0] == cur_re[0]:
                        flag = 1
                        if item2[1]>cur_re[1]:
                            cur_re[1] = item2[1]
                if flag == 0:
                    cur_recommend.append(item2)
        for cur_item in cur_recommend:#将每一个二元组放入推荐字典中
            Recommend.setdefault(userid,[]).append(cur_item)

    #输出
    for userid in range(1,944):
        outfile = "F:\\协同过滤推荐算法\\基于物品\\推荐结果集合\\Recommend{}.csv".format(userid)
        Recommend[userid].sort(key=(lambda x:x[1]), reverse=True)
        data = pd.DataFrame(Recommend[userid])
        data.to_csv(outfile, index=False, header=False)
        print(Recommend[userid],len(Recommend[userid]))
    return Recommend

file1="F:\\协同过滤推荐算法\\基于物品\\user_rating.csv"
data1=pd.read_csv(file1, header=None)#header取消列名
user_rating=np.array(data1)
#print(user_rating)

file2="F:\\协同过滤推荐算法\\基于物品\\item_sim.csv"
data1=pd.read_csv(file2,header=None)
item_sim=np.array(data1)

#得到用户喜欢物品的列表
user_item = Create_User_items(user_rating)

#得到推荐列表
Count_User_Interest(item_sim,30,user_item,user_rating)

用户1的推荐列表(第一列为电影id,第二列为感兴趣值):
在这里插入图片描述

数据和详细代码在仓库

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jiaoooooo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值