引言java
Taste是曾經風靡一時的推薦算法框架,後來被併入Mahout中,Mahout的部分推薦算法基於Taste實現。算法
下文介紹基於Taste實現最經常使用的UserCF和ItemCF。apache
本文不涉及UserCF和ItemCF算法的介紹,這方面網上資料不少,本文僅介紹如何基於Mahout編程實現。編程
歡迎轉載,請註明來源:框架
http://blog.csdn.net/u010967382/article/details/39183839 ide
步驟一:構建數據模型測試
UserCF和ItemCF算法的輸入數據是用戶偏好,用戶偏好數據能夠有兩種形式:idea
推薦算法的第一步是基於數據源構建數據模型,Taste構建數據模型的數據源能夠有不少,好比JDBC,文件等。.net
下面僅介紹最經常使用的文件數據源:rest
示例代碼:
DataModel dm = new FileDataModel(new File("E:\\testdata\\3columns"));
示例代碼:
DataModel dm = new GenericBooleanPrefDataModel(
GenericBooleanPrefDataModel
.toDataMap(new FileDataModel(new File("E:\\testdata\\2columns"))));
步驟二:指定距離(類似度)計算方法
建立好數據模型後,第二步須要指定一種計算「距離」的方法,由於在後續的步驟中須要計算user或item之間的「距離」。
Taste提供的計算距離的方法不少,如下僅介紹經常使用的方法:
歐氏距離:EuclideanDistanceSimilarity
皮爾森距離:PearsonCorrelationSimilarity
餘弦距離:UncenteredCosineSimilarity
曼哈頓距離:CityBlockSimilarity
對數似然距離: LogLikelihoodSimilarity
示例代碼:
UserSimilarity us = new CityBlockSimilarity(dm);
ItemSimilarity is = new CityBlockSimilarity(dm);
步驟三(僅UserCF須要):選擇近鄰算法
若是選擇使用UserCF算法作推薦,則在完成類似度計算方法的指定後,須要指定近鄰算法。
指定距離最近的N個用戶做爲鄰居。
示例:UserNeighborhood unb = new NearestNUserNeighborhood(10, us, dm);
三個參數分別是: 鄰居的個數,用戶類似度,數據模型
指定距離最近的必定百分比的用戶做爲鄰居。
示例:UserNeighborhood unb = new ThresholdUserNeighborhood(0.2, us, dm);
三個參數分別是: 閥值(取值範圍0到1之間),用戶類似度,數據模型
步驟四:建立推薦器
實施推薦算法的最後一步就是建立推薦引擎,Taste爲UserCF和ItemCF算法,針對有用戶評分和沒用戶評分的狀況,分別提供了推薦器:
示例代碼:
UserCF:Recommender re = new GenericUserBasedRecommender(dm, unb, us);
ItemCF:Recommender re = new GenericItemBasedRecommender(dm, is);
示例代碼:
UserCF:Recommender re = new GenericBooleanPrefUserBasedRecommender(dm, unb, us);
ItemCF:Recommender re = new GenericBooleanPrefItemBasedRecommender(dm, is);
題外話:
經過召回率和查準率的測試, CityBlockSimilarity + UserCF 的推薦效果最好。
示例代碼:用戶偏好數據不包含評分 + CityBlockSimilarity + UserCF
1,101
1,102
1,103
2,101
2,102
2,103
2,104
3,101
3,104
3,105
3,107
4,101
4,103
4,104
4,106
5,101
5,102
5,103
5,104
5,105
5,106
import java.io.File;
import java.util.List;
import org.apache.mahout.cf.taste.impl.model.GenericBooleanPrefDataModel;
import org.apache.mahout.cf.taste.impl.model.file.FileDataModel;
import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
import org.apache.mahout.cf.taste.impl.recommender.GenericBooleanPrefUserBasedRecommender;
import org.apache.mahout.cf.taste.impl.similarity.CityBlockSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;
public class UserCFRecommender {
public static void main(String[] args) throws Exception {
// 建立數據模型,不包含用戶評分
DataModel dm = new GenericBooleanPrefDataModel(
GenericBooleanPrefDataModel
.toDataMap( new FileDataModel( new File("E:\\testdata\\2columns"))));
// 使用曼哈頓距離計算類似度
UserSimilarity us = new CityBlockSimilarity(dm);
//指定NearestNUserNeighborhood做爲近鄰算法
UserNeighborhood unb = new NearestNUserNeighborhood(10, us, dm);
// 構建不包含用戶評分的UserCF推薦器
Recommender re = new GenericBooleanPrefUserBasedRecommender(dm, unb, us);
// 輸出推薦結果,爲1號用戶推薦5個商品
List<RecommendedItem> list = re.recommend(1, 5);
for (RecommendedItem recommendedItem : list) {
System. out.println(recommendedItem.getItemID()+" : "+recommendedItem.getValue());
}
}
}