java和python实现一个加权SlopeOne推荐算法

一.加权SlopeOne算法公式:

(1).求得所有item之间的评分偏差

上式中分子部分为项目j与项目i的偏差和,分母部分为所有同时对项目j与项目i评分的用户数

(2).加权预测评分

项目j与项目i

上式中表示用户u对项目j的评分预测,分子为项目j对项目i的偏差加上用户对项目i的评分,cji表示同时对项目j与项目i评分的用户数

二.python实现

 1 #!/usr/bin/python
 2 # -*- coding: utf-8 -*-
 3
 4 user_data = {"小明": {"张学友": 4, "周杰伦": 3, "刘德华": 4},
 5           "小海": {"张学友": 5, "周杰伦": 2},
 6           "李梅": {"周杰伦": 3.5, "刘德华": 4},
 7           "李磊": {"张学友": 5, "刘德华": 3}}
 8
 9 class recommender:
10
11     def __init__(self,data):
12         self.frequency={}
13         self.deviation={}
14         self.data=data
15
16     #计算所有item之间评分偏差
17     def computeDeviation(self):
18         for ratings in self.data.values():
19             for item,rating in ratings.items():
20                 self.frequency.setdefault(item,{})
21                 self.deviation.setdefault(item,{})
22                 for item2,rating2 in ratings.items():
23                     if item!=item2:
24                         self.frequency[item].setdefault(item2,0)
25                         self.deviation[item].setdefault(item2,0.0)
26                         self.frequency[item][item2]+=1#两个项目的用户数
27                         self.deviation[item][item2]+=(rating-rating2)#累加两个评分差值
28         for item,ratings in self.deviation.items():
29             for item2 in ratings:
30                 ratings[item2]/=self.frequency[item][item2]
31
32     #评分预测
33     def predictRating(self,userRatings,k):
34         recommendations={}
35         frequencies={}
36         for item,rating in userRatings.items():
37             for diffItem,diffRating in self.deviation.items():
38                 if diffItem not in userRatings and item in self.deviation[diffItem]:
39                     fre=self.frequency[diffItem][item]
40                     recommendations.setdefault(diffItem,0.0)
41                     frequencies.setdefault(diffItem,0)
42                     #分子部分
43                     recommendations[diffItem]+=(diffRating[item]+rating)*fre
44                     #分母部分
45                     frequencies[diffItem]+=fre
46         recommendations=[(k,v/frequencies[k]) for (k,v) in recommendations.items()]
47         #排序返回前k个
48         recommendations.sort(key=lambda a_tuple:a_tuple[1],reverse=True)
49         return recommendations[:k]
50
51 if __name__==‘__main__‘:
52     r=recommender(user_data)
53     r.computeDeviation()
54     u=user_data[‘李磊‘]
55     print(r.predictRating(u,5))
56     

