技术标签: LFM breadcrumb 推荐系统 Play Me —— Algorithm and Structure
所有源码都在github上(https://github.com/seasonyao/recommended-system)
代码环境:windows环境下python3.5,安装numpy和sklearn即可
源码、数据、结果:https://download.csdn.net/download/codes_first/10741150
各个读入文件的格式如下:
一、代码理论模型(参考书本《推荐系统实践》以及《机器学习》中理论内容,可跳过看后文具体思路和实现)
1.LFM
对于一个给定的用户行为数据集(数据集包含的是所有的user, 所有的item,以及每个user有过行为的item列表),使用LFM对其建模后,我们可以得到如下图所示的模型:(假设数据集中有3个user, 4个item, LFM建模的分类数为4)
R矩阵是user-item矩阵,矩阵值Rij表示的是user i 对item j的兴趣度,这正是我们要求的值。对于一个user来说,当计算出他对所有item的兴趣度后,就可以进行排序并作出推荐。LFM算法从数据集中抽取出若干主题,作为user和item之间连接的桥梁,将R矩阵表示为P矩阵和Q矩阵相乘。其中P矩阵是user-class矩阵,矩阵值Pij表示的是user i对class j的兴趣度;Q矩阵式class-item矩阵,矩阵值Qij表示的是item j在class i中的权重,权重越高越能作为该类的代表。所以LFM根据如下公式来计算用户U对物品I的兴趣度
我们发现使用LFM后,
1. 我们不需要关心分类的角度,结果都是基于用户行为统计自动聚类的,全凭数据自己说了算。
2. 不需要关心分类粒度的问题,通过设置LFM的最终分类数就可控制粒度,分类数越大,粒度约细。
3. 对于一个item,并不是明确的划分到某一类,而是计算其属于每一类的概率,是一种标准的软分类。
4. 对于一个user,我们可以得到他对于每一类的兴趣度,而不是只关心可见列表中的那几个类。
5. 对于每一个class,我们可以得到类中每个item的权重,越能代表这个类的item,权重越高。
那么,接下去的问题就是如何计算矩阵P和矩阵Q中参数值。一般做法就是最优化损失函数来求参数。在定义损失函数之前,我们需要准备一下数据集并对兴趣度的取值做一说明。
数据集应该包含所有的user和他们有过行为的(也就是喜欢)的item。所有的这些item构成了一个item全集。对于每个user来说,我们把他有过行为的item称为正样本,规定兴趣度RUI=1,此外我们还需要从item全集中随机抽样,选取与正样本数量相当的样本作为负样本,规定兴趣度为RUI=0。因此,兴趣的取值范围为[0,1]。
采样之后原有的数据集得到扩充,得到一个新的user-item集K={(U,I)},其中如果(U,I)是正样本,则RUI=1,否则RUI=0。损失函数如下所示:
上式中的是用来防止过拟合的正则化项,λ需要根据具体应用场景反复实验得到。损失函数的优化使用随机梯度下降算法:
1. 通过求参数PUK和QKI的偏导确定最快的下降方向;
2. 迭代计算不断优化参数(迭代次数事先人为设置),直到参数收敛。
其中,α是学习速率,α越大,迭代下降的越快。α和λ一样,也需要根据实际的应用场景反复实验得到。
LFM的伪代码可以表示如下:
2.Kmeans
K-Means算法的基本思想是初始随机给定K个簇中心,按照最邻近原则把待分类样本点分到各个簇。然后按平均法重新计算各个簇的质心,从而确定新的簇心。一直迭代,直到簇心的移动距离小于某个给定的值。
K-Means聚类算法主要分为三个步骤:
(1)第一步是为待聚类的点寻找聚类中心
(2)第二步是计算每个点到聚类中心的距离,将每个点聚类到离该点最近的聚类中去
(3)第三步是计算每个聚类中所有点的坐标平均值,并将这个平均值作为新的聚类中心
(4)反复执行(2)、(3),直到聚类中心不再进行大范围移动或者聚类次数达到要求为止
二、思路分析和遇到的问题
在开始正式讲代码之前,先来说说对几个细节问题的解决思路:
1.根据数据集初始化P和Q矩阵
这个初始化其实耗费了巨量的写代码时间,我的思路是
(1)对于P矩阵,对每一个用户计算其自己评分的平均值,然后用户对每个class的评分就以平均值为基础进行正态分布的随机值取值。
(2)对于Q的初始化前前后后做了很多工作:一开始就是以所有评分的平均值进行正态随机值(显然这和理论不符合,理论上Q是概率矩阵,也就是某个item所有class加起来要为1,但一开始就先简单赋予初值了)。后来结合itemAtrribute的文件,首先对这个文件里的item进行聚类(使用kmean),对于聚类结果我的利用方式有两种:
(a)一种是根据聚类结果把item分为150个class(为什么是150后文有解释),那么对于Q矩阵的初始化就可以按照我们的理论进行初始化了:某个item根据聚类结果属于某个class(又出现在itemAttribute最好,没有也可以和150个中心点算距离得到类别),将这个class对应的数设为某个参数
文章浏览阅读533次。0.引言//输出是优化过后的相机位姿//这里得到的是第l帧坐标系到各帧的变换矩阵,应将其转变为各帧在第l帧坐标系上的位姿for (int i = 0; i < frame_num; i++){ q[i].w() = c_rotation[i][0]; q[i].x() = c_rotation[i][1]; q[i].y() = c_rotation[i][2]; q[i].z() = c_rotation[i][3]; q[i] = q[i].inverse();}fo_vins extrinsicrotation
文章浏览阅读4.7k次。本地OTA升级:(从别人文档复制过来的)百度云链接: 提取码: qqyt一:准备安卓手机一台(包括小米手机)二:安装对应小爱同学(安卓版 2.9.21版本)三:将“小米蓝牙耳机Air2Pro固件(3.0.11.0).zip”解压,将其中的EM028。。。。。。.bin文件存入手机的某个目录本地OTA升级具体操作步骤如下(小米手机):在进行以下步骤前,首先到设置-应用设置-应用管理把系统原来的小爱同学卸载更新(没有卸载更新的清楚全部数据),然后安装升级文件中的小爱同学APP(该apk._小米air2pro固件包
文章浏览阅读297次。众所周知,光纤是具有不导电性的,可以免受冲击电流,光缆也具有良好的防护性能,光缆中的金属构件对地绝缘值较高,雷电流不易进入光缆,但因为光缆具有加强芯,特别是直埋光缆具有铠装层,因而在光缆线路遭雷击时,也能发生光缆被烧毁或损坏的情况。那么,我们该如何预防光纤光缆布线中的雷击伤害呢?接下来我们就跟随飞畅科技的小编一起来看看吧! 随着网络的发展,光纤作为综合布线系统中用来传输数据的一种介质,因为去具有传输速率大,距离远等优点,越来越受人们的使用。众所周知,光纤是具有不导电性的,可以免受冲击电流,光缆也具_光纤收发器容易被雷击
文章浏览阅读1.5w次,点赞13次,收藏61次。? x:y 类似于if语句,例如: x>9?50:100; 意思是x是否大于9 ,是的话就输出50,不是的话就输出100;字母与数字比较大小,实际比较ASCII码值大小,字母都大于数字。c语言中,!的作用是逻辑非,例如:!a 凡是a不等于0,那么输出都是0,只有当a等于0时,输出的才是0; !=意思是不等于,一般应用与判断 if(a!=b); c语言中,&&表示逻辑且_c语言中并集符号
文章浏览阅读4.3k次。在项目中,需要将一个svn上的文件checkout下来,替换另一个svn上的对应文件。如果直接cp过去,会发现替换的文件无法commit到新svn。通过svn info命令发现,文件的svn路径依然是原来svn的。 碰到该问题,可通过如下步骤进行操作:(自己做个记录,以备将来复用)1、删除文件下名为.svn的隐藏文件。.svn文件是subversion的版本控制信息文件,.svn_svn怎么替换原有文件
文章浏览阅读2k次,点赞5次,收藏9次。基于Raft共识算法搭建多机Fabric1.4.1网络环境fabric官方继fabric1.4LTS版本之后,又推出了fabric1.4.1的正式补丁版本,虽然fabric1.4.1是fabric1.4后续的补丁版本,但是这一小版本更新了fabric1.4.0版本没有完成的工作,,比如Raft共识,从fabric0.6版本开始,共识推出过BFT算法,用于实现拜占庭容错,但由于性能原因在后续版本..._lpgsy
文章浏览阅读331次。27 同构渲染架构:实现一个 SSR 应用从这一讲开始,我们正式进入 Node.js 主题学习。作为 Node.js 技术的重要应用场景,同构渲染 SSR 应用尤其重要。不管是服务端渲染还是服务端渲染衍生出的同构应用,现在来看已经并不新鲜了,实现起来也并不困难。可是有的开发者认为:同构应用不就是调用一个renderToString(React 中)类似的 API 吗?讲道理,确实如此,但同构应用也不只是这么简单。就拿面试来说,同构应用的考察点不是“纸上谈兵”的理论,而是实际实施时的细节。这一讲我们就来_perf-patronus
文章浏览阅读435次。RESTful API 是一套规范,它可以规范我们如何对服务器上的资源进行操作。在了解 RESTful API 之前,我先为你介绍下 HTTP Method,因为 RESTful API 和它是密不可分的。说起 HTTP Method,最常见的就是POST和GET,其实最早在 HTTP 0.9 版本中,只有一个GET方法,该方法是一个幂等方法,用于获取服务器上的资源,也就是我们在浏览器中直接输入网址回车请求的方法。在 HTTP 1.0 版本中又增加了HEAD和POST。_go访问restful接口
文章浏览阅读451次。15 三角形作者: ZhuKai时间限制: 10S章节: 循环问题描述 :“明明,你会用1到9这九个数字组成一个三角形吗?”明明的爸爸问明明。明明被问的很莫名其妙,不明白他爸爸在说什么,于是就问道:“用1到9组成三角形???”“是的,我的要求很简单,给你2个数,一个数作为这个三角形的开始,另一个数决定这个三角形的大小。例如我给你5和6这两个数,你就要组成如下的一个三角形:5 6 7 8 ..._“明明,你会用1到9这九个数字组成一个三角形吗?”明明的爸爸问明明。明明被问的很
文章浏览阅读694次。一、安装Ubuntu系统win7下通过easyBCD引导安装Ubuntu14.04U盘 + UltraISO 装机参考文献 ubuntu的su初始密码设置 设置相关密码如下:moa-android-server 123456su 123456常见命令sudo nautilus root方式开启文件系统sudo gedit /etc/profile 环境变量配置ls -al 显_jenkins unzipping /root/.gradle/wrapper/dists/gradle-
文章浏览阅读356次。近些年,除了商科之外,被中国留学生追捧的就是计算机专业,据统计显示,计算机科学是就业市场需求最多的专业之一。美国的计算机技术在世界一直位居前列,因此,很多留学生前往美国深造计算机科学专业,可是,如何选择一所好的大学成为了留学生首要考虑的问题,那么,接下来,就随小编来看看美国大学研究生计算机科学专业排名,希望对大家有所帮助:2018年USNews美国大学研究生计算机科学专业排名:排名 学校英文名 学...
文章浏览阅读81次。Shell变量变量介绍什么是变量变量即变化的量,核心是“变”与“量”二字,变即变化,量即衡量状态。量:是记录现实世界当中的某种状态变:指的是记录的状态是可以发生变化的为什么要使用变量变量名=变量值变量名:相当于一个门牌号,便于取出变量值,是访问到值的唯一方式=:赋值符号变量值:用来表示状态定义变量名规范大前提::变量名的命名应该能够反映出值记录的状态。变量是用来访问变量值的,所以变量名应该遵循一定规范,来方便我们标识存到内存中值的功能。# shell定义变量1.不能以数字开头_shell histcontrol