python实现协同过滤算法

article/2025/10/19 16:09:13

协同过滤算法常用于商品推荐或者类似的场合,根据用户之间或商品之间的相似性进行精准推荐

  1. 协同过滤算法分为:
  • 基于用户的协同过滤算法(UserCF算法)(适合社交化应用)
  • 基于商品的协同过滤算法(ItemCF算法)(适合电子商务、电影)
    两者不同在于UserCF是通过物品到用户倒排表来计算用户相似矩阵,ItemCF是用过用户到物品倒排表计算机物品相似度,在计算相似度的时候,都没有考虑到评分,只是在最终的推荐时使用预测用户已看过的电影评分。
    一篇写的比较好的文章
  1. 相似度矩阵的计算
    ① 泊松相关系数
    ② 余弦相似度
    ③ 调整余弦相关度
    ④ Jaccard系数

UserCF:

  • 计算用户之间的相似度
    看过同一场电影的用户之间关系+1
D, N = {}, {}
# 物品到用户倒排表
for user, items in user_movie.items():N[user] = len(items)for i in items.keys():D.setdefault(i, [])D[i].append(user)
C = {}
# 用户到用户矩阵
for item, user in D.items():for i in user:C.setdefault(i, {})for j in user:if i== j :continueC[i].setdefault(j, 0)C[i][j] += 1W = {}
# 计算用户相似度
for i, related_users in C.items():W.setdefault(i, {})for j, cij in related_users.items():W[i][j] = cij / math.sqrt((N[i]* N[j]))
  • 预测
    在这里插入图片描述
    S(u,K)是和用户u兴趣最接近的K个用户的集合;N(i)是喜欢物品i的用户集合;Wuv是用户u和v的相似度;rvi是隐反馈信息,代表用户v对物品i的感兴趣程度,为该电影的打分
    rank = {} # 排名# W 用户相似矩阵, N: 喜欢物品的用户集合,for u, wu in sorted(W[user].items(), key=lambda x: x[1], reverse=True)[0:K]:for movie, users in movie_user.items():# 选择K个最高相似度用户# 选出 前K个喜欢,user没有选择的filmif u in users and user not in users:rank.setdefault(movie, 0)score = movie_user[movie][u]rank[movie] += score * wureturn dict(sorted(rank.items(), key=lambda x:x[1], reverse=True)[0:N])

ItemCF:

  • 计算电影之间的相似度
    (原理是:用户看过的电影之间有联系,比如一个人看过film1和film2,则film1与film2之间的关系值为1,若又有一个用户也看过film1和film2,则film1和film2关系值+1,以此类推。这样做是根据用户的兴趣偏好来确定电影的关系):
    C = {}N = {}for user, items in user_movie.items():# items : {'film6': 4, 'film11': 2, 'film8': 2, 'film14': 2},for i in items.keys():# i :‘film6...N.setdefault(i , 0)N[i] += 1 # 电影打分人数C.setdefault(i, {})for j in items.keys():if i == j : continueC[i].setdefault(j, 0)C[i][j] += 1  # 电影相似度
  • 使用余弦相似度计算物品相似度矩阵W
    在这里插入图片描述
    W1 = {}for i, related_items in C.items():W.setdefault(i, {})for j, cij in related_items.items():W[i][j] = cij / (math.sqrt(N[i] * N[j]))

在这里插入图片描述

  • 预测
    rank = {}action_item = user_movie[user]for item, score in action_item.items():for j, Wj in sorted(W[item].items(), key=lambda x: x[1], reverse=True)[0:K]:取前K个相似用户,减少计算量if j in action_item.keys(): # 用户已看过该电影continuerank.setdefault(j, 0)rank[j] += score * Wj # 用户没看过,用看过的电影*物品相似度return dict(sorted(rank.items(), key=lambda x: x[1], reverse=True)[0:N])
  • 下面直接在用户-物品上计算相似度。