三.java实现

  1 import java.util.HashMap;
  2 import java.util.Map;
  3 import java.util.List;
  4 import java.util.ArrayList;
  5 import java.util.Comparator;
  6 import java.util.Collections;
  7
  8 /**
  9  * Created by  on 2016/12/8.ShiYan
 10  * 一.计算所有物品对的偏差
 11  * 二.利用偏差进行预测
 12  */
 13 public class SlopeOne {
 14     Map<String,Map<String,Integer>> frequency=null;
 15     Map<String,Map<String,Double>> deviation=null;
 16     Map<String,Map<String,Integer>> user_rating=null;
 17
 18     public SlopeOne( Map<String,Map<String,Integer>> user_rating){
 19         frequency=new HashMap<String,Map<String,Integer>>();
 20         deviation=new HashMap<String,Map<String,Double>>();
 21         this.user_rating=user_rating;
 22     }
 23
 24     /**
 25      * 所有有item间的评分偏差
 26      */
 27     public void computeDeviation(){
 28         for(Map.Entry<String,Map<String,Integer>> ratingsEntry:user_rating.entrySet()){
 29             for(Map.Entry<String,Integer> ratingEntry:ratingsEntry.getValue().entrySet()){
 30                 String item=ratingEntry.getKey();
 31                 int rating=ratingEntry.getValue();
 32                 Map<String,Integer> itemFrequency=null;
 33                 if(!frequency.containsKey(item)){
 34                     itemFrequency=new HashMap<String, Integer>();
 35                     frequency.put(item,itemFrequency);
 36                 }else{
 37                     itemFrequency=frequency.get(item);
 38                 }
 39
 40                 Map<String,Double> itemDeviation=null;
 41                 if(!deviation.containsKey(item)){
 42                     itemDeviation=new HashMap<String, Double>();
 43                     deviation.put(item,itemDeviation);
 44                 }else{
 45                     itemDeviation=deviation.get(item);
 46                 }
 47
 48                 for(Map.Entry<String,Integer> ratingEntry2:ratingsEntry.getValue().entrySet()){
 49                     String item2=ratingEntry2.getKey();
 50                     int rating2=ratingEntry2.getValue();
 51                     if(!item.equals(item2)){
 52                         //两个项目的用户数
 53                         itemFrequency.put(item2,itemFrequency.containsKey(item2)?itemFrequency.get(item2)+1:0);
 54                         //两个项目的评分偏差,累加
 55                         itemDeviation.put(item2,itemDeviation.containsKey(item2)?itemDeviation.get(item2)+(rating-rating2):0.0);
 56                     }
 57                 }
 58             }
 59         }
 60
 61         for(Map.Entry<String,Map<String,Double>> itemsDeviation:deviation.entrySet()){
 62             String item=itemsDeviation.getKey();
 63             Map<String,Double> itemDev=itemsDeviation.getValue();
 64             Map<String,Integer> itemFre=frequency.get(item);
 65             for(String itemName:itemDev.keySet()){
 66                 itemDev.put(itemName,itemDev.get(itemName)/itemFre.get(itemName));
 67             }
 68         }
 69     }
 70
 71     /**
 72      * 评分预测
 73      * @param userRating 目标用户的评分
 74      * @param k 返回前k个
 75      * @return
 76      */
 77     public  List<Map.Entry<String,Double>> predictRating(Map<String,Integer> userRating,int k){
 78         Map<String,Double> recommendations=new HashMap<String,Double>();
 79         Map<String,Integer> frequencies=new HashMap<String, Integer>();
 80         for(Map.Entry<String,Integer> userEntry:userRating.entrySet()){
 81             String userItem=userEntry.getKey();
 82             double rating=userEntry.getValue();
 83             for(Map.Entry<String,Map<String,Double>> deviationEntry:deviation.entrySet()){
 84                 String item=deviationEntry.getKey();
 85                 Map<String,Double> itemDeviation=deviationEntry.getValue();
 86                 Map<String,Integer> itemFrequency=frequency.get(item);
 87                 if(!userRating.containsKey(item) && itemDeviation.containsKey(userItem)){
 88                     int fre=itemFrequency.get(userItem);
 89                     if(!recommendations.containsKey(item))
 90                         recommendations.put(item,0.0);
 91                     if(!frequencies.containsKey(item))
 92                         frequencies.put(item,0);
 93                     //分子部分
 94                     recommendations.put(item,recommendations.get(item)+(itemDeviation.get(userItem)+rating)*fre);
 95                     //分母部分
 96                     frequencies.put(item,frequencies.get(item)+fre);
 97                 }
 98             }
 99         }
100         for(Map.Entry<String,Double> recoEntry:recommendations.entrySet()){
101             String key=recoEntry.getKey();
102             double value=recoEntry.getValue()/frequencies.get(key);
103             recommendations.put(key,value);
104         }
105         //排序,这里还可以使用优先队列返回top_k
106         List<Map.Entry<String,Double>> list_map=new ArrayList<Map.Entry<String,Double>>(recommendations.entrySet());
107         Collections.sort(list_map,new Comparator<Map.Entry<String,Double>>(){
108                     @Override
109                     public int compare(Map.Entry<String, Double> o1, Map.Entry<String, Double> o2) {
110                         if(o2.getValue()>o1.getValue())
111                             return 1;
112                         else if(o2.getValue()<o1.getValue())
113                             return -1;
114                         else
115                             return 0;
116                     }
117                 }
118         );
119         List<Map.Entry<String,Double>> top_k=new ArrayList<Map.Entry<String, Double>>();
120         if(list_map.size()<k) k=list_map.size();
121         for(int i=0;i<k;i++){
122             top_k.add(list_map.get(i));
123         }
124         return top_k;
125     }
126
127     public static void main(String[] args){
128         Map<String,Map<String,Integer>> userRatings=new HashMap<String, Map<String, Integer>>();
129         Map<String,Integer> xiMingRating=new HashMap<String, Integer>();
130         xiMingRating.put("张学友",4);
131         xiMingRating.put("周杰伦",3);
132         xiMingRating.put("刘德华",4);
133         Map<String,Integer> xiHaiRating=new HashMap<String, Integer>();
134         xiHaiRating.put("张学友",5);
135         xiHaiRating.put("周杰伦",2);
136         Map<String,Integer> liMeiRating=new HashMap<String, Integer>();
137         liMeiRating.put("周杰伦",3);
138         liMeiRating.put( "刘德华",4);
139         Map<String,Integer> liLeiRating=new HashMap<String, Integer>();
140         liLeiRating.put("张学友",5);
141         liLeiRating.put("刘德华",3);
142         userRatings.put("xiMing",xiMingRating);
143         userRatings.put("xiHai",xiHaiRating);
144         userRatings.put("liMei", liMeiRating);
145         userRatings.put("liLei",liLeiRating);
146
147         SlopeOne slopOne=new SlopeOne(userRatings);
148         slopOne.computeDeviation();
149         List<Map.Entry<String,Double>> top_k=slopOne.predictRating(userRatings.get("liLei"),5);
150         for(Map.Entry<String,Double> item:top_k){
151             System.out.println(item.getKey()+"   "+item.getValue());
152         }
153     }
154 }
时间: 2024-08-29 15:14:27

java和python实现一个加权SlopeOne推荐算法的相关文章

SlopeOne推荐算法实现(C++)

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

关于2015阿里移动推荐算法大赛的总结(三)——机器学习

关于2015阿里移动推荐算法大赛的总结(一) 关于2015阿里移动推荐算法大赛的总结(二)--推荐算法 关于2015阿里移动推荐算法大赛的总结(三)--机器学习 后来我们回归到正途上,虽然我们也想用深度学习的方法,但是毕竟还是菜鸟的水平,所以把目标定在能用机器学习跑通一遍,顺带熟悉一下各种机器学习算法的实际应用.但是最后的最后我们只用了LR,然后就受打击了.哈哈~ 想用机器学习的方法,那么思路其实也很明确,问题是那一天用户是买还是不买,那么可以看成是二分法.通过用户行为方式来判断是否会购买.就是

从分类,排序,top-k多个方面对推荐算法稳定性的评价

介绍 论文名: "classification, ranking, and top-k stability of recommendation algorithms". 本文讲述比较推荐系统在三种情况下, 推荐稳定性情况. 与常规准确率比较的方式不同, 本文从另一个角度, 即推荐算法稳定性方面进行比较. 详细 参与比较的推荐算法 包括: baseline 传统基于用户 传统基于物品 oneSlope svd 比较方式 比较的过程分为两个阶段: 阶段一, 将原始数据分为两个部分, 一部分

mahout入门指南之mahout单机版推荐算法

鄙人最近在研究mahout,网上找了一些入门资料来看,发现都整理的比较乱.折腾了一番,终于搞清楚了.为了让新手们较快入门,决定总结分享一下,写此入门指南. mahout是什么? mahout是一个机器学习库,里面实现了一些算法,比如推荐算法,聚类算法. 实现方式有单机内存版,也有分布式(hadoop和spark). mahout如何快速入门? 个人觉得单机版的mahout推荐系统demo比较适合初学者.网上有一些入门资料其实也是单机版的算法,但是那些资料都要配置很多"不必要的"的环境,

【推荐算法工程师技术栈系列】推荐系统--数据效果与评估

目录 推荐系统上线的基本条件 AB实验 功能列表 数据指标 覆盖率 AUC及gAUC 指标展示 指标监控 人工评测 附录 推荐系统上线的基本条件 一个新的推荐算法最终上线,需要完成上面所说的3个实验: (1)首先,需要通过离线实验证明它在很多离线指标上优于现有的算法: (2)然后,需要通过用户调查(或内部人工评测)确定它的用户满意度不低于现有的算法: (3)最后,通过在线等AB测试确定它在我们关心的指标上优于现有的算法. AB实验 (1)AB test 的好处是显而易见的,可以公平获得不同算法实

Go语言将在未来成为下一个王者,消灭Java和Python?

在过去几年中,新的编程语言有所增加:Go或GoLang. 没有什么能让开发人员疯狂而不是新的编程语言,对吗?近几年来,Go语言真是越来越火了.我们来看看Tiobe世界编程语言排行的最新排名,Go已经从去年的第14名上升到今年的第十名了.虽然Java仍然占据编程界的老大哥的地位,但是它所占的份额确实是有所下滑.还有C和C++的市场份额也是逐年下滑. 就现在的条件来说我们无法向处理器添加越来越多的缓存以提高性能,因为缓存具有物理限制:缓存越大,获得的速度越慢.为处理器添加更多核心也有其成本.而且,这

Python开发一个csv比较功能相关知识点汇总及demo

Python 2.7 doc demo: # -*- coding: utf-8 -*- import csv with open('eggs.csv', 'wb') as csvfile: spamwriter = csv.writer(csvfile, delimiter=' ', quotechar='|', quoting=csv.QUOTE_MINIMAL) spamwriter.writerow(['Spam'] * 5 + ['Baked Beans']) spamwriter.w

Java VS Python 应该先学哪个?

http://blog.segmentfault.com/hlcfan/1190000000361407 http://www.tuicool.com/articles/fqAzqi Java 和 Python 是当下两种巨火的巨强大的编程语言,对于刚开始学习编程的同学来说,很是迷惑,最经常问得问题就是,我应该学 Java 还是 Python,是不是 Python 容易学,或者应该给初学者推荐什么编程语言等等这样的问题.因为我是个 Java 程序员,我的意见显然是有偏见的,我会建议你先学 Jav

Java or Python?测试开发工程师如何选择合适的编程语言?

很多测试开发工程师尤其是刚入行的同学对编程语言和技术栈选择问题特别关注,毕竟掌握一门编程语言要花不少时间成本,也直接关系到未来的面试和就业(不同企业/项目对技术栈要求也不一样),根据自身情况做一个相对正确的选择确实要比盲目投入更明智也更高效. 目前最常见的情况是纠结选择 Java 还是 Python?关于这个问题,我搜索了之前的相关博客,也特意请教了几位资深的测试技术专家,在这里做一个汇总整理,集"各家"之言供大家参考.也欢迎各位朋友根据自己的经验回帖补充意见. P.S. 有一点需要强