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
|
|
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