SlopeOne推薦算法


       Slope One 算法 是一種基於評分的預測算法, 本質上也是一種基於項目的算法。與一般的基於項目的算法不同, 該算法不計算項目之間的相似度, 而是用一種簡單的線性回歸模型進行預測(可以擴展) 算法易於實現, 計算速度快, 可擴展性好, 同時對數據稀疏性有較好的適應性。
       例如下面表格里有3個用戶對4個物品的評分
 
101
102
103
104
UserX 5
3.5
 
 
UserY
2
5
4
2
UserZ
4.5
3.5
1
4
      求物品兩兩之間的差值平均分:
         物品102和101:{(3.5-5)+(5-2)+(3.5-4.5)}/3=0.5/3
      物品103跟101:{(4-2)+(1-4.5)}/2=-1.5/2
      物品104跟101:{(2-2)+(4-4.5)}/2=-0.5/2
      物品103跟102:{(4-5)+(1-3.5)}/2=-3.5/2
      物品104跟102:{(2-5)+(4-3.5)}/2=-2.5/2
      物品104跟103:{(2-4)+(4-1)}/2=1/2
能得到下面表格
 
101
102
103
104
101
 
 
 
 
102
0.17
 
 
 
103
-0.75
-1.75
 
 
104
-0.25
-1.25
0.5
 
       OK,現在准備工作已經完成了,然后進行推薦,例如對X用戶進行推薦,103和104個預測評分根據101、102的評分來的。
       X預測103評分={(-0.75+5)+(-1.75+3.5)}/2=(4.25+1.75)/2=3
       X預測104評分={(-0.25+5)+(-1.25+3.5)}/2=(4.75+2.25)/2=3.5
       那么給X用戶推薦的順序就是:先推薦104在推薦103
        實戰經驗 :可以看出該算法對評分質量要求非常高,那么如果某一個物品的平均分高的話,那么該物品就非常容易被推薦。
       下面代碼是基於Mahout的SlopeOne算法調用:
 
  1 import java.io.BufferedReader;
  2 
  3 import java.io.BufferedWriter;
  4 
  5 import java.io.File;
  6 
  7 import java.io.FileNotFoundException;
  8 
  9 import java.io.FileReader;
 10 
 11 import java.io.FileWriter;
 12 
 13 import java.io.IOException;
 14 
 15 import java.util.List;
 16 
 17 import org.apache.commons.cli2.OptionException;
 18 
 19 import org.apache.mahout.cf.taste.common.TasteException;
 20 
 21 import org.apache.mahout.cf.taste.impl.common.LongPrimitiveIterator;
 22 
 23 import org.apache.mahout.cf.taste.impl.model.file.FileDataModel;
 24 
 25 import org.apache.mahout.cf.taste.impl.recommender.CachingRecommender;
 26 
 27 import org.apache.mahout.cf.taste.impl.recommender.slopeone.SlopeOneRecommender;
 28 
 29 import org.apache.mahout.cf.taste.model.DataModel;
 30 
 31 import org.apache.mahout.cf.taste.recommender.RecommendedItem;
 32 
 33 
 34 public class App 
 35 
 36 {  
 37 
 38     static final String inputFile = "/mnt/new/ml-1m/ratings.dat";
 39 
 40     static final String outputFile = "/mnt/new/ml-1m/ratings.csv";
 41 
 42     
 43 
 44     public static void main( String[] args ) throws IOException, TasteException, OptionException
 45 
 46     {
 47 
 48         CreateCsvRatingsFile();    
 49 
 50        //創建模型數據源文件      
 51 
 52         File ratingsFile = new File(outputFile);  
 53 
 54         DataModel model = new FileDataModel(ratingsFile);
 55 
 56         // SlopeOne算法
 57 
 58         CachingRecommender cachingRecommender = new CachingRecommender(new SlopeOneRecommender(model));
 59 
 60         // 對所有用戶進行推薦
 61 
 62         for (LongPrimitiveIterator it = model.getUserIDs(); it.hasNext();){
 63 
 64             long userId = it.nextLong();     
 65 
 66             // 對單個User進行推薦
 67 
 68             List<RecommendedItem> recommendations = cachingRecommender.recommend(userId, 10);
 69 
 70 
 71             // 該用戶無推薦結果
 72 
 73             if (recommendations.size() == 0){
 74 
 75                 System.out.print("User ");
 76 
 77                 System.out.print(userId);
 78 
 79                 System.out.println(": no recommendations");
 80 
 81             }                 
 82 
 83             // 打印推薦信息
 84 
 85             for (RecommendedItem recommendedItem : recommendations) {
 86 
 87                 System.out.print("User ");
 88 
 89                 System.out.print(userId);
 90 
 91                 System.out.print(": ");
 92 
 93                 System.out.println(recommendedItem);
 94 
 95             }
 96 
 97         }                
 98 
 99     }
100 
101  
102     //讀文件前1000行作為模型輸入
103     private static void CreateCsvRatingsFile() throws FileNotFoundException, IOException {
104 
105 
106         BufferedReader br = new BufferedReader(new FileReader(inputFile));        
107 
108         BufferedWriter bw = new BufferedWriter(new FileWriter(outputFile));
109 
110 
111 
112         String line = null;
113 
114         String line2write = null;
115 
116         String[] temp;
117 
118 
119         int i = 0;
120 
121         while ((line = br.readLine()) != null && i < 1000)
122 
123         {
124 
125             i++;
126 
127             temp = line.split("::");
128 
129             line2write = temp[0] + "," + temp[1];
130 
131             bw.write(line2write);
132 
133             bw.newLine();
134 
135             bw.flush();
136 
137         }        
138 
139         br.close();
140 
141         bw.close();
142 
143     } 
144 
145 }

參考資料:1,Mahout cookbook;2,http://weibo.com/bicloud 網友寫的SlopeOnePPT


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM