基於用戶的協同過濾推薦算法WEB版代碼實現

基於用戶的協同過濾推薦算法WEB版代碼實現

(包含輸出用戶-評分矩陣模型、用戶間相似度、最近鄰居、推薦結果、平均絕對誤差MAE、查準率、召回率)

一、開發工具及使用技術

MyEclipse10、jdk1.7、mahout API、movielens數據集。

二、實現過程

1、定義用戶-電影評分矩陣:

/**

* 用戶-電影評分矩陣工具類

*/

public class DataModelUtil {


//定義用戶-電影評分矩陣

private static DataModel model = null

;


//初始化數據

static{

try {

//找到用戶-電影評分文件

// File file = new File(Constant.dataPath+Constant.rateFile);

// model = new FileDataModel(file);//實例化數據源


//jar包中的文件必須改成文件流進行操作,而且數據文件必須放在src文件夾下

InputStream inputStream = DataModelUtil.class.getClassLoader().

getResourceAsStream(Constant.dataPath+Constant.rateFile);


File file = new File("d://"+Constant.rateFile);

if (!file.exists())

file.createNewFile();

OutputStream outputStream = new FileOutputStream(file);

int bytesRead = 0;

byte[] buffer = new byte[1024];

while ((bytesRead = inputStream.read(buffer, 0, 1024)) != -1) {

outputStream.write(buffer, 0, bytesRead);

}

outputStream.close();

inputStream.close();

model = new FileDataModel(file);//實例化數據源


// File file = new File(Constant.dataPath+Constant.rateFile2);

// model = new FileDataModel(file, "::");//實例化數據源

} catch (Exception e) {

e.printStackTrace();

}

}


/**

* 得到用戶-電影評分矩陣

* @return

*/

public static DataModel getDataModel(){

return model;

}


/**

* 獲取矩陣中的所有用戶

* @return

*/

public static LongPrimitiveIterator getUserids(){

try {

return model.getUserIDs();

} catch (TasteException e) {

e.printStackTrace();

}

return null;

}


/**

* 獲取矩陣中的所有電影

* @return

*/

public static LongPrimitiveIterator getItemids(){

try {

return model.getItemIDs();

} catch

(TasteException e) {

e.printStackTrace();

}

return null;

}


/**

* 根據用戶id和電影id找到評分

* @param userid

* @param itemid

* @return

*/

public static Float getPreferenceValue(long userid,long itemid){

try {

return model.getPreferenceValue(userid,itemid);

} catch (TasteException e) {

e.printStackTrace();

}

return null;

}


}

2、計算用戶之間的相似度:

/**

* 相似度工具類

*/

public class SimilarityUtil {


/**

* 獲取用戶相似度對象

* @param

dataModel

* @return

*/

public static UserSimilarity getUserSimilarity(DataModel dataModel){

return (UserSimilarity) getPearsonSimilarity(dataModel);

}


/**

* 使用pearson皮爾森相似度算法

* @param dataModel

* @return

*/

private static Object getPearsonSimilarity(DataModel dataModel){

try {

return

new PearsonCorrelationSimilarity(dataModel);

} catch (TasteException e) {

e.printStackTrace();

}

return null;

}


}

3、計算目標用戶的最近鄰居:

/**

* 最近鄰居工具類

* @author line

*

*/

public class NearestNUserUtil {


/**

* 最近鄰居工具方法

* @param userSimilarity

* @param dataModel

* @return

*/

public static UserNeighborhood getNearestNUser(UserSimilarity userSimilarity,

DataModel dataModel){

try {

return new NearestNUserNeighborhood(Constant.knn, userSimilarity, dataModel);

} catch (TasteException e) {

e.printStackTrace();

}

return null;

}


}

4、定義推薦器:

/**

* 推薦器工具類

* @author line

*

*/

public class RecommendUtil {


public static Recommender getRecommend(DataModel dataModel,

UserNeighborhood neighborhood,UserSimilarity userSimilarity){

return new GenericUserBasedRecommender(dataModel, neighborhood, userSimilarity);

}


}

5、計算MAE、precision、recall:

/**

* 協同過濾算法評判標準類

*/

public class JudgeUtil {


// public static void main(String[] args) {

// getJudge();

// }


/**

* 協同過濾算法評判標準方法

*/

public static void getJudge(){

System.out.println("計算平均絕對誤差MAE、查準率、召回率開始");

try

{

RandomUtils.useTestSeed();

//這裡使用的評估方法--平均差值

RecommenderEvaluator evaluator = new AverageAbsoluteDifferenceRecommenderEvaluator();

/*

我們創建了一個推薦器生成器

因為評估的時候我們需要將源數據中的一部分作為測試數據,其他作為算法的訓練數據

需要通過新訓練的DataModel構建推薦器,所以採用生成器的方式生成推薦器

*/

RecommenderBuilder builder = new RecommenderBuilder() {

public Recommender buildRecommender(DataModel dataModel) throws TasteException {

UserSimilarity userSimilarity = SimilarityUtil.getUserSimilarity(dataModel);

LongPrimitiveIterator userids = DataModelUtil.getUserids();

UserNeighborhood neighborhood = NearestNUserUtil.getNearestNUser(userSimilarity, dataModel);

return RecommendUtil.getRecommend(dataModel, neighborhood, userSimilarity);

}

};

/*

RecommenderEvaluator負責將數據分為訓練集和測試集,用訓練集構建一個DataModel和Recommender用來進行測試活動,得到結果之後在於真實數據進行比較。

參數中0.7代表訓練數據為70%,測試數據是30%。最後的1.0代表的是選取數據集的多少數據做整個評估。

此處第二個null處,使用null就可以滿足基本需求,但是如果我們有特殊需求,比如使用特殊的DataModel,在這裡可以使用DataModelBuilder的一個實例。

*/

double score = evaluator.evaluate(builder, null, DataModelUtil.getDataModel(),

Constant.trainCount, Constant.testCount);

/*

最後得出的評估值越小,說明推薦結果越好

最後的評價結果是0.943877551020408,表示的是平均與真實結果的差值是0.9.

*/

System.out.println("平均絕對誤差MAE:"+score);


/*

計算推薦4個結果時的查準率和召回率,使用評估器,並設定評估期的參數

4表示"precision and recall at 4"即相當於推薦top4,然後在top-4的推薦上計算準確率和召回率

查準率為0.75 上面設置的參數為4,表示 Precision at 4(推薦4個結果時的查準率),平均有3/4的推薦結果是好的

Recall at 4 推薦兩個結果的查全率是1.0 表示所有的好的推薦都包含在這些推薦結果中

*/

RandomUtils.useTestSeed();

RecommenderIRStatsEvaluator statsEvaluator = new GenericRecommenderIRStatsEvaluator();

IRStatistics stats = statsEvaluator.evaluate(builder, null, DataModelUtil.getDataModel(),

null, Constant.cfCount, GenericRecommenderIRStatsEvaluator.CHOOSE_THRESHOLD, 1.0);

System.out.println("查準率:"+stats.getPrecision());

System.out.println("召回率:"+stats.getRecall());


}

catch (Exception e) {

e.printStackTrace();

}

System.out.println("計算平均絕對誤差MAE、查準率、召回率結束");

}


}

三、運行結果

1、用戶-電影評分矩陣:

基於用戶的協同過濾推薦算法WEB版代碼實現

2、用戶相似度:

基於用戶的協同過濾推薦算法WEB版代碼實現

3、用戶最近鄰:

基於用戶的協同過濾推薦算法WEB版代碼實現

4、推薦結果:

基於用戶的協同過濾推薦算法WEB版代碼實現

5、MAE、precision、recall結果:

基於用戶的協同過濾推薦算法WEB版代碼實現

歡迎留言、私信交流或關注博客https://blog.csdn.net/u011291472


分享到:


相關文章: