文章目录

  • 前言
    • 推荐系统定义
    • 基本分类
    • 相似度计算
      • 欧式距离
      • 皮尔逊系数
      • 余弦相似度
  • 协同过滤
  • 案例
    • 数据定义
    • 相似度计算
    • 推荐
    • svd奇异值分解优化
    • 完整代码
  • 总结

前言

打瞌睡遇到送枕头的感觉真爽嘿嘿 @BoyC啊

废话不多说,开始吧。

推荐系统定义

推荐系统(Recommendation System, RS),就是根据用户的日常行为,自动预测用户的喜好,为用户提供更多完善的服务。例如给DY上的小姐姐疯狂点赞此时DY会疯狂推送小姐姐,那么我们这边也是这样的。

基本分类

主要可以分为以下两类:

  1. 基于内容(content-based)的推荐。主要依据的是推荐项的性质。
  2. 基于协同过滤(collaborative filtering)的推荐。主要依据的是用户或者项之间的相似性。

此外基于协同过滤的推荐系统用可以分为两类:

  1. 基于项的推荐系统。主要依据的是项与项之间的相似性。
  2. 基于用户的推荐系统。主要依据的是用户与用户之间的相似性。

所以我们的推荐算法,推荐系统大体上就是做这几件事情,基于用户时,找到和你趣味相投的小伙伴,通过这个小伙伴有的去补齐你没有的,举个例子,假设你喜欢刷小姐姐,但是你没有关注A主播,此时系统发现有个其他和你相似的用户都关注了A,那么下次就给你推荐A。那么基于项,这个类似,看你对于项的定义,总之,就是找到和当前有的类似的玩意,然后按照评分给你推荐,比如你刷视频的时候发现你对科技频道很感兴趣,那么此时,把和科技频道相似的例如数学频道推荐给你。

相似度计算

那么在我们这边比较核心的地方就是咱们的一个相似度的一个计算。那么这里的话有几个方法。

欧式距离

这个就不用我多说了吧,例如Lmeans用的比较多的一个方法,直接分类是吧。

皮尔逊系数

这个也不用我多说了吧:

高中数学就已经开始见面了的东西。

余弦相似度

这个就更简单了,把两个东西,变成一个向量,计算向量夹角的值,然后的话,越相似越接近1.

协同过滤

ok,此时的话,基本的概念是说完了,那么接下来说一说神马是协同过滤这个玩意。

这个东西其实容易理解。首先我们还是来好好解释一下这个名词的意思,首先什么是协同,过滤的话很好理解,我们的推荐算法本身就是在做一种过滤嘛。那么协同呢,我们把这两个字拆开来理解,说白了就是,联合,相同,联合类似的事物进行推断,之后过滤出可信度最高的一组结果。

所以我们基本上可以开始梳理出一套流程,那就是:

在猜测你喜欢啥的时候,例如推测你喜欢谁,那么此时我们的流程是这样子的

  1. 看看你的情史(你的历史数据/最近操作,点赞收藏等等)
  2. 根据你的情史,去找找和你有类似经历的家伙,查看这些家伙现在和什么样的女生在一起(找和你类似的用户)
  3. 找出和你情况最类似的几个家伙,看看他们现在和什么女生在一块(假设这些人存在,这里请不要带入你自己,我知道你没有)(找出相似度较高的一组用户的喜好的标签之类的数据)
  4. 判断那些家伙和那些女孩是不是达到了情侣程度,在筛选一次,找出那些家伙中的女朋友(选出了相似度高的用户喜好的标签后,筛选出他们最喜欢的几组标签)
  5. 结合那些女孩的特点,在你熟悉的圈子里面找到你最有可能喜欢的女孩(拿到推荐标签,到具体服务里面找到实际的数据)

那么这个就是一个基本大致的流程,这里不要对号入座哈,相信自己,你绝对是和我一样的!

案例

