推荐系统-基于用户的协同过滤(User-based CF)

2023-10-30

基于邻域的算法应该算是推荐系统中最基础的算法之一了,主要包括基于用户的协同过滤和基于物品的协同过滤,我觉得他们是最符合直觉的推荐算法了。你想想看,如果给你若干人的行为数据,你怎么去做推荐,一个就是找到和他最相似的用户,因为他们臭味相投,所以看看这些用户都看了些啥,然后给他推荐这些用户看过而待推荐用户没看过的商品;另一个就是找到和用户历史放生交互的商品最相似的商品,用户以前喜欢过它,也许会喜欢和它相似或者相关的东西。今天我们就从User-based CF开始,也就是基于用户的协同过滤。

那么问题来了,最最关键的一个问题,如何找出和待推荐用户口味相似的用户呢?哎呀,其实也没有其他选择啦,就是根据用户的历史行为记录,如果两个人的历史记录里有非常多共同的部分,那么大概率他们是志趣相投的,所以可以通过余弦相似度进行计算

 

直观地来看,对用户做两层嵌套的循环就可以算出来,但事实上在海量用户的情况下,这样的复杂度是很难接受的,那么可优化的空间在哪里呢?其实用户的交互是稀疏的,所以对于很多(u,v)对来说其实没有计算的必要。所以可以选择做一个物品-用户倒排表,用一个矩阵C[u][v]来表示用户之间相同的交互数量,对于倒排表中的每个物品对应的用户,两两之间在C中+1,通过这种方式得到所有交互不为0的用户相似度,实现算法如下所示:

def User_Similarity(train_set):
    # Build inverse table
    item_user = {}
    for u, items in train_set.items():
        for i in items:
            if i not in item_user.keys():
                item_user[i] = set()
            item_user[i].add(u)
    print('Inverse table finished')
    # Co-rated items between users
    C = {}
    N = {}
    W = {}
    for u in train_set.keys():
        N[u] = 0
        C[u] = {}
        W[u] = {}
        for v in train_set.keys():
            if v == u:
                continue
            C[u][v] = 0
            W[u][v] = 0
    for i, users in item_user.items():
        for u in users:
            N[u] += 1
            for v in users:
                if v == u:
                    continue
                C[u][v] += 1
    print('Co-rated items count finished')
    # Calculate similarity matrix
    for u, related_users in C.items():
        for v, cuv in related_users.items():
            W[u][v] = cuv/(N[u]*N[v])**0.5
    print('Similarity calculation finished')
    return W

有了相似度矩阵之后我们就可以进行推荐了,首先找出和用户相似度最高的K个用户,然后得到这K个用户发生交互商品的集合,去除用户原本已经发生交互的商品就得到了带推荐的集合,如何去衡量这些待推荐商品的优先级呢,很容易想到,如果它来自和用户相似度非常高的用户,那么它的优先级肯定应该高一点对吧,所以可以用如下公式来描述

与用户最相似的K个用户中如果用户v与待推荐商品发生过交互,则用户对该商品的兴趣加上这两个用户的相似度和该用户对该商品的兴趣的乘积,如果只是单纯的行为数据,则兴趣为1。有了用户对待推荐商品的兴趣之后,可以选择一个阈值N,将用户兴趣度最高的N个商品作为最后的推荐集合,代码实现如下

def Recommend(user, train, W, K):
    rank = {}
    already_items = train[user]
    for v, wuv in sorted(W[user].items(), key=itemgetter(1), reverse=True)[:K]:
        for i in train[v]:
            if i in already_items:
                continue
            if i not in rank.keys():
                rank[i] = 0
            rank[i] += wuv
    return rank

到了这里,其实咱们已经完成了User-based CF算法,下面咱们得操练操练呀。例子来自于《推荐系统实践》这本书,利用MovieLens的数据集进行离线实验。首先是训练集和测试集的划分,这里比例选择是4:1,每一次将所有的数据打乱,前80%用作训练集,后20%用于测试集,代码实现如下:

def train_test_split(data, seed):
    train_set = {}
    test_set = {}
    for user, movies in data.groupby('user_id'):
        movies = movies.sample(
            frac=1, random_state=seed).reset_index(drop=True)
        train = movies[:int(0.8*len(movies))]
        test = movies[int(0.8*len(movies)):]
        train_set[user] = set(train['movies_id'].tolist())
        test_set[user] = set(test['movies_id'].tolist())
    print('Data preparation finished')
    return train_set, test_set

划分好数据集之后我们就可以进行预测了,包括交互表的统计,相似度排序,兴趣度计算和截断,生成推荐集。那么这边问题来了,我们怎么去评价推荐的效果呢,这里主要计算了以下四个指标

1 Recall

召回率是指实际发生交互的商品中被预测出来部分的比例,实现如下

def Recall(train, test, N, K, W):
    hit = 0
    all = 0
    for user in train.keys():
        tu = test[user]
        recommend_list = get_recommendation(N, user, K, W, train)
        for item in recommend_list:
            if item in tu:
                hit += 1
        all += len(tu)
    return hit/(all*1.0)

2 Precision

准确率是指实推荐的商品中用户真正发生交互商品的比例,实现如下

def Precision(train, test, N, K, W):
    hit = 0
    all = 0
    for user in train.keys():
        tu = test[user]
        recommend_list = get_recommendation(N, user, K, W, train)
        for item in recommend_list:
            if item in tu:
                hit += 1
            all += N
    return hit/(all*1.0)

3 Coverage

覆盖率,这算是推荐系统中独有的指标了,指推荐的商品占总商品数的比例。这个比例越高表明推荐系统发掘长尾的能力越强,实现如下

def All_item(train):
    all_items = set()
    for user in train.keys():
        for item in train[user]:
            all_items.add(item)
    return all_items

def Coverage(train, test, N, K, W,all_items):
    recommend_items = set()
    for user in train.keys():
        recommend_list = get_recommendation(N, user, K, W, train)
        for item in recommend_list:
            recommend_items.add(item)
    return len(recommend_items)/(len(all_items)*1.0)

4 Popularity

流行度,推荐商品的平均流行度,该值越高表明推荐的商品大多是比较热门的内容,推荐系统发掘长尾的能力较差,可以和覆盖率联合起来看,表征推荐的新颖度,实现如下

def Item_popularity(train):
    item_popularity = {}
    for user, items in train.items():
        for item in items:
            if item not in item_popularity.keys():
                item_popularity[item] = 0
            item_popularity[item] += 1
    return item_popularity

def Popularity(train, test, N, K, W,item_popularity):  
    ret = 0
    n = 0
    for user in train.keys():
        recommend_list = get_recommendation(N, user, K, W, train)
        for item in recommend_list:
            ret += np.log(1+item_popularity[item])
            n += 1
    return ret/(n*1.0)

OK,到了这里我们应该算是完成一个小小的User-based CF的实现及测试了,那么还有什么问题呢?在我们的算法里有两个超参数,一个是选择和用户最相似的K个用户,一个是选择用户兴趣度最高的N个商品生成推荐集。想一想,N固定的情况下,K越高,参与用户兴趣度计算的相似用户越多,那么更多的用户潜在交互商品被发掘出来,推荐的召回率和精确率肯定都会上升,但是应该会有一个边际效应,当K提升到某个值之后,基本没有提高了;而对于覆盖率和流行度而言,越多用户参与评分,推荐出来的东西肯定更热门,那么覆盖率肯定下降,流行度提升。同样的,在K固定的情况下,如果N越高,肯定有更多的用户潜在交互商品被推荐出来,所以召回率肯定会提升,而对于准确率,一开始也许会有一个提升,但后来肯定会下降,因为预测出的商品数量越来越多;至于覆盖率,由于商品数量变多,所以肯定会上升,而对于流行度,推荐排行越靠后的商品相对越小众一点,所以平均流行度会下降。

这里做一个小实验,我固定了N值,对不同的K值进行计算,采用八折计算的平均结果作为最后的对应K值地结果,可以看看趋势变化是否和我们分析一致

 

确实是随着K值的提高,召回率和准确率有所提升,但到80左右已经几乎达到了峰值,进一步提高到160甚至略微有所下降;而覆盖率和流行度和预测完全一致,覆盖率不停下降,流行度不断上升,越来越倾向于推荐热门内容。

最后还有一个小改进,是关于咱们计算用户之间相似度的,现在我们用的是不同用户对同一物品都发生过交互,则相似度加一,对于所有的物品一视同仁。但是仔细想想存在这样一种商品,它超级热门,基本人人都和它发生过交互,可它对我们判断有两个人相似有作用吗?米有,所以我们针对热门产品需要加一波惩罚,具体就是该商品的交互人数的对数的倒数作为相似度累加时的加权,减少热门产品对我们预测的影响,实现如下,

def User_Similarity2(train_set):
    # Build inverse table
    item_user = {}
    for u, items in train_set.items():
        for i in items:
            if i not in item_user.keys():
                item_user[i] = set()
            item_user[i].add(u)
    print('Inverse table finished')
    # Co-rated items between users
    C = {}
    N = {}
    W = {}
    for u in train_set.keys():
        N[u] = 0
        C[u] = {}
        W[u] = {}
        for v in train_set.keys():
            if v == u:
                continue
            C[u][v] = 0
            W[u][v] = 0
    for i, users in item_user.items():
        for u in users:
            N[u] += 1
            for v in users:
                if v == u:
                    continue
                C[u][v] += 1/np.log(1+len(users)*1.0)
    print('Co-rated items count finished')
    # Calculate similarity matrix
    for u, related_users in C.items():
        for v, cuv in related_users.items():
            W[u][v] = cuv/(N[u]*N[v])**0.5
    print('Similarity calculation finished')
    return W

这里我们再做一个小实验,固定N值为10,K值为刚才最好表现的80,采用两种不同的相似度计算方法,比较一下它们的结果,如下图所示

从图中我们就可以看出,在计算相似度时考虑到物品的流行度对我们的预测确实是有帮助的,而且是全方位无死角的提高,蛤蛤蛤,不过计算时间长了15倍……

今天就到这儿,下一篇咱们来聊一聊Item-based CF。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

推荐系统-基于用户的协同过滤(User-based CF) 的相关文章

  • 毕业设计-基于大数据的电影推荐系统-python

    目录 前言 课题背景和意义 实现技术思路 实现效果图样例 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力 近几年各个学校要求的毕设项目越来越难 有不少课题是研究生级别难度
  • 【推荐系统】geohash召回

    经纬度坐标 精度非常高 只能表述一个点 二维坐标 geohash 一种地理编码系统 划分成4 8的格子 编码长度越长 区域大小越小 位置描述的越精确 1km 一般编码长度用6 7长度 geohash比经纬度好在哪里 浮点数编码成字符串占用的
  • 推荐系统-基于物品的协同过滤(Item-based CF)

    今天我们来聊一聊基于物品的协同过滤即Item based CF方法 有了上一篇的经验 你可能很容易就想到Item based CF就是通过计算物品之间的相似度 然后用户曾与那些商品发生过交互 给他推荐与这些商品最接近的东西给他 这样做有什么
  • 推荐系统-基于用户的协同过滤(User-based CF)

    基于邻域的算法应该算是推荐系统中最基础的算法之一了 主要包括基于用户的协同过滤和基于物品的协同过滤 我觉得他们是最符合直觉的推荐算法了 你想想看 如果给你若干人的行为数据 你怎么去做推荐 一个就是找到和他最相似的用户 因为他们臭味相投 所以
  • 协同过滤-图书馆图书推荐系统(JAVA,JSP,SSM,MYSQL)

    协同过滤 图书馆图书推荐系统 JAVA JSP SSM MYSQL 毕业论文27564字 共78页 程序代码 MySQL数据库 链接 https pan baidu com s 1PilFCeVoH3S2VYwfrdMgnQ 提取码 888
  • 阿里手淘猜你喜欢Swing算法介绍

    Swing算法原理比较简单 是阿里早期使用到的一种召回算法 在阿里多个业务被验证过非常有效的一种召回方式 它认为 user item user 的结构比 itemCF 的单边结构更稳定 Swing指的是秋千 例如用户 u uu 和用户 v
  • 【人工智能】推荐系统算法

    推荐系统算法详解 一 推荐系统详解 1 基于人口统计学的推荐算法 基于人口统计学的推荐机制 Demographic based Recommendation 是一种最易于实现的推荐方法 它只是简单的根据系统用户的基本信息发现用户的相关程度
  • 计算物品的相似度矩阵

    计算物品的相似度矩阵 例如现在有A B C D四个用户 分别对a b c d e五个物品表达了自己喜好程度 通过评分高低来表现自己的偏好程度高低 计算物品之间的相似度矩阵 算法 1 建立用户物品倒排表 A a b d B a c e C b
  • Java语言开发在线新闻推荐网 新闻推荐系统 基于用户、物品的协同过滤推荐算法 环球日报新闻爬虫 SSM(Spring+SpringMVC+Mybatis)开发框架 大数据、机器学习、人工智能开发

    Java语言开发在线新闻推荐网 新闻推荐系统 基于用户 物品的协同过滤推荐算法 环球日报新闻爬虫 SSM Spring SpringMVC Mybatis 开发框架 大数据 机器学习 人工智能开发NewsRecommendOnline 一
  • 基于用户 的协同过滤算法

    计算用户相似度和用户对未知物品的可能评分 基于用户的协同过滤算法主要包括两个步骤 1 找到和目标用户兴趣相似的用户集合 2 找到这个集合中的用户喜欢的 且目标用户没有听说过的物品推荐给目标用户 例如现在有A B C D四个用户 分别对a b
  • 广电大数据用户画像及营销推荐策略(四)——Python实现

    本次大数据项目数据及分析均做脱敏化和保密化 主要分享思路体系 全程用Python实现 数据和代码均不提供 如有建议欢迎讨论 4 模型构建 在实际应用中 构造推荐系统时 并不是采用单一的某种推荐方法进行推荐 为了实现较好的推荐效果 大部分都将
  • Pytorch中的torch.nn.Linear()方法的详解

    torch nn Linear 作为深度学习中最简单的线性变换方法 其主要作用是对输入数据应用线性转换 先来看一下官方的解释及介绍 class Linear Module r Applies a linear transformation
  • 个人总结:推荐算法篇(附协同过滤等) 综述

    现代推荐系统 对于在线部分来说 一般要经历几个阶段 首先通过召回环节 将给用户推荐的物品降到千以下规模 因为在具备一定规模的公司里 是百万到千万级别 甚至上亿 所以对于每一个用户 如果对于千万级别物品都使用先进的模型挨个进行排序打分 明显速
  • 大数据Hadoop学习之————基于物品的协同过滤算法实现物品推荐

    一 基础概念 协同过滤算法一般分为两种实现 基于用户的协同过滤算法 userCF 通过寻找相似兴趣的其他用户 为指定用户推荐物品 比如用户A喜欢商品A B 用户B也喜欢商品A和B 则可以认为用户A和B兴趣相似 这时候就可以像用户A推荐用户B
  • 【Tensorflow 2.12 电影推荐系统之排序模型】

    Tensorflow 2 12 电影推荐系统之排序模型 学习笔记 导入相关模块 准备数据 加载数据 数据预处理 获取词汇表 构建模型 定义评分排序模型 定义损失函数以及模型评估指标 定义完整的评分排序模型 训练和评估 创建排序模型实例 缓存
  • Sequential Recommendation with Graph Neural Networks

    Sequential Recommendation with Graph Neural Networks 文章目录 1 背景 2 模型 2 1 Interest Graph Construction 2 1 1 Raw graph cons
  • 推荐系统(3)——最经典的推荐算法(协同过滤算法原理部分)

    一 最经典的推荐算法 协同过滤推荐算法 Collaborative Filtering 算法思想 物以类聚 人以群分 基本的协同过滤推荐算法基于以下假设 跟你喜好相似的人喜欢的东西你也很有可能喜欢 基于用户的协同过滤推荐 User base
  • 毕业设计-基于大数据招聘岗位可视化系统-python

    目录 前言 课题背景和意义 实现技术思路 实现效果图样例 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力 近几年各个学校要求的毕设项目越来越难 有不少课题是研究生级别难度
  • 推荐算法实战项目:用户协同过滤(UserCF)原理以及案例实战(附完整 Python 代码)

    协同过滤 collaborative filtering 是一种在推荐系统中广泛使用的技术 该技术通过分析用户或者事物之间的相似性 来预测用户可能感兴趣的内容并将此内容推荐给用户 这里的相似性可以是人口特征的相似性 也可以是历史浏览内容的相
  • 【推荐算法】双塔模型代码(tensorflow)

    推荐算法 双塔模型介绍 MachineCYL的博客 CSDN博客 上文介绍了双塔模型的原理和结构 这篇介绍一下双塔模型的代码实现 我使用的是tensorflow来实现双塔模型和模型训练 一 前期准备 tensorflow使用的版本是2 0

随机推荐

  • 匹配算法,角点介绍

    https www zhangshengrong com p wrad8o2EaB Harris角点 以一点为中心 画一个窗口 让该窗口在该点周围移动 看灰度值是否有变化 有变化证明是角点 该cost可以表达为 2 2 2 2次函数可以看作
  • SynchroTrap-基于松散行为相似度的欺诈账户检测算法

    大家好 我是小伍哥 今天给大家分享一个非常牛逼的算法 叫做SynchroTrap 有问题可以加我一起交流 一 极致对抗下的风控怎么做 为了好理解 以淘宝刷单为例 各阶段为假设 本人并未做过刷单的风控 第一阶段 同设备 同地址 大量购买 第二
  • 软件设计师(十)网络与信息安全基础知识

    计算机网络是由多台计算机组成的系统 与传统的单机系统 多机系统相比有很大的区别 一 网络概述 计算机网络是计算机技术与通信技术相结合的产物 它实现了远程通信 远程信息处理和资源共享 1 计算机网络的概念 计算机网络的定义是利用通信设备和线路
  • 三种主流的Web服务实现方案(REST+SOAP+XML-RPC)简述及比较

    目前知道的三种主流的Web服务实现方案为 REST 表象化状态转变 软件架构风格 SOAP 简单对象访问协议 XML RPC 远程过程调用协议 下面分别作简单介绍 REST 表征状态转移 Representational State Tra
  • GIT本地代码处于detached HEAD的情况(又称游离状态)的解决办法

    有时候git由于一些操作的问题出现了detached HEAD 的情况 对于新手来说很焦急 但又不敢动 生怕搞错点什么把劳动成果付之东流 下面的解决办法要顺序执行 先 git commit 进行提交 提交完你的本地分支指向的是你刚commi
  • FM33G0XX-创建一个KEIL工程的步骤

    1 说明 本文章为 FM33G 系列低功耗 MCU 创建 keil 工程 FM33G0XX 系列是复旦微电子 公司开发的低功耗 MCU 芯片 2 创建一个 keil 工程的步骤 2 1 新建功能文件夹 这里我们建立一个文件夹为 Templa
  • Ethereum以太坊区块链底层换用国密算法实验报告

    区块链技术的基础是计算机密码学 可以说 没有计算机密码学 就没有区块链技术 区块链在如下方面用到了计算机密码学 验证签名 保证交易发起的真实性 用到了ECDSA 哈希校验区块完整性 保证不可篡改特性 用到了hash算法 以太坊中具体用到sh
  • 一个java文件中是否可以定义多个类

    title 一个java文件中是否可以定义多个类 date 2017 12 31 1 53 43 tags Java基础 基本概念 categories Java基础 一个java文件中可以定义多个类 但是最多只有一个类被public修饰
  • 如何在宝塔面板中使用小皮面板的数据库(mysql)

    1 关闭mysql service mysqld stop 2 查看是否有僵尸进程残留 ps ef grep mysqld 如果存在 则杀掉进程 kill quit 进程号 或者 kill 9 进程号 3 复制小皮面板的mysql 的 da
  • 一款新的网页设计工具,简单好用

    之前一直在找一些智能化的 简单操作的网页设计工具 后来发现这个VXPLO 还蛮好用的 使用地址http www vxplo cn VXPLO是互联网上出现的第一款基于云计算方式的交互式网页设计工具 也是一个互动作品分享平台 大家需要网页设计
  • 蓝桥杯:火星人(全排列模板) Java

    import java util ArrayList import java util Arrays import java util LinkedList import java util List import java util Sc
  • Python编程题

    1 输入直角三角形的两个直角边的长度a b 求斜边c的长度 from math import sqrt 从math库中导入sqrt方法 a eval input 输入直角边a的长度 b eval input 输入直角边b的长度 c sqrt
  • Python FastAPI上传文件至七牛云

    最近需要给博客添加上传图片的功能 之前有图片上传的 上传主题图片的 考虑到博客的话图片太多就不存到服务器了 存到七牛云上比较好 相关的图片服务也比较多 我的上传流程是 前端上传图片至服务器 服务器在上传到七牛云 我的后台使用的是Python
  • linux系统的宝塔面板密码忘记了?用户名忘记了?访问地址忘记了?安全入口忘记了?宝塔服务是否已开启?以下是解决方法!修改密码、修改用户名、修改访问端口、修改安全入口等等!

    宝塔面板 在Linux系统下 宝塔面板 BT Panel 可以帮助用户简化服务器的管理和配置 宝塔面板适用于多个Linux发行版 如CentOS Ubuntu等 并提供了图形化的界面 使得用户可以通过简单的点击和配置来完成各种操作 使用宝塔
  • VS2017 创建动态链接库并使用

    下面我们直接步入正题 1 首先在VS2017中新建Dll项目 2 组织你的项目工程目录如下 3 其中 MyDll h文件中的代码为 pragma once ifdef MY DLL EXPORTS define MY DLL EXP dec
  • redis打开若依前端出现端口错误无法显示验证码

    解决方案 由深到表 1 redis服务没有开 箭头朝下 2 redis cli没有开 箭头朝下 3 redis cli打开后报错及解决 我出现的问题是自己在这两个文件设置了密码 但是没有输入导致无法连接 可以去查下如何在文件内设置redis
  • paramiko的两种简单用法,sftp上传下载,执行服务器cmd

    注 1 安装paramiko之前需要安装pycrypto 2 需要服务端添加你的公钥权限你才能使用对应的私钥 1 上传下载文件 import paramiko privatekeyfile 私钥的地址 mykey paramiko RSAK
  • 软件测试综述-软件开发过程

    1 软件产品构成的主要部分 1 客户需求 2 产品说明书 3 进度表 4 软件设计文档 包括 结构文档 数据流图 状态转换图 流程图 代码注释等 5 测试文档 包括 测试计划 测试用例 缺陷报告 测试工具和自动测试 质量 统计和总结 2 软
  • POJ-1416 Shredding Company(DFS)

    题目链接 点击打开链接 大致题意 公司现在要发明一种新的碎纸机 要求新的碎纸机能够把纸条上的数字切成最接近而不超过target值 比如 target的值是50 而纸条上的数字是12346 应该把数字切成四部分 分别是1 2 34 6 因为这
  • 推荐系统-基于用户的协同过滤(User-based CF)

    基于邻域的算法应该算是推荐系统中最基础的算法之一了 主要包括基于用户的协同过滤和基于物品的协同过滤 我觉得他们是最符合直觉的推荐算法了 你想想看 如果给你若干人的行为数据 你怎么去做推荐 一个就是找到和他最相似的用户 因为他们臭味相投 所以