日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Fast Matrix Factorization for Online Recommendation with Implicit Feedback论文代码分析

發布時間:2024/8/23 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Fast Matrix Factorization for Online Recommendation with Implicit Feedback论文代码分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1 數據結構

userCount:用戶數
itemCount:項目數
user_ratings:ArrayList<ArrayList>,
問:此處為什么要用二維數組?
答:第1維是用戶,第2維是用戶對所有項目的評分。
testRatings:ArrayList
問:此處為什么只用一維數組?
答:個人認為這個處理有問題,因為每個用戶有1-2個評分作為測試集,如果用一維數組,則數組的下標就不能和用戶id(userId)一一對應。

2 讀取評分:ReadRatings_HoldOneOut

步驟如下:

  • 從文件中一行行讀取,然后存入user_ratings中,存儲后如下:
    用戶0:
    [<0,0,4.0,0>,<0,1,4.0,0>,…,<0,64,5.0,0>,<0,65,3.0,0>][<0,0,4.0,0>, <0,1,4.0,0>, \dots, <0,64,5.0,0>, <0,65,3.0,0>][<0,0,4.0,0>,<0,1,4.0,0>,,<0,64,5.0,0>,<0,65,3.0,0>]
    注:<userId, itemId, score, timestamp>,<0,0,4.0,0><0,0,4.0,0><0,0,4.0,0>可以解讀為用戶0對項目0在0時刻評分為4.0分。
    用戶1:
    [<1,0,5.0,0>,<1,66,4.0,0>,…,<1,192,1.0,0>,<1,193,5.0,0>][<1,0,5.0,0>, <1,66,4.0,0>, \dots, <1,192,1.0,0>, <1,193,5.0,0>][<1,0,5.0,0>,<1,66,4.0,0>,,<1,192,1.0,0>,<1,193,5.0,0>]
    用戶2:
    [<2,0,5.0,0>,<2,194,5.0,0>,…,<2,202,5.0,0>,<2,203,5.0,0>][<2,0,5.0,0>, <2,194,5.0,0>, \dots, <2,202,5.0,0>, <2,203,5.0,0>][<2,0,5.0,0>,<2,194,5.0,0>,,<2,202,5.0,0>,<2,203,5.0,0>]
  • 利用user_ratings構造訓練集和測試集testRatings
    [<0,65,3.0,0>,<0,64,5.0,0>,<1,193,5.0,0>,<1,192,1.0,0>,<2,203,5.0,0>,<2,202,5.0,0>,<3,278,5.0,0>,<3,277,4.0,0>,<4,290,4.0,0>,<4,289,5.0,0>,<5,328,2.0,0>,<5,327,5.0,0>,<6,394,4.0,0>,<6,393,5.0,0>,<7,406,5.0,0>,<7,405,2.0,0>,<8,420,3.0,0>,<8,419,3.0,0>,<9,482,5.0,0>,<9,481,4.0,0>,…][<0,65,3.0,0>, <0,64,5.0,0>, <1,193,5.0,0>, <1,192,1.0,0>, <2,203,5.0,0>, <2,202,5.0,0>, <3,278,5.0,0>, < 3,277,4.0,0>, <4,290,4.0,0>, <4,289,5.0,0>, <5,328,2.0,0>, <5,327,5.0,0>, <6,394,4.0,0>, <6,393,5.0,0>, <7,406,5.0,0>, <7,405,2.0,0>, <8,420,3.0,0>, <8,419,3.0,0>, <9,482,5.0,0>, <9,481,4.0,0>, \dots][<0,65,3.0,0>,<0,64,5.0,0>,<1,193,5.0,0>,<1,192,1.0,0>,<2,203,5.0,0>,<2,202,5.0,0>,<3,278,5.0,0>,<3,277,4.0,0>,<4,290,4.0,0>,<4,289,5.0,0>,<5,328,2.0,0>,<5,327,5.0,0>,<6,394,4.0,0>,<6,393,5.0,0>,<7,406,5.0,0>,<7,405,2.0,0>,<8,420,3.0,0>,<8,419,3.0,0>,<9,482,5.0,0>,<9,481,4.0,0>,]
    問:這種方式有問題沒有?
    答:有,測試集由于是一個一維的列表,導致利用testRatings.get(u).itemId這個代碼來取數據的時候,u并不是指代某個用戶id,而是列表中某個位置的下標,容易誤解為用戶id和項目id不匹配。
  • 上面的不匹配是由于下面的代碼導致的,由于每一個用戶將最后兩個評分加入到測試集,導致用戶id和列表的下標對應不上。

    //if (i == ratings.size() - 1) { // test if (i == ratings.size() - 1 || i == ratings.size() - 2) { // testtestRatings.add(ratings.get(i));//the size of testing = the number of users. } else { // traintrainMatrix.setValue(userId, itemId, ratings.get(i).score); }//of if

    方案(1):改成如下代碼即可,使得每個用戶只有一個評分加入測試集,即測試集大小和用戶數一致

    if (i == ratings.size() - 1) { // test //if (i == ratings.size() - 1 || i == ratings.size() - 2) { // testtestRatings.add(ratings.get(i));//the size of testing = the number of users. } else { // traintrainMatrix.setValue(userId, itemId, ratings.get(i).score); }//of if

    方案(2):可以用二維列表來存儲測試集。

    3 evaluate_for_user的理解

    3.1 數據結構

    map_item_score:HashMap<Integer, Double>,散列表。HashMap的主干是一個Entry數組,Entry是HashMap的基本組成單元,每一個Entry包含一個key-value鍵值對。

    HashMap<Integer, Double> map_item_score = new HashMap<Integer, Double>();

    ignoreSet:HashSet ,HashSet 基于 HashMap 來實現的,一個不允許有重復元素的集合。

    3.2 代碼解讀

    /*** Evaluation for a specific user with given GT item.對具有給定Groud-Truth項目的特定用戶的評估* @return:* result[0]: hit ratio* result[1]: ndcg* result[2]: precision*/protected double[] evaluate_for_user(int u, int gtItem) {double[] result = new double[3];HashMap<Integer, Double> map_item_score = new HashMap<Integer, Double>();// Get the score of the test item first.double maxScore = predict(u, gtItem);// Early stopping if there are topK items larger than maxScore.int countLarger = 0;for (int i = 0; i < itemCount; i++) {double score = predict(u, i);//預測用戶u對所有項目的評分map_item_score.put(i, score);//將預測評分放入散列表中,key為i,value為score//下面的兩句的作用是只要gtItem沒有進入TopK則不計算三個評價指標?if (score > maxScore) countLarger ++;if (countLarger > topK) return result; // early stopping}// Selecting topK items (does not exclude train items).ArrayList<Integer> rankList = ignoreTrain ? CommonUtils.TopKeysByValue(map_item_score, topK, trainMatrix.getRowRef(u).indexList()) : CommonUtils.TopKeysByValue(map_item_score, topK, null);result[0] = getHitRatio(rankList, gtItem);result[1] = getNDCG(rankList, gtItem);result[2] = getPrecision(rankList, gtItem);return result;}/*** Get the topK keys (by its value) of a map. Does not consider the keys which are in ignoreKeys.* @param map* @return*/public static<K, V extends Comparable<? super V>> ArrayList<K> TopKeysByValue(Map<K, V> map, int topK, ArrayList<K> ignoreKeys) {HashSet<K> ignoreSet;if (ignoreKeys == null) {ignoreSet = new HashSet<K>();} else {ignoreSet = new HashSet<K> (ignoreKeys);//將訓練集中用戶u購買過的項目放入ignoreSet}//因為map保存的是所有項目,如果要忽略訓練集中的項目,則將訓練集之外的項目寫入topQueueTopKPriorityQueue<K, V> topQueue = new TopKPriorityQueue<K, V>(topK);for (Map.Entry<K, V> entry : map.entrySet()) {if (!ignoreSet.contains(entry.getKey())) {topQueue.add(entry);}}//對topQueue中的元素進行排序,排序后保存在topKeys并返回ArrayList<K> topKeys = new ArrayList<K>();for (Map.Entry<K, V> entry : topQueue.sortedList()) {topKeys.add(entry.getKey());}return topKeys;}public ArrayList<Map.Entry<K, V>> sortedList() {ArrayList<Map.Entry<K, V>> list = new ArrayList<Map.Entry<K, V>>(queue); Collections.sort(list, c.reversed()); return list;}

    Collections.sort參考博客https://baijiahao.baidu.com/s?id=1660417080221659283&wfr=spider&for=pc

    這里還用到了一個非常重要的接口Comparable。
    功能: Comparable接口可用于對象的排序或者對象的分組

    介紹: Comparable接口強行對實現它的類的每個實例進行自然排序,該接口的唯一方法compareTo方法被稱為自然比較方法
    方法: int compareTo(Object o)

    利用當前對象和傳入的目標對象進行比較:

    • 若是當前對象比目標對象大,則返回1,那么當前對象會排在目標對象的后面
    • 若是當前對象比目標對象小,則返回-1,那么當前對象會排在目標對象的后面
    • 若是兩個對象相等,則返回0
    import java.util.Arrays;public class User implements Comparable<User> {public int age;public String username;public User(int age, String username) {this.age = age;this.username = username;}@Overridepublic String toString() {return this.username;}@Overridepublic int compareTo(User o) {if(this.age>o.age) {return 1;} else if(this.age<o.age) {return -1;} else {return 0;}}public static void main(String[] args) {User[] arr = new User[3];arr[0] = new User(15,"user1");arr[1] = new User(10,"user2");arr[2] = new User(20,"user3");System.out.println("排序前:" + Arrays.toString(arr));Arrays.sort(arr);System.out.println("排序后:" + Arrays.toString(arr));} }排序前:[user1, user2, user3] 排序后:[user2, user1, user3]

    總結

    以上是生活随笔為你收集整理的Fast Matrix Factorization for Online Recommendation with Implicit Feedback论文代码分析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。