共計 7978 個字符,預(yù)計需要花費 20 分鐘才能閱讀完成。
這篇文章的內(nèi)容主要圍繞 Mahout、協(xié)同過濾和 CF 推薦算法基本概念及代碼示例分析進(jìn)行講述,文章內(nèi)容清晰易懂,條理清晰,非常適合新手學(xué)習(xí),值得大家去閱讀。感興趣的朋友可以跟隨丸趣 TV 小編一起閱讀吧。希望大家通過這篇文章有所收獲!
協(xié)同過濾
協(xié)同過濾是利用集體智慧的一個典型方法。要理解什么是協(xié)同過濾 (Collaborative Filtering, 簡稱 CF),首先想一個簡單的問題,如果你現(xiàn)在想看個電影,但你不知道具體看哪部,你會怎么做?大部分的人會問問周圍的朋友,看看最近有什么好看的電影推薦,而我們一般更傾向于從口味比較類似的朋友那里得到推薦。這就是協(xié)同過濾的核心思想。
協(xié)同過濾一般是在海量的用戶中發(fā)掘出一小部分和你品位比較類似的,在協(xié)同過濾中,這些用戶成為鄰居,然后根據(jù)他們喜歡的其他東西組織成一個排序的目錄作為推薦給你。當(dāng)然其中有一個核心的問題:
如何確定一個用戶是不是和你有相似的品位?
如何將鄰居們的喜好組織成一個排序的目錄?
協(xié)同過濾相對于集體智慧而言,它從一定程度上保留了個體的特征,就是你的品位偏好,所以它更多可以作為個性化推薦的算法思想。
算法評判標(biāo)準(zhǔn):召回率 (recall) 與查準(zhǔn)率(precision)
Mahout 提供了 2 個評估推薦器的指標(biāo),查準(zhǔn)率和召回率(查全率),這兩個指標(biāo)是搜索引擎中經(jīng)典的度量方法。
相關(guān) 不相關(guān)
檢索到 A C
未檢索到 B D
A:檢索到的,相關(guān)的(搜到的也想要的)
B:未檢索到的,但是相關(guān)的(沒搜到,然而實際上想要的)
C:檢索到的,但是不相關(guān)的(搜到的但沒用的)
D:未檢索到的,也不相關(guān)的(沒搜到也沒用的)
被檢索到的越多越好,這是追求“查全率”,即 A /(A+B),越大越好。
被檢索到的,越相關(guān)的越多越好,不相關(guān)的越少越好,這是追求“查準(zhǔn)率”,即 A /(A+C),越大越好。
在大規(guī)模數(shù)據(jù)集合中,這兩個指標(biāo)是相互制約的。當(dāng)希望索引出更多的數(shù)據(jù)的時候,查準(zhǔn)率就會下降,當(dāng)希望索引更準(zhǔn)確的時候,會索引更少的數(shù)據(jù)
基于用戶的 CF 的基本原理
基于用戶的協(xié)同過濾,通過不同用戶對物品的評分來評測用戶之間的相似性,基于用戶之間的相似性做出推薦。簡單來講就是:給用戶推薦和他興趣相似的其他用戶喜歡的物品。
基于用戶的 CF 的基本思想相當(dāng)簡單,基于用戶對物品的偏好找到相鄰鄰居用戶,然后將鄰居用戶喜歡的推薦給當(dāng)前用戶。計算上,就是將一個用戶對所有物品的偏好作為一個向量來計算用戶之間的相似度,找到 K 鄰居后,根據(jù)鄰居的相似度權(quán)重以及他們對物品的偏好,預(yù)測當(dāng)前用戶沒有偏好的未涉及物品,計算得到一個排序的物品列表作為推薦。下圖 給出了一個例子,對于用戶 A,根據(jù)用戶的歷史偏好,這里只計算得到一個鄰居 – 用戶 C,然后將用戶 C 喜歡的物品 D 推薦給用戶 A。
基于物品的 CF 的基本原理
基于 item 的協(xié)同過濾,通過用戶對不同 item 的評分來評測 item 之間的相似性,基于 item 之間的相似性做出推薦。簡單來講就是:給用戶推薦和他之前喜歡的物品相似的物品。
基于物品的 CF 的原理和基于用戶的 CF 類似,只是在計算鄰居時采用物品本身,而不是從用戶的角度,即基于用戶對物品的偏好找到相似的物品,然后根據(jù)用戶的歷史偏好,推薦相似的物品給他。從計算的角度看,就是將所有用戶對某個物品的偏好作為一個向量來計算物品之間的相似度,得到物品的相似物品后,根據(jù)用戶歷史的偏好預(yù)測當(dāng)前用戶還沒有表示偏好的物品,計算得到一個排序的物品列表作為推薦。下圖 給出了一個例子,對于物品 A,根據(jù)所有用戶的歷史偏好,喜歡物品 A 的用戶都喜歡物品 C,得出物品 A 和物品 C 比較相似,而用戶 C 喜歡物品 A,那么可以推斷出用戶 C 可能也喜歡物品 C。
基于物品的 CF 的基本原理
User CF 與 Item CF 的基本假設(shè)與適用性
對于 User CF,推薦的原則是假設(shè)用戶會喜歡那些和他有相同喜好的用戶喜歡的東西,但如果一個用戶沒有相同喜好的朋友,那 User CF 的算法的效果就會很差,所以一個用戶對的 CF 算法的適應(yīng)度是和他有多少共同喜好用戶成正比的。
Item CF 算法也有一個基本假設(shè),就是用戶會喜歡和他以前喜歡的東西相似的東西,那么我們可以計算一個用戶喜歡的物品的自相似度。一個用戶喜歡物品的自相似度大,就說明他喜歡的東西都是比較相似的,也就是說他比較符合 Item CF 方法的基本假設(shè),那么他對 Item CF 的適應(yīng)度自然比較好;反之,如果自相似度小,就說明這個用戶的喜好習(xí)慣并不滿足 Item CF 方法的基本假設(shè),那么對于這種用戶,用 Item CF 方法做出好的推薦的可能性非常低。
代碼示例
import java.io.File;
import java.util.List;
import org.apache.mahout.cf.taste.impl.common.FastByIDMap;
import org.apache.mahout.cf.taste.impl.common.LongPrimitiveIterator;
import org.apache.mahout.cf.taste.impl.model.GenericDataModel;
import org.apache.mahout.cf.taste.impl.model.GenericPreference;
import org.apache.mahout.cf.taste.impl.model.GenericUserPreferenceArray;
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.GenericItemBasedRecommender;
import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
import org.apache.mahout.cf.taste.impl.similarity.EuclideanDistanceSimilarity;
import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.model.PreferenceArray;
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.ItemSimilarity;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;
public class RecommenderDemo {public static void main(String[] args) throws Exception {userBasedRecommender();
itemBasedRecommender();
CFDemo();
* 基于用戶相似度的推薦引擎
*
* @throws Exception
*/
public static void userBasedRecommender() throws Exception {
// step1 構(gòu)建模型
DataModel model = new FileDataModel(new File( data.txt));
// step2 計算相似度 (基于皮爾遜相關(guān)系數(shù)計算相似度)UserSimilarity similarity = new PearsonCorrelationSimilarity(model);
// step3 查找 k 緊鄰
UserNeighborhood neighborhood = new NearestNUserNeighborhood(2,
similarity, model);
// 構(gòu)造推薦引擎
Recommender recommender = new GenericUserBasedRecommender(model,
neighborhood, similarity);
// 為用戶 1 推薦兩個 ItemID
List RecommendedItem recommendations = recommender.recommend(1, 2);
for (RecommendedItem recommendation : recommendations) {System.out.println(recommendation);
* 基于內(nèi)容的推薦引擎
*
* @throws Exception
*/
public static void itemBasedRecommender() throws Exception {DataModel model = new FileDataModel(new File( data.txt));
ItemSimilarity similarity = new PearsonCorrelationSimilarity(model);
Recommender recommender = new GenericItemBasedRecommender(model,
similarity);
List RecommendedItem recommendations = recommender.recommend(1, 1);
for (RecommendedItem recommendation : recommendations) {System.out.println(recommendation);
*
* @throws Exception
*/
public static void CFDemo() throws Exception {
// 創(chuàng)建 dataModel
FastByIDMap PreferenceArray preferences = new FastByIDMap PreferenceArray
// 用戶 1 喜歡物品 1、2、3
PreferenceArray userPref1 = new GenericUserPreferenceArray(3);
// userPref1.setUserID(1, 1);
// userPref1.setItemID(0, 1);
// userPref1.setValue(0, 5.0f);
// userPref1.setItemID(1, 2);
// userPref1.setValue(1, 3.0f);
// userPref1.setItemID(2, 3);
// userPref1.setValue(2, 2.5f);
userPref1.set(0, new GenericPreference(1, 1, 5.0f));
userPref1.set(1, new GenericPreference(1, 2, 3.0f));
userPref1.set(2, new GenericPreference(1, 3, 2.5f));
// 用戶 2 喜歡物品 1、2、3、4
PreferenceArray userPref2 = new GenericUserPreferenceArray(4);
userPref2.set(0, new GenericPreference(2, 1, 2.0f));
userPref2.set(1, new GenericPreference(2, 2, 2.5f));
userPref2.set(2, new GenericPreference(2, 3, 5.0f));
userPref2.set(3, new GenericPreference(2, 4, 2.0f));
// 用戶 3 喜歡物品 1、4、5、7
PreferenceArray userPref3 = new GenericUserPreferenceArray(4);
userPref3.set(0, new GenericPreference(3, 1, 2.5f));
userPref3.set(1, new GenericPreference(3, 4, 4.0f));
userPref3.set(2, new GenericPreference(3, 5, 4.5f));
userPref3.set(3, new GenericPreference(3, 7, 5.0f));
// 用戶 4 喜歡物品 1、3、4、6
PreferenceArray userPref4 = new GenericUserPreferenceArray(4);
userPref4.set(0, new GenericPreference(4, 1, 5.0f));
userPref4.set(1, new GenericPreference(4, 3, 3.0f));
userPref4.set(2, new GenericPreference(4, 4, 4.5f));
userPref4.set(3, new GenericPreference(4, 6, 4.0f));
// 用戶 5 喜歡物品 1、2、3、4、5、6
PreferenceArray userPref5 = new GenericUserPreferenceArray(6);
userPref5.set(0, new GenericPreference(5, 1, 4.0f));
userPref5.set(1, new GenericPreference(5, 2, 3.0f));
userPref5.set(2, new GenericPreference(5, 3, 2.0f));
userPref5.set(3, new GenericPreference(5, 4, 4.0f));
userPref5.set(4, new GenericPreference(5, 5, 3.5f));
userPref5.set(5, new GenericPreference(5, 6, 4.0f));
preferences.put(1, userPref1);
preferences.put(2, userPref2);
preferences.put(3, userPref3);
preferences.put(4, userPref4);
preferences.put(5, userPref5);
// 基于程序構(gòu)建的 dataModel
DataModel model = new GenericDataModel(preferences);
// 基于文件的 dataModel
// DataModel model = new FileDataModel(new File( testCF.csv));
// 基于用戶的、歐氏距離、最近鄰的協(xié)同過濾算法
UserSimilarity similarity = new EuclideanDistanceSimilarity(model);
UserNeighborhood neighborhood = new NearestNUserNeighborhood(2,
similarity, model);
Recommender recommender = new GenericUserBasedRecommender(model,
neighborhood, similarity);
// 打印用戶 4 的推薦信息
List RecommendedItem recommendations = recommender.recommend(4, 3);
for (RecommendedItem recommendation : recommendations) {System.out.println(recommendation);
// 打印所有用戶的推薦信息
LongPrimitiveIterator iter = model.getUserIDs();
while (iter.hasNext()) {long uid = iter.nextLong();
List RecommendedItem list = recommender.recommend(uid, 3);
System.out.printf(uid:%s , uid);
for (RecommendedItem ritem : list) {System.out.printf( (%s,%f) , ritem.getItemID(),
ritem.getValue());
System.out.println();
// 基于內(nèi)容的、歐氏距離、最近鄰的協(xié)同過濾算法
ItemSimilarity similarity1 = new EuclideanDistanceSimilarity(model);
Recommender recommender1 = new GenericItemBasedRecommender(model,similarity1);
LongPrimitiveIterator iter1 = model.getUserIDs();
while (iter1.hasNext()) {long uid = iter1.nextLong();
List RecommendedItem list = recommender1.recommend(uid, 3);
System.out.printf(uid:%s , uid);
for (RecommendedItem ritem : list) {System.out.printf( (%s,%f) , ritem.getItemID(),
ritem.getValue());
System.out.println();}
data.txt 內(nèi)容
1,101,5
1,102,3
1,103,2.5
2,101,2
2,102,2.5
2,103,5
2,104,2
3,101,2.5
3,104,4
3,105,4.5
3,107,5
4,101,5
4,103,3
4,104,4.5
4,106,4
5,101,4
5,102,3
5,103,2
5,104,4
5,105,3.5
5,106,4
感謝你的閱讀,相信你對“Mahout、協(xié)同過濾和 CF 推薦算法基本概念及代碼示例分析”這一問題有一定的了解,快去動手實踐吧,如果想了解更多相關(guān)知識點,可以關(guān)注丸趣 TV 網(wǎng)站!丸趣 TV 小編會繼續(xù)為大家?guī)砀玫奈恼拢?/p>