虚拟数据:
10个用户,对14部电影的评分
在这里插入图片描述
ex:计算相似度的三种方法:

  • ① Jaccard相似度(缺点是没有考虑评分系统):N(u)是用户u的看过的电影集合
    在这里插入图片描述

  • ② 余弦相似度 (缺点是认为缺失值为0)
    在这里插入图片描述

  • ③ 皮尔逊相关系数(要求矩阵有序)
    在这里插入图片描述

  • 在预测时使用加权的方法
    在这里插入图片描述
    ex:对user0 ->film2的预测:
    取N个最相近的用户
    p = N1与user0相似度xN1对film2的评分+N2与user0相似度xN2对film2的评分 / N1的相似度+N2的相似度

利用上述表格利用不同方法进行对user0做推荐

UserCF,用user-item倒排表余弦相似度计算相似度
在这里插入图片描述

ItemCF,使用user-item倒排表使用余弦相似度
在这里插入图片描述

UserCF:直接在表格用余弦计算相似度
在这里插入图片描述

UserCF直接在表格用皮尔逊相关系数计算相似度
在这里插入图片描述
使用MovieLens作为实验数据

UserCF,用item-user计算相似度
可以看出geners大多数相同,效果应该应该还不错
在这里插入图片描述
ItemCF,使用user-item倒排表使用余弦相似度
耗时较长,应该是item远远大于user, item相似度矩阵非常大
在这里插入图片描述
UserCF直接在表格用皮尔逊相关系数计算相似度
在这里插入图片描述
UserCF

# -*- coding: utf-8 -*-
# author: cmzz
# datetime:2020/6/11 22:12
import math
from itertools import islice
import timedef readData():file_user_movie = './ml-latest-small/ratings.csv'file_movie_info = './ml-latest-small/movies.csv'user_movie = {}for line in islice(open(file_user_movie, encoding='utf-8'), 1, None):user, item, score = line.split(',')[0:3]user_movie.setdefault(user, {})user_movie[user][item] = float(score)movies = {}for line in islice(open(file_movie_info, encoding='utf-8'), 1, None):(movieId, movieTitle, genres) = line.split(',')[0:3]movies[movieId] = movieTitle+' '+'genres:{}'.format(genres)return user_movie, movies
def simmialr(user_movie):D, N = {}, {}# 物品到用户倒排表for user, items in user_movie.items():N[user] = len(items)for film, score in items.items():D.setdefault(film, {})D[film][user] = scoreC = {}# 用户到用户矩阵for item, user in D.items():for i in user:C.setdefault(i, {})for j in user:if i== j :continueC[i].setdefault(j, 0)C[i][j] += 1W = {}# 计算用户相似度for i, related_users in C.items():W.setdefault(i, {})for j, cij in related_users.items():W[i][j] = cij / math.sqrt((N[i]* N[j]))return W, Ddef recommend2(user, movie_user, W, K, N):rank = {} # 排名# W 用户相似矩阵, N: 喜欢物品的用户集合,for u, wu in sorted(W[user].items(), key=lambda x: x[1], reverse=True)[0:K]:for movie, users in movie_user.items():# 选择K个最高相似度用户# 选出 前K个喜欢,user没有选择的filmif u in users and user not in users:rank.setdefault(movie, 0)score = movie_user[movie][u]rank[movie] += score * wureturn dict(sorted(rank.items(), key=lambda x:x[1], reverse=True)[0:N])if __name__ == '__main__':user_movie, movies = readData()pre = time.time()UW, movie_user = simmialr(user_movie) # userCFresult = recommend2('1', movie_user, UW, 10, 10)# userCFprint('耗时{}s'.format(time.time()- pre))for film, rating in result.items():print(movies[film])print(rating)print('\n')

UserCF,表格使用余弦计算相似度

def simmialr(user_moives):# 余弦计算相关度W={}for user1, items1 in user_moives.items():W.setdefault(user1, {})for user2, items2 in user_moives.items():if user1 == user2: continueW[user1].setdefault(user2, 0)items = items1.keys() & items2.keys() # 取交集if items:for item in items:# 余弦计算公式W[user1][user2] += \(user_moives[user1][item]*user_moives[user2][item]) / \(math.sqrt(sum([x**2 for x in items1.values()])) * math.sqrt(sum([y**2 for y in items2.values()])))return Wdef recommend(uuser, user_movie, W, K, N):rank,sumN = {}, {}action_item = user_movie[uuser].keys()for user, Wj in sorted(W[uuser].items(), key=lambda x: x[1], reverse=True)[0:K]:for item, score in user_movie[user].items():if item in action_item: continuerank.setdefault(item, 0)if item in user_movie[user].keys():sumN.setdefault(item, 0)sumN[item] += Wjrank[item] += score * Wjfor item1, score1 in rank.items():for item2, score2 in sumN.items():if item1 == item2:#  除以该item的相似度总和rank[item1] = score1 / score2return dict(sorted(rank.items(), key=lambda x: x[1], reverse=True)[0:N])

ItemCF

# -*- coding: utf-8 -*-
# datetime:2020/6/9 11:48
import math
from itertools import islice
import timedef readData():file_user_movie = './ml-latest-small/ratings.csv'file_movie_info = './ml-latest-small/movies.csv'user_movie = {}for line in islice(open(file_user_movie, encoding='utf-8'), 1, None):user, item, score = line.split(',')[0:3]user_movie.setdefault(user, {})user_movie[user][item] = float(score)movies = {}for line in islice(open(file_movie_info, encoding='utf-8'), 1, None):(movieId, movieTitle, genres) = line.split(',')[0:3]movies[movieId] = movieTitle+' '+'genres:{}'.format(genres)return user_movie, movies
# ItemCF
#  使用余弦计算相似度
def cosineItemSimilarity(user_movie):C = {}N = {}for user, items in user_movie.items():for i in items.keys():# i : 电影idN.setdefault(i , 0)N[i] += 1 # 用户对应物品集合C.setdefault(i, {})for j in items.keys():if i == j : continueC[i].setdefault(j, 0)C[i][j] += 1 # 物品对应用户的集合# print(C)W =  {}for i, related_items in C.items():W.setdefault(i, {})for j, cij in related_items.items():W[i][j] = cij / (math.sqrt(N[i] * N[j]))return Wdef recommend(user, user_movie, W, K, N):rank = {}action_item = user_movie[user]for item, score in action_item.items():for j, Wj in sorted(W[item].items(), key=lambda x: x[1], reverse=True)[0:K]:if j in action_item.keys(): continuerank.setdefault(j, 0)rank[j] += score * Wjreturn dict(sorted(rank.items(), key=lambda x: x[1], reverse=True)[0:N])#  userCF
def simmialr(user_movie):D, N = {}, {}# 物品到用户倒排表for user, items in user_movie.items():N[user] = len(items)for film, score in items.items():D.setdefault(film, {})D[film][user] = scoreC = {}# 用户到用户矩阵for item, user in D.items():for i in user:C.setdefault(i, {})for j in user:if i== j :continueC[i].setdefault(j, 0)C[i][j] += 1W = {}# 计算用户相似度for i, related_users in C.items():W.setdefault(i, {})for j, cij in related_users.items():W[i][j] = cij / math.sqrt((N[i]* N[j]))return W, Ddef recommend2(user, movie_user, W, K, N):rank = {} # 排名# W 用户相似矩阵, N: 喜欢物品的用户集合,for u, wu in sorted(W[user].items(), key=lambda x: x[1], reverse=True)[0:K]:for movie, users in movie_user.items():# 选择K个最高相似度用户# 选出 前K个喜欢,user没有选择的filmif u in users and user not in users:rank.setdefault(movie, 0)score = movie_user[movie][u]rank[movie] += score * wureturn dict(sorted(rank.items(), key=lambda x:x[1], reverse=True)[0:N])if __name__ == '__main__':user_movie, movies = readData()pre = time.time()W = cosineItemSimilarity(user_movie)result = recommend('1', user_movie, W, 10, 10)print('耗时{}s'.format(time.time()- pre))for film, rating in result.items():print(movies[film])print(rating)print('\n')

UserCF直接在表格用皮尔逊相关系数计算相似度(代码)

def simmialr(user_movie):#W = {}# 物品到用户倒排表for user1, items1 in user_movie.items():W.setdefault(user1, {})for user2, items2 in user_movie.items():if user1 == user2 : continueW[user1].setdefault(user2, 0)ave1 = sum(items1.values()) / len(items1)ave2 = sum(items2.values()) / len(items2)U = items1.keys() | items2.keys()u1, u2 = [], []for i in U:# print(i)if i in items1.keys():u1.append(items1[i])else:u1.append(ave1)if i in items2.keys():u2.append(items2[i])else:u2.append(ave2)W[user1][user2] = corrcoef(u1, u2)return Wdef multipl(a, b):sumofab = 0.0for i in range(len(a)):temp = a[i] * b[i]sumofab += tempreturn sumofabdef corrcoef(x, y):n = len(x)# 求和sum1 = sum(x)sum2 = sum(y)# 求乘积之和sumofxy = multipl(x, y)# 求平方和sumofx2 = sum([pow(i, 2) for i in x])sumofy2 = sum([pow(j, 2) for j in y])num = sumofxy - (float(sum1) * float(sum2) / n)# 计算皮尔逊相关系数den = math.sqrt((sumofx2 - float(sum1 ** 2) / n) * (sumofy2 - float(sum2 ** 2) / n))if den:return num / denelse:return num / 1def recommend(uuser, user_movie, W, K, N):rank,sumN = {}, {}action_item = user_movie[uuser].keys()for user, Wj in sorted(W[uuser].items(), key=lambda x: x[1], reverse=True)[0:K]:for item, score in user_movie[user].items():if item in action_item: continuerank.setdefault(item, 0)rank[item] += score * Wjreturn dict(sorted(rank.items(), key=lambda x: x[1], reverse=True)[0:N])

http://chatgpt.dhexx.cn/article/Xd3C90iJ.shtml

相关文章

java 协同过滤算法_推荐系统中协同过滤算法实现分析

最近研究Mahout比较多,特别是里面协同过滤算法;于是把协同过滤算法的这个实现思路与数据流程,总结了一下,以便以后对系统做优化时,有个清晰的思路,这样才能知道该如何优化且优化后数据亦能正确。 推荐中的协…

协同过滤算法理解

一、协同过滤思想介绍 顾名思义,协同过滤算法的核心思想就是“物以类聚,人以群分”,通过用户对物品的评价和意见,将物品和人聚成几类,从各自的类中挑选出用户可能感兴趣的的物品进行推荐,而代替从直接从海量…

协同过滤推荐算法的原理及实现

一、协同过滤算法的原理及实现 二、基于物品的协同过滤算法详解 一、协同过滤算法的原理及实现 协同过滤推荐算法是诞生最早,并且较为著名的推荐算法。主要的功能是预测和推荐。算法通过对用户历史行为数据的挖掘发现用户的偏好,基于不同的偏好对用户…

协同过滤算法详解

一、协同过滤算法简介 协同过滤算法是一种较为著名和常用的推荐算法,它基于对用户历史行为数据的挖掘发现用户的喜好偏向,并预测用户可能喜好的产品进行推荐。也就是常见的“猜你喜欢”,和“购买了该商品的人也喜欢”等功能。它的主要实现由…

协同过滤算法

目录 一、什么是协同过滤算法 二、相似度的计算 2.1杰卡德(Jaccard)相似度 2.2余弦相似度(Cosine Similarity) 2.3皮尔逊相关系数(Pearson Correlation Coefficient) 2.4欧氏距离(Euclidea…

协同过滤推荐算法

一、协同过滤思想简介 二、协同过滤算法原理介绍 三、基于用户的协同过滤算法描述 四、基于物品的协同过滤算法 基于物品的协同过滤算法的优缺点 一、协同过滤思想简介 协同过滤,从字面上理解,包括协同和过滤两个操作。首先我们在外出和朋友吃饭的时候肯…

推荐系统之协同过滤算法

1、介绍 协同过滤算法(Collaborative Filtering) 是比较经典常用的推荐算法,从1992年一直延续至今。所谓协同过滤算法,基本思想是根据用户的历史行为数据的挖掘发现用户的兴趣爱好,基于不同的兴趣爱好对用户进行划分并…

oracle数据库中spool的作用,Oracle中Spool命令如何使用 Oracle中Spool命令使用方法

Oracle中Spool命令如何使用?本篇文章小编给大家分享一下Oracle中Spool命令使用方法,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看。 方法/步骤 首先需要明白Spool是Oracle的命令而不是sql语句。 Spool命…

oracle的Spool命令

使用spool命令实行将sql*plus中的输出的结果复制到一个指定的文件中,或者把查询的结果 发送到打印机中,直接使用spool off命令为止。 spool命令的语法如下: spool [file_name [create|replace|append] off|out] 其中file_name指定一个操作…

Oracle数据导出spool用法详解

Oracle数据导出spool用法详解 spool可导出select查询的结果集以emp表为例spool命令参数 spool可导出select查询的结果集 在实际的工作中,很多时候我们需要将Oracle中查询的数据导出来,生成excel格式的表以便于处理。虽然plsql可以导数据,但是…

oracle spool命令

1.spool的作用是什么? spool的作用可以用一句话来描述:在sqlplus中用来保存或打印查询结果。 通过spool 命令,可以将select 数据库的内容写到文件中,通过在sqlplus设置一些参数,使得按指定方式写到文件中。 spool 是…

spool命令的使用

(一)SPOOL是sqlplus中的命令 转自:https://blog.csdn.net/wangnan537/article/details/20706555 可作如下用途: 1)可使用SPOOL保存查询的结果集 [sql] view plain copy SPOOL "C:\test.txt" --生成test.txt文件 ...…

spooling

SPOOLing的含义是什么?试述SPOOLing系统的特点、功能以及控制过程。答:SPOOLing是Simultaneous Peripheral Operation On-Line (即外部设备联机并行操作)的缩写 SPOOLING ,它是关于慢速字符设备如何与计算机主机交换信…

SPOOLing技术

1.什么是SPOOLing 脱机输入、脱机输出技术。 该技术是利用专门的外围控制机,将低速I/O设备上的数据传送到高速磁盘上,或者相反。 引入了多道程序技术后,可以利用进程来模拟脱机输入时的外围控制机功能。这样,外围操作…

SoapUI接口测试-基本操作

SoapUI:http接口测试 GET请求: 1、打开SoapUI工具,点击左上角REST,新建一个REST项目。(一般的http接口文档中会有声明此接口遵循RESTful API的设计规范),弹出的框中提示输入接口地址&#xff0c…

SoapUI-一款强大的Rest和Soap测试工具

文章目录 SoapUI-一款强大的Rest和Soap测试工具1.什么是SoapUI2.SoapUi基本使用-Http2.1 构建一个项目2.2 确定项目名2.3 创建测试用例以及用例组2.4 创建一个http请求的测试用例,这里我们用一个天气测试接口测试2.5 运行接口测试 3.SoapUi基本使用-Web Service3.1 …

接口测试工具--SoapUI下载安装教程

接口测试工具--SoapUI下载安装教程: 作为一个初学测试的小白,当然是从下载熟悉各种测试工具开始了,现在写一下SoapUI的下载安装过程,以便日后使用。 我是直接在松勤网的网站上找的下载资源:链接:ht…

SoapUI基本使用

SoapUI是用java开发的测试web service的工具。 SoapUI基本使用: 主要用其来查看web service提供的接口,以及返回的结果,以便进一步的利用,但是SoapUI的功能远不止这些,其可以对web service进行功能上和性能上的测试。…

soapui 自动化教程(四)

上一节介绍到了使用groovy实现接口自动化测试的基本功能。 本节将介绍groovy执行用例动态参数、参数回传、参数加密、soapui引入第三方jar包、生成随机参数(绕过业务逻辑中的一些唯一校验阻碍自动化),以适应更真实、复杂的场景。 soapui引入…

soapUI 5.7.0使用

soapUI 5.7.0使用 公司有接口是webService的,用的是soap协议类型,这时候使用postman就不好使了,所以这边要使用SoapUI来进行测试,以下是SoapUI的使用流程首先,新建一个SOAP项目 将webService的地址填入其中&#xff0c…