Collaborative Filtering Recommendation

度量向量之间的相似度方法很多了,你可以用距离(各种距离)的倒数,向量夹角,Pearson相关系数等。

皮尔森相关系数计算公式如下:

ρX,Y=cov(X,Y)σxσy=E((X−μx)(Y−μy))σxσy(1)

分子是协方差,分子是两个变量标准差的乘积。显然要求X和Y的标准差都不能为0。

因为μX=E(X),σ2X=E(X−μX)2=E(X2)−E2(X)所以皮尔森相关系数计算公式还可以写成:

ρX,Y=E(XY)−E(X)E(Y)E(X2)−E2(X)−−−−−−−−−−−−−√E(Y2)−E2(Y)−−−−−−−−−−−−√(2)

当两个变量的线性关系增强时,相关系数趋于1或-1。

Pearson相关系数有个特点,它在计算两个数列的相似度时忽略其平均值的差异。比如说有的用户对商品评分普遍偏低,有的用户评分普遍偏高,而实际上他们具有相同的爱好,他们的Pearson相关系数会比较高。用户1对某一个商品的评分是X=(1,2,3),用户2对这三个商品的评分是Y=(4,5,6),则X和Y的Pearson相关系数是0.865,相关性还是挺高的。

  iterm1 ………… itemn
user1 R11   R1n
……   Rij  
userm Rm1   Rmn

用户评分数据矩阵

基于用户的协同过滤

step1.如果用户i对项目j没有评过分,就找到与用户i最相似的K个邻居(采用Pearson相关系数)

step2.然后用这K个邻居对项目j的评分的加权平均来预测用户i对项目j的评分。

U1=(r1,1,r1,2...r1,n)

U2=(r2,1,r2,2...r2,n)

要预测用户u对商品i的评分ru,i

用户u对所有商品的平均得分为ru¯

用户x评分的商品集合为Ix,用户y评分的商品集合为Iy,其并集为Ixy

采用Pearson相关系数用户x和y的相似度:

sim(x,y)=∑i∈Ixy(rx,i−rx¯)(ry,i−ry¯)∑i∈Ixy(rx,i−rx¯)2∑i∈Ixy(ry,i−ry¯)2−−−−−−−−−−−−−−−−−−−−−−−−−−−−−√(3)

ru,i=ru¯+z∑u′∈Usim(u,u′)(ru′,i−ru′¯)(4)

其中U是用户u的近邻,z是归一化因子,z=1∑u′∈Usim(u,u′)

这各预测方法充分考虑了用户一向的评分习惯是偏高还是偏低,因为用户u的近邻对u产生影响时已经减去了各自的平均值。

计算用户U1和U2的相似度时并不是去拿原始的评分向量去计算,而是只关注他们的评交集Ix,y,这是因为一个用户只对很少的物品有过评分,这样用户评分向量是个高度稀疏的向量,采用Pearson相关系数计算两个用户的相似度时很不准。

基于物品的协同过滤

step1.如果用户i对项目j没有评过分,就把ri,j置为0。找到与物品j最相似的k个近邻(采用余弦距离)

step2.然后用这K个邻居对项目j的评分的加权平均来预测用户i对项目j的评分。

I1=(r1,1,r2,1...rm,1)

I2=(r1,2,r2,2...rm,2)

每一项减去各个用户评分的均值:

I1=(r1,1−r1¯,r2,1−r2¯...rm,1−rm¯)

I2=(r1,2−r1¯,r2,2−r2¯...rm,2−rm¯)

商品i和j之间的相似度采用余弦计算:

sim(i,j)=∑x(rx,i−rx¯)(rx,j−rx¯)∑x(rx,i−rx¯)2∑x(rx,j−rx¯)2−−−−−−−−−−−−−−−−−−−−−−−√(5)

预测用户u对商品i的评分:

ru,i=∑i′∈Nsim(i,i′)ru,i′∑i′∈Nsim(i,i′)(6)

其中N是商品i的近邻。

由于物品之间的相似度比较稳定,可以离线先算好,定期更新即可。在电商行业这种算法用的比较多。

混合协同过滤

所谓的混合算法,主体思路还是基于用户的协同过滤,只是在计算两个用户的相似度时又嵌套了item-based CF思想。

度量用户i和用户j相似度更好的方法是:

1.用户i参与评分的项目集合为Ii,用户j参与评分的项目集合为Ij,找到它们的并集Uij=Ii∪Ij

2.在集合Uij中用户i未评分的项目是Ni=Uij−Ii,采用item-based CF方法重新估计用户i对Ni中每个项目的评分。

3.这样用户i和j对Uij的评分就都是非0值了,在此情况下计算他们的相似度。

示例代码:

#include<iostream>
#include<queue>
#include<cmath>
#include<cassert>
#include<cstdlib>
#include<fstream>
#include<sstream>
#include<vector>
#include<algorithm>using namespace std;const int ITERM_SIZE=1682;
const int USER_SIZE=943;
const int V=15;        //ITERM的最近邻居数
const int S=10;        //USER的最近邻居数struct MyPair{int id;double value;MyPair(int i=0,double v=0):id(i),value(v){}
};struct cmp{bool operator() (const MyPair & obj1,const MyPair & obj2)const{return obj1.value < obj2.value;}
};double rate[USER_SIZE][ITERM_SIZE];    //评分矩阵
MyPair nbi[ITERM_SIZE][V];            //存放每个ITERM的最近邻居
MyPair nbu[USER_SIZE][S];            //存放每个USER的最近邻居
double rate_avg[USER_SIZE];            //每个用户的平均评分//从文件中读入评分矩阵
int readRate(string filename){ifstream ifs;ifs.open(filename.c_str());if(!ifs){cerr<<"error:unable to open input file "<<filename<<endl;return -1;}string line;while(getline(ifs,line)){string str1,str2,str3;istringstream strstm(line);strstm>>str1>>str2>>str3;int userid=atoi(str1.c_str());int itermid=atoi(str2.c_str());double rating=atof(str3.c_str());rate[userid-1][itermid-1]=rating;line.clear();}ifs.close();return 0;
}//计算每个用户的平均评分
void getAvgRate(){for(int i=0;i<USER_SIZE;++i){double sum=0;for(int j=0;j<ITERM_SIZE;++j)sum+=rate[i][j];rate_avg[i]=sum/ITERM_SIZE;}
}//计算两个向量的皮尔森相关系数
double getSim(const vector<double> &vec1,const vector<double> &vec2){int len=vec1.size();assert(len==vec2.size());double sum1=0;double sum2=0;double sum1_1=0;double sum2_2=0;double sum=0;for(int i=0;i<len;i++){sum+=vec1[i]*vec2[i];sum1+=vec1[i];sum2+=vec2[i];sum1_1+=vec1[i]*vec1[i];sum2_2+=vec2[i]*vec2[i];}double ex=sum1/len;double ey=sum2/len;double ex2=sum1_1/len;double ey2=sum2_2/len;double exy=sum/len;double sdx=sqrt(ex2-ex*ex);double sdy=sqrt(ey2-ey*ey);assert(sdx!=0 && sdy!=0);double sim=(exy-ex*ey)/(sdx*sdy);return sim;
}//计算每个ITERM的最近邻
void getNBI(){for(int i=0;i<ITERM_SIZE;++i){vector<double> vec1;priority_queue<MyPair,vector<MyPair>,cmp> neighbour;for(int k=0;k<USER_SIZE;k++)vec1.push_back(rate[k][i]);for(int j=0;j<ITERM_SIZE;j++){if(i==j)continue;vector<double> vec2;for(int k=0;k<USER_SIZE;k++)vec2.push_back(rate[k][j]);double sim=getSim(vec1,vec2);MyPair p(j,sim);neighbour.push(p);}for(int j=0;j<V;++j){nbi[i][j]=neighbour.top();neighbour.pop();}}
}//预测用户对未评分项目的评分值
double getPredict(const vector<double> &user,int index){double sum1=0;double sum2=0;for(int i=0;i<V;++i){int neib_index=nbi[index][i].id;double neib_sim=nbi[index][i].value;sum1+=neib_sim*user[neib_index];sum2+=fabs(neib_sim);}return sum1/sum2;
}//计算两个用户的相似度
double getUserSim(const vector<double> &user1,const vector<double> &user2){vector<double> vec1;vector<double> vec2;int len=user1.size();assert(len==user2.size());for(int i=0;i<len;++i){if(user1[i]!=0 || user2[i]!=0){if(user1[i]!=0)vec1.push_back(user1[i]);elsevec1.push_back(getPredict(user1,i));if(user2[i]!=0)vec2.push_back(user2[i]);elsevec2.push_back(getPredict(user2,i));}}return getSim(vec1,vec2);
}//计算每个USER的最近邻
void getNBU(){for(int i=0;i<USER_SIZE;++i){vector<double> user1;priority_queue<MyPair,vector<MyPair>,cmp> neighbour;for(int k=0;k<ITERM_SIZE;++k)user1.push_back(rate[i][k]);for(int j=0;j<USER_SIZE;++j){if(j==i)continue;vector<double> user2;for(int k=0;k<ITERM_SIZE;++k)user2.push_back(rate[j][k]);double sim=getUserSim(user1,user2);MyPair p(j,sim);neighbour.push(p);}for(int j=0;j<S;++j){nbu[i][j]=neighbour.top();neighbour.pop();}}
}//产生推荐,预测某用户对某项目的评分
double predictRate(int user,int iterm){double sum1=0;double sum2=0;for(int i=0;i<S;++i){int neib_index=nbu[user][i].id;double neib_sim=nbu[user][i].value;sum1+=neib_sim*(rate[neib_index][iterm]-rate_avg[neib_index]);sum2+=fabs(neib_sim);}return rate_avg[user]+sum1/sum2;
}//测试
int main(){string file="/home/orisun/DataSet/movie-lens-100k/u.data";if(readRate(file)!=0){return -1;}getAvgRate();getNBI();getNBU();while(1){cout<<"please input user index and iterm index which you want predict"<<endl;int user,iterm;cin>>user>>iterm;cout<<predictRate(user,iterm)<<endl;}return 0;
}

协同过滤推荐算法-----向量之间的相似度相关推荐

  1. 从原理到落地,七大维度读懂协同过滤推荐算法

    作者丨gongyouliu 来源 | 大数据与人工智能 导语:本文会从协同过滤思想简介.协同过滤算法原理介绍.离线协同过滤算法的工程实现.近实时协同过滤算法的工程实现.协同过滤算法应用场景.协同过滤算 ...

  2. 推荐算法工程师必备!!!协同过滤推荐算法总结

    推荐算法具有非常多的应用场景和商业价值,因此对推荐算法值得好好研究.推荐算法种类很多,但是目前应用最广泛的应该是协同过滤类别的推荐算法,本文就对协同过滤类别的推荐算法做一个概括总结,后续也会对一些典型 ...

  3. 协同过滤推荐算法及应用

    1. CF协同过滤推荐算法原理 1.1 概述 什么是协同过滤 (Collaborative Filtering, 简称 CF)? 首先想一个简单的问题,如果你现在想看个电影,但你不知道具体看哪部,你会 ...

  4. 基于云模型的协同过滤推荐算法代码实现(附源代码)

    基于云模型的协同过滤推荐算法代码实现(附源代码) 一.云模型介绍 针对传统推荐系统数据稀疏.相似性计算方法导致共同评分用户少的问题,提出利用云模型概念与定量数值转换的优势,研究云模型(百度百科查看概念 ...

  5. 什么是协同过滤推荐算法?

    剖析千人千面的大脑--推荐引擎部分,其中这篇是定位:对推荐引擎中的核心算法:协同过滤进行深挖. 首先,千人千面融合各种场景,如搜索,如feed流,如广告,如风控,如策略增长,如购物全流程等等:其次千人 ...

  6. java 用户协同过滤算法_基于用户的协同过滤推荐算法java实现(UserCF)

    UserCF的核心思想即为根据用户数据模拟向量相似度,我们根据这个相似度,来找出指定用户的相似用户,然后将相似用户买过的而指定用户没有买的东西推荐给指定用户,推荐度的计算也是结合了相似用户与指定用户的 ...

  7. 基于用户的协同过滤推荐算法java实现(UserCF)

    UserCF的核心思想即为根据用户数据模拟向量相似度,我们根据这个相似度,来找出指定用户的相似用户,然后将相似用户买过的而指定用户没有买的东西推荐给指定用户,推荐度的计算也是结合了相似用户与指定用户的 ...

  8. 05-机器学习_(协同过滤推荐算法与应用)---没用

    机器学习算法day03_协同过滤推荐算法及应用 课程大纲 协同过滤推荐算法原理 协同过滤推荐算法概述 协同过滤推荐算法思想 协同过滤推荐算法分析 协同过滤推荐算法要点 协同过滤推荐算法实现 协同过滤推 ...

  9. 从原理到实现,详解基于朴素ML思想的协同过滤推荐算法

    作者丨gongyouliu 编辑丨Zandy 来源 | 大数据与人工智能(ID: ai-big-data) 作者在<协同过滤推荐算法>.<矩阵分解推荐算法>这两篇文章中介绍了几 ...

  10. 【知识发现】基于用户的协同过滤推荐算法python实现

    1.协同过滤推荐算法分为两类,分别是基于用户的协同过滤算法(user-based collaboratIve filtering),和基于物品的协同过滤算法(item-based collaborat ...

最新文章

  1. Gartner 2019 年供应链技术八大趋势:AI、高级分析、物联网、RPA、自主设备、数字孪生...
  2. spring data mongo比较两个字段查询
  3. 微软嵌入式WEC2013产品研讨会(深圳站---2013.10.16)
  4. 巧用DOS命令合并多个文本文件的内容
  5. 闪电网络介绍以及试用 (下)
  6. StandardContext
  7. jQuery验证用户名是否可用
  8. boost::mpl模块实现list_c相关的测试程序
  9. c语言死循环中输入字符,如下代码,如果输入字符,为什么会造成死循环?
  10. 程序员的算法课(15)-分治法获取文件中出现频次最高100词
  11. 多线程bug处理记录
  12. java处理pdf文件——iText的使用
  13. ImportError: cannot import name ‘XGBClassifier‘
  14. C#匿名委托,匿名函数,lambda表达式
  15. 微信小程序毕业设计 基于微信小程序外卖点餐系统开题报告
  16. 硕士期间两篇计算机sci二区,我院青年教师陈新华今年连续两篇论文在中科院二区SCI期刊见刊...
  17. Android 9 (P) recovery升级Map of ‘@/cache/recovery/block.map‘ failed问题分析指南
  18. 人工智能在计算机领域的应用论文,人工智能应用领域论文 关于人工智能领域的大学论文...
  19. 21、人类简史-从动物到上帝(赫拉利)
  20. ps4 优酷 html5,ps4-hen-vtx/index.html at master · xvortex/ps4-hen-vtx · GitHub

热门文章

  1. Linux常用命令介绍(三)——基础操作命令
  2. VGMP报文封装格式简介
  3. python supper()函数
  4. nodejs操作redis总结
  5. [转载]敏捷开发,你真的做对了吗?
  6. Ubuntu16.04下 编译安装 Tensorflow
  7. 【撸码师的备忘录】JedisPool.returnResource()遭弃用
  8. 使用result配置结果视图
  9. Spring 的 ApplicationEvent and ApplicationListener
  10. leetcode------Binary Tree Level Order Traversal II