java和python實現一個加權SlopeOne推薦算法

一.加權SlopeOne算法公式:java

(1).求得全部item之間的評分誤差python


上式中分子部分爲項目j與項目i的誤差和,分母部分爲全部同時對項目j與項目i評分的用戶數算法

(2).加權預測評分ide

項目j與項目ithis

上式中表示用戶u對項目j的評分預測,分子爲項目j對項目i的誤差加上用戶對項目i的評分,cji表示同時對項目j與項目i評分的用戶數spa

二.python實現code

 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實現blog

  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 }
相關文章
相關標籤/搜索