C/C++知识点之SlopeOne推荐算法实现(C++)
小标 2019-01-10 来源 : 阅读 1356 评论 0

摘要:本文主要向大家介绍了 C/C++知识点之SlopeOne推荐算法实现(C++),通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

本文主要向大家介绍了 C/C++知识点之SlopeOne推荐算法实现(C++),通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

C/C++知识点之SlopeOne推荐算法实现(C++)

SlopeOne算法是一个非常简单的协同过滤算法,主要思想如下:如果用户u对物品j打过分,现在要对物品i打分,那么只需要计算出在同时对物品i和j打分的这种人中,他们的分数之差平均是多少,那么我们就可以根据这个分数之差来计算用户u对物品i的打分了,当然,这样的物品j也有很多个,那有的物品和j共同打分的人少,有的物品和j共同打分的人多,那么显而易见,共同打分多的那个物品在评分时所占的比重应该大一些。

如上就是简单的SlopeOne算法的主要思想,用维基百科上的一张图来表示(一看就懂):

途中用户B要对物品J进行评分,那么这时候发现物品i被用户B打为2分,而同时发现用户A同时评价了物品i和物品j,且物品i比物品j少了0.5分,那么由此看来,用户B给物品j打得分应该就是比给物品i打的分高0.5分,故是2.5分。
由于思想是如此简单,故我们就来实践一把,当然这里就是最最朴素的实现,只是为了检测下算法效果如何。。。数据集还是如上篇博客一样,用的是movielens里面的小数据集,其中有1000用户对2000物品的评分,80%用来训练,20%用来测试。
具体代码如下:
#include 
#include 
#include 
#include 
using namespace std;
const int USERMAX = 1000;
const int ITEMMAX = 2000;
double rating[USERMAX][ITEMMAX];
int I[USERMAX][ITEMMAX];//indicate if the item is rated
double mean;

double predict(int u, int l)
{
 double total = 0;
 double totalCnt = 0;
 for (int i = 0; i < ITEMMAX; i++)
 {
  if (l != i&&I[u][i])
  {
   double dev = 0;
   int cnt = 0;
   for (int j = 0; j < USERMAX; j++)
   {
    if (I[j][l] && I[j][i])
    {
     dev += rating[j][i]-rating[j][l];
     cnt++;
    }
   }
   if (cnt)
   {
    dev /= cnt;
    total += (rating[u][i] - dev)*cnt;
    totalCnt += cnt;
   }
  }
 }
 if (totalCnt == 0)
  return mean;
 return total / totalCnt;
}
double calMean()
{
 double total = 0;
 int cnt = 0;
 for (int i = 0; i < USERMAX; i++)
  for (int j = 0; j < ITEMMAX; j++)
  {
   total += I[i][j] * rating[i][j];
   cnt += I[i][j];
  }
 return total / cnt;
}

void train()
{
 //read rating matrix
 memset(rating, 0, sizeof(rating));
 memset(I, 0, sizeof(I));
 ifstream in("ua.base");
 if (!in)
 {
  cout << "file not exist" << endl;
  exit(1);
 }
 int userId, itemId, rate;
 string timeStamp;
 while (in >> userId >> itemId >> rate >> timeStamp)
 {
  rating[userId][itemId] = rate;
  I[userId][itemId] = 1;
 } 
 mean = calMean();
}

void test()
{
 ifstream in("ua.test");
 if (!in)
 {
  cout << "file not exist" << endl;
  exit(1);
 }
 int userId, itemId, rate;
 string timeStamp;
 double total = 0;
 double cnt = 0;
 while (in >> userId >> itemId >> rate >> timeStamp)
 {
  double r = predict(userId, itemId);
  cout << "true: " << rate << " predict: " << r << endl;
  total += (r - rate)*(r - rate);
  cnt += 1;
  //cout << total << endl;
 }
 cout << "test rmse is " << pow(total / cnt, 0.5) << endl;
}
int main()
{
 train();
 test();
 return 0;
}
实验结果如下:

在测试集上的rmse达到了0.96,而之前一篇博客实现的svd通过复杂的梯度下降来求最优解也就0.95左右,故SlopeOne算法是非常简单有效的,维基百科里说是最简洁的协同过滤了,但是我个人觉得类似knn的协同过滤更加好懂啊(只不过在计算用户相似度等方面麻烦了点)

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C/C+频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程