那么接下来,我们来玩玩这个。这里的话我们来玩玩这个基于用户的过滤,这里我们还是拿那个上面的例子举个栗子吧,就是假设咱们有一个脱单App,现在有一些数据,我们现在要做一个匹配(给你推荐什么类型的女孩子是适合你的)

但是咱们这块的话简化一下流程,先前是还要找到和你相似的家伙,现在的话简化一下,我们假设数据是这样的:

我们这边就只是说,根据你目前在这个脱单App产生的一些数据,例如上面表中表示的是,当前这个用户点在了上面类型女孩多少次。我们这边通过这些你点赞的女孩类型去推测你会对哪些类型感兴趣。这个时候你可能会说了,我都点赞了,我肯定是对点赞的女孩类型感兴趣了,如果不是喜欢谁TM天天看咧,但是怎么说呢,你当前喜欢这些女孩类型可能只是你目前只能接触到这些女生或者男生,有可能有更好的你压根没有接触到(等等党,不吃亏)那么这个时候,我是不是可能根据别的用户,别的一些也对你当前点赞了的女孩类型的用户,他们所喜欢的其他的类型的女孩进行一个拓展推荐,甚至就是说,我们发现你当前点赞了女孩类型9,此时我们发现点赞了9这个类型的用户都点赞了类型1,并且点赞的次数远远大于类型9,那么是不是有可能是说类型1可能会更好?

所以这个就是咱们的这个推荐的一个逻辑。

ok,那么首先对于这个我们要做的其实很简单,咱们这里的话其实有两个方案。

  1. 基于用户去推荐,看看相似的用户喜欢啥类型
  2. 直接基于标签类型去做,看看相似的标签还有那些
    但是不管是哪一种,咱们都是基于这个目前的数据去做的。

那么咱们这边的话就是直接基于这个第2点去做吧。

数据定义

我们看到数据定义的代码:

    data_ = [[0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5],[0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 3],[0, 0, 0, 0, 4, 0, 0, 1, 0, 4, 0],[3, 3, 4, 0, 0, 0, 0, 2, 2, 0, 0],[5, 4, 5, 0, 0, 0, 0, 5, 5, 0, 0],[0, 0, 0, 0, 5, 0, 1, 0, 0, 5, 0],[4, 3, 4, 0, 0, 0, 0, 5, 5, 0, 1],[0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 4],[0, 0, 0, 2, 0, 2, 5, 0, 0, 1, 2],[0, 0, 0, 0, 5, 0, 0, 0, 0, 4, 0],[1, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0]]feature = ["女孩类型"+str(i) for i in range(1,len(data_[0])+1)]users = ["用户" + str(i) for i in range(1,len(data_)+1)]data = np.mat(data_)df = pd.DataFrame(data, columns=feature, index=users)print("测试数据为:")print(df)

相似度计算

咱们的相似度是基于这个用户的点赞来算的,群众的眼睛是雪亮的嘛。

def cos_sim(self,x, y):"""计算余弦值(相似度:param x::param y::return:"""return ((x * y.T) / (np.sqrt(x * x.T) * np.sqrt(y * y.T)))[0, 0]def similarity(self,data):"""计算相似度:return:"""m = np.shape(data)[0]simil = np.mat(np.zeros((m, m)))for i in range(m):for j in range(i, m):if j != i:simil[i, j] = self.cos_sim(data[i, :], data[j, :])simil[j, i] = simil[i, j]else:simil[i, j] = 0return simil

这里用的是cos,计算简单一点。

推荐

咱们现在有了这个相似度,我们的相似度矩阵是一个二维的,此时表示的是类别之间的一个关系。
那么此时传入一个用户当前喜欢哪一些类型,计算出这些类型相似的标签,然后做出一个排序,推荐。

   def __recommend(self,data, simil, user):"""根据当前的用户进行一个推荐,通过咱们的这个相似度矩阵,然后进行评分:param data:我们这边是对用户喜欢的女孩类型进行推荐,所以data做了一个转置:param simil:相似度矩阵,我们这里做的是不同女孩类型的相似度:param user:要知道哪些用户的一个推荐:return:interaction: 互动(其实就是原来的表)"""m, n = np.shape(data)interaction = data[:, user].Tpredict = {}not_inter = []for i in range(n):# 用户没有点赞的类型if interaction[0, i] == 0:not_inter.append(i)else:predict[i] = interaction[0,i]# 对点赞进行预测for x in not_inter:for j in range(m):if interaction[0, j] != 0:if x not in predict:predict[x] = simil[x, j] * interaction[0, j]else:predict[x] = predict[x] + simil[x, j] * interaction[0, j]# 按照预测的评分大小从大到小排序return sorted(predict.items(), key=lambda d: d[1], reverse=True)

如果你想基于用户也简单,反一下。

此时我们还可以筛选出前面几个

def RecomtopK(self,user,k):"""推荐前面K个:param predict::param k::return: 返回适合的类型的下标以及对应的评分"""data_T = self.data.Tif(self.simil.all()==None):raise Exception("请先build")predict = self.__recommend(data_T, self.simil, user)top_recom = []len_result = len(predict)if k >= len_result:top_recom = predictelse:for i in range(k):top_recom.append(predict[i])return top_recom

svd奇异值分解优化

之后的话,咱们这里还涉及到一个优化,就是这个svd,主要是计算咱们的这个相似度矩阵的时候的一个优化,通过svd,可以对原来的矩阵进行一个压缩,之后的加速运算得到相似度矩阵。
因为这个协同过滤其实最重要的就是计算出相似度矩阵,之后通过这个矩阵进行一个搜索过滤。

    def __svd(self,data,threshold=0.9):""":param data: :param threshold: 保留多少特征:return: """n = np.shape(data)[1]U, Sigma, VT = np.linalg.svd(data)sig2 = Sigma ** 2cut = 0for i in range(n):if sum(sig2[:i]) / sum(sig2) > threshold :cut = ibreakSig4 = np.mat(np.eye(cut) * Sigma[:cut])xformedItems = data.T * U[:, :cut] * Sig4.Isvd_data = xformedItems.Treturn svd_data

完整代码

之后是完整的代码:

import numpy as np
import pandas as pdclass RecmBaseDome(object):def __init__(self,data):self.data = dataself.simil = Nonedef cos_sim(self,x, y):"""计算余弦值(相似度:param x::param y::return:"""return ((x * y.T) / (np.sqrt(x * x.T) * np.sqrt(y * y.T)))[0, 0]def similarity(self,data):"""计算相似度:return:"""m = np.shape(data)[0]simil = np.mat(np.zeros((m, m)))for i in range(m):for j in range(i, m):if j != i:simil[i, j] = self.cos_sim(data[i, :], data[j, :])simil[j, i] = simil[i, j]else:simil[i, j] = 0return simildef __recommend(self,data, simil, user):"""根据当前的用户进行一个推荐,通过咱们的这个相似度矩阵,然后进行评分:param data:我们这边是对用户喜欢的女孩类型进行推荐,所以data做了一个转置:param simil:相似度矩阵,我们这里做的是不同女孩类型的相似度:param user:要知道哪些用户的一个推荐:return:interaction: 互动(其实就是原来的表)"""m, n = np.shape(data)interaction = data[:, user].Tpredict = {}not_inter = []for i in range(n):# 用户没有点赞的类型if interaction[0, i] == 0:not_inter.append(i)else:predict[i] = interaction[0,i]# 对点赞进行预测for x in not_inter:for j in range(m):if interaction[0, j] != 0:if x not in predict:predict[x] = simil[x, j] * interaction[0, j]else:predict[x] = predict[x] + simil[x, j] * interaction[0, j]# 按照预测的评分大小从大到小排序return sorted(predict.items(), key=lambda d: d[1], reverse=True)def __svd(self,data,threshold=0.9):""":param data: :param threshold: 保留多少特征:return: """n = np.shape(data)[1]U, Sigma, VT = np.linalg.svd(data)sig2 = Sigma ** 2cut = 0for i in range(n):if sum(sig2[:i]) / sum(sig2) > threshold :cut = ibreakSig4 = np.mat(np.eye(cut) * Sigma[:cut])xformedItems = data.T * U[:, :cut] * Sig4.Isvd_data = xformedItems.Treturn svd_datadef build(self,svd=True,threshold=0.9):"""构建这个推荐系统(表):param svd: 要不要使用svd对数据进行一个压缩:param threshold: :return: """svd_data = self.dataif(svd):svd_data = self.__svd(self.data,threshold)svd_data = svd_data.Tself.simil = self.similarity(svd_data)def RecomtopK(self,user,k):"""推荐前面K个:param predict::param k::return: 返回适合的类型的下标以及对应的评分"""data_T = self.data.Tif(self.simil.all()==None):raise Exception("请先build")predict = self.__recommend(data_T, self.simil, user)top_recom = []len_result = len(predict)if k >= len_result:top_recom = predictelse:for i in range(k):top_recom.append(predict[i])return top_recomif __name__ == '__main__':data_ = [[0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5],[0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 3],[0, 0, 0, 0, 4, 0, 0, 1, 0, 4, 0],[3, 3, 4, 0, 0, 0, 0, 2, 2, 0, 0],[5, 4, 5, 0, 0, 0, 0, 5, 5, 0, 0],[0, 0, 0, 0, 5, 0, 1, 0, 0, 5, 0],[4, 3, 4, 0, 0, 0, 0, 5, 5, 0, 1],[0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 4],[0, 0, 0, 2, 0, 2, 5, 0, 0, 1, 2],[0, 0, 0, 0, 5, 0, 0, 0, 0, 4, 0],[1, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0]]feature = ["女孩类型"+str(i) for i in range(1,len(data_[0])+1)]users = ["用户" + str(i) for i in range(1,len(data_)+1)]data = np.mat(data_)df = pd.DataFrame(data, columns=feature, index=users)print("测试数据为:")print(df)#每次上面那个pd就是拿来看的recbase = RecmBaseDome(data)recbase.build()top_recom = recbase.RecomtopK(0,3)print(top_recom)#接下来看看这个用户0(用户1)适合的类型是啥items  = []for top in top_recom:items.append(feature[top[0]])print(items)

之后是咱们的一个测试:

我们测试的是用户1

0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5

可以发现这个用户对于类型6的女孩也是有点赞的而且点赞了3次,但是top3却没有这个类型6。这个也印证了前面说的,可能更加适合的在后面,那么依据是什么呢,很简单“群众的眼睛是雪亮的”,类型6可能存在一定的问题,当然也有可能是说,你最先发现了类型6的好,她可能是影藏款,但是随着数据量加大,这种可能性还是比较低的。

总结

水完了一个dome,下班~

胡扯推荐算法(协同)及其dome实现相关推荐

  1. 推荐系统 --- 推荐算法 --- 基于用户行为的推荐算法 - 协同过滤算法

    概述 历史 1992年,Goldberg.Nicols.Oki及Terry提出 基本思想 爱好相似的用户喜欢的东西可能也会喜欢 优点 共享朋友的经验,提高推荐的准确度 根据爱好相似的用户喜欢的视频进行 ...

  2. 经典推荐算法-协同过滤

    协同过滤算法 1.传统推荐模型的演化关系图 2. 协同过滤 2.1 什么是协同过滤 2.2 计算用户相似度 2.3 最终结果排序 2.4 存在缺点 2.5 ItemCF 2.6 各自的应用场景 1.传 ...

  3. 基于神经网络的推荐算法,协同过滤推荐算法python

    大数据运维的主要工作内容是什么? . 大数据相关工作岗位很多,有大数据分析师.大数据挖掘算法工程师.大数据研发工程师.数据产品经理.大数据可视化工程师.大数据爬虫工程师.大数据运营专员.大数据架构师. ...

  4. 个性化试题推荐系统 协同过滤推荐算法在在线考试系统中的运用 基于用户/项目的协同过滤推荐算法 混合协同过滤推荐算法 协同过滤混合推荐算法

    个性化试题推荐系统 协同过滤推荐算法在在线考试系统中的运用 一.项目开发技术及功能介绍 1.SSH开发框架(spring+struts+hibernate) 2.js.jquery.bootstrap ...

  5. 个性化推荐算法-协同过滤

    协同过滤Collaborative filtering ItemCF 基础公式 Sij:物品i & 物品j 的相似度. 分子:浏览过物品i 与 浏览过物品j的用户的交集. 分母:浏览过物品i ...

  6. 【推荐算法】协同过滤算法——基于用户 Java实现

    只是简单谢了一个Demo,先贴上GitHub地址. https://github.com/wang135139/recommend-system 基本概念就不过多介绍了,相信能看明白的都了解.如果想了 ...

  7. 毕业设计 推荐系统设计与实现 协同过滤推荐算法

    文章目录 0 前言 简介 常见推荐算法 协同过滤 分解矩阵 聚类 深度学习 协同过滤原理 系统设计 示例代码(py) 系统展示 系统界面 推荐效果 最后 0 前言

  8. 协同过滤推荐算法:UserCF、ItemCF python现实

    目录 一.协同过滤算法 二.基于邻域的算法:UserCF.ItemCF 三.UserCF.ItemCF的改进 一.协同过滤推荐算法 协同过滤算法是指基于用户行为数据设计的推荐算法,主要包括: 1.基于 ...

  9. 协同过滤推荐算法和基于内容推荐算法的区别?

    文章最前: 我是Octopus,这个名字来源于我的中文名--章鱼:我热爱编程.热爱算法.热爱开源.所有源码在我的个人github :这博客是记录我学习的点点滴滴,如果您对 Python.Java.AI ...

最新文章

  1. 麒麟处理器是基于arm的吗_麒麟芯片是基于ARM构架,如果得不到授权华为还能活吗?...
  2. 100W无线充电方案文献调研 - 信息HUB
  3. Sharding-JDBC 1.3.0发布——支持读写分离
  4. Linux的文本字段统计方法
  5. 上标3下标6算法_插入排序算法导学案
  6. RocketMQ-初体验RocketMQ(11)-过滤消息_自定义Java类筛选消息
  7. python教程:apscheduler模块使用教程
  8. lightGBM GPU支持的安装、验证方法
  9. 电路串联和并联图解_负反馈型三极管放大电路的识图方法
  10. Spring Cloud实战Zuul统一异常处理
  11. Ansible@一个高效的配置管理工具--Ansible configure management--翻译(十一)
  12. linux每日命令(28):chgrp命令
  13. python编辑程序用print函数输出中国加油武汉加油_python练习1之print函数
  14. 单点登录系统原理与接入
  15. 解决vscode的报错:Java 11 or more recent is required to run the Java extension
  16. 刘洪波《英文字根词源精讲》完整目录
  17. word中设置页眉页脚奇偶页不同,页脚为页码时偶数页不显示一招解决
  18. CREO:CREO软件之零件【工具(调查/模型意图/实用工具)】、【视图(可见性/方向/模型显示/显示/窗口)】的简介及其使用方法(图文教程)之详细攻略
  19. 微软与网景关于浏览器的恩怨情仇
  20. 日期控件--WdatePicker的使用小技能

热门文章

  1. Cesium 修改当前时间,显示北京时间
  2. 【华为OD机试真题 JS】仿LISP运算
  3. asp mysql 可编辑树状,基于数据库动态生成树形目录-ASP教程,数据库相关
  4. Kinect结合Unity开发(一)
  5. 某公司变电所运维云平台的应用
  6. 【内网穿透笔记】虚假公网IP体验动态域名解析
  7. Office365客户端激活失败
  8. 公网中的Winbox
  9. android微信如何禁用拍一拍,微信拍一拍怎么样关闭 微信拍一拍功能关闭方法
  10. 在linux在安装打印机驱动