日撸 Java 三百行day54-55

这篇具有很好参考价值的文章主要介绍了日撸 Java 三百行day54-55。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

说明

闵老师的文章链接: 日撸 Java 三百行(总述)_minfanphd的博客-CSDN博客
自己也把手敲的代码放在了github上维护:https://github.com/fulisha-ok/sampledata

day54 基于 M-distance 的推荐

1. M-distance 理解

例如day51-53中的KNN我们预测一个物品类别,我们是以测试样本和我们训练样本的距离的远近来找k个最相似似的邻居,对这k个邻居评分来预测测试样本的类别。而M-distance是根据平均分来计算两个用户 (或项目) 之间的距离。
如下图标这是以基于项目来预测得分的例子。例如预测用户u0对m2的评分,我们怎么来找邻居呢?我们是求出每个项目的平均分,找离m2平均分半径范围内的项目求平均分来预测得分。
日撸 Java 三百行day54-55

2.代码理解

1.代码中变量的解读

文档中的内容有100000行记录,数据如下(部分):
日撸 Java 三百行day54-55
一行代表的意思:0用户对项目0的评分,评分为5分;有943个用户,1682部电影,100000个评分;对部分变量说明

  • 总数统计(用户数量,项目数量,评分数)
private  int numItems; 
private int numUsers;
private int numRatings;

-日撸 Java 三百行day54-55

  • compressedRatingMatrix(压缩的评分矩阵-实际上就是把文件内容读出来)
    就本次文本来看,共有100000条记录
 private int[][] compressedRatingMatrix;

日撸 Java 三百行day54-55

  • userDegrees(每个用户评分的项目数量)
 private int[] userDegrees;

日撸 Java 三百行day54-55

  • userStartingIndices(每个用户的起始索引,例如用户1的起始索引是272)
 private int[] userStartingIndices;

日撸 Java 三百行day54-55- userAverageRatings(每个用户评价项目的一个平均分)

private double[] userAverageRatings;

日撸 Java 三百行day54-55

  • itemDegrees (每个项目被评分的次数-也可以理解为有多少用户评分了)
private int[] itemDegrees;

日撸 Java 三百行day54-55

  • itemAverageRatings (每个项目的平均分)
 private double[] itemAverageRatings;

日撸 Java 三百行day54-55
MBR构造函数即是对上面的变量进行赋值,初始化。

2.leave-one-out测试

之前在knn中已经接触过了,即将数据集中的每一个样本都被单独作为测试集,而剩下的样本就作为训练集.
以一个测试集来举例。例如我们将第一行的数据作为测试集(0,0,5)我们知道这是用户0对项目0评分为5分,我们现在结合其他项目来预测项目0的评分。接下来的步骤为:

  • 先移除这个用户0对项目0的评分,重新计算对项目0的平均分
    日撸 Java 三百行day54-55
  • 找邻居(这里是基于项目进行预测,去找用户评论过的项目的平均分与当前项目的平均分差值在一个半径范围内,则作为邻居,并累计他的评分)。如我们知道用户0评论了272部电影,排除项目0,我们要从271部电影中去找邻居来预测项目0的评分。
  • 若找到了邻居则求他们的平均分。如用户0找到94个邻居,总分387分,那我们预测用户0对项目0的预测分数为:4.117021276595745
    日撸 Java 三百行day54-55
  • 完整代码:
    public void leaveOneOutPrediction() {
        double tempItemAverageRating;
        // Make each line of the code shorter.
        int tempUser, tempItem, tempRating;
        System.out.println("\r\nLeaveOneOutPrediction for radius " + radius);

        numNonNeighbors = 0;
        for (int i = 0; i < numRatings; i++) {
            tempUser = compressedRatingMatrix[i][0];
            tempItem = compressedRatingMatrix[i][1];
            tempRating = compressedRatingMatrix[i][2];

            // Step 1. Recompute average rating of the current item.
            tempItemAverageRating = (itemAverageRatings[tempItem] * itemDegrees[tempItem] - tempRating)
                    / (itemDegrees[tempItem] - 1);

            // Step 2. Recompute neighbors, at the same time obtain the ratings
            // Of neighbors.
            int tempNeighbors = 0;
            double tempTotal = 0;
            int tempComparedItem;
            for (int j = userStartingIndices[tempUser]; j < userStartingIndices[tempUser + 1]; j++) {
                tempComparedItem = compressedRatingMatrix[j][1];
                if (tempItem == tempComparedItem) {
                    continue;// Ignore itself.
                } // Of if

                if (Math.abs(tempItemAverageRating - itemAverageRatings[tempComparedItem]) < radius) {
                    tempTotal += compressedRatingMatrix[j][2];
                    tempNeighbors++;
                }
            }
            // Step 3. Predict as the average value of neighbors.
            if (tempNeighbors > 0) {
                predictions[i] = tempTotal / tempNeighbors;
            } else {
                predictions[i] = DEFAULT_RATING;
                numNonNeighbors++;
            }
        }
    }

3.计算MAE(平均绝对误差)

预测值与实际值之间的平均绝对偏差程度(MAE 的值越小,表示预测结果与实际值的偏差越小,预测模型的准确性越高)

    public double computeMAE() throws Exception {
        double tempTotalError = 0;
        for (int i = 0; i < predictions.length; i++) {
            tempTotalError += Math.abs(predictions[i] - compressedRatingMatrix[i][2]);
        } 

        return tempTotalError / predictions.length;
    }

4.计算RMSE(均方根误差)

预测值与实际值之间的平方值偏差程度。RMSE 的值越小,表示预测结果与实际值的均方差越小,预测模型的准确性越高

 public double computeRSME() throws Exception {
        double tempTotalError = 0;
        for (int i = 0; i < predictions.length; i++) {
            tempTotalError += (predictions[i] - compressedRatingMatrix[i][2])
                    * (predictions[i] - compressedRatingMatrix[i][2]);
        } 
        
        double tempAverage = tempTotalError / predictions.length;
        return Math.sqrt(tempAverage);
    }

日撸 Java 三百行day54-55

day55 基于 M-distance 的推荐(续)

1.基于用户和基于项目的推荐

  • day 54基于项目的推荐
    我们预测m2的评分是:计算每个项目(m0~m5)的一个平均分,找到邻居(m1,m3)我们求他的品平均就是我们对m2的一个预测分数。(在这个过程中我们是根据项目邻居去评估的得分)
    日撸 Java 三百行day54-55
  • 基于用户的推荐
    我们预测m2的评分:计算每个用户评分的项目(u0~u4),找到邻居(u1),求他们的平均分即我们对m2的预测得分。
    日撸 Java 三百行day54-55

2.基于用户推荐代码思路

我最开始也想到的是对compressedRatingMatrix重新赋值,使数组进用户与项目关系互换。但最后我还是想采用列表的方式来编码。我大致思路如下:

2.1 抽象文本内容

将文本内容涉及的三个指标抽象为一个对象Text.其中userNum代表用户的编号,itemNum代表项目的编号,score代表用户对项目的评分。

    class Text{
        private Integer userNum;
        private Integer itemNum;
        private Integer score;

        public Integer getUserNum() {
            return userNum;
        }

        public void setUserNum(Integer userNum) {
            this.userNum = userNum;
        }

        public Integer getItemNum() {
            return itemNum;
        }

        public void setItemNum(Integer itemNum) {
            this.itemNum = itemNum;
        }

        public Integer getScore() {
            return score;
        }

        public void setScore(Integer score) {
            this.score = score;
        }

        public Text(Integer userNum, Integer itemNum, Integer score) {
            this.userNum = userNum;
            this.itemNum = itemNum;
            this.score = score;
        }
    }

2.2 构造函数, 初始化MBR对象(借助jdk1.8新特性–Stream流)

stream流的知识可以百度使用(结合Lambda表达式),他可以对集合进行非常复杂的查找、过滤、筛选等操作。

我大致思路是将文本内容放在一个列表中:List textList,我对这个textList采用stream流进行分组,按电影编号分组Map<Integer, List > textGroupByItem和按用户编号分组Map<Integer, List > textGroupByUser。并对相应的数组进行赋值。

stream流的使用:

// 按电影编号分组
textGroupByItem = textList.stream().collect(Collectors.groupingBy(Text::getItemNum));
//按用户编号分组
textGroupByUser = textList.stream().collect(Collectors.groupingBy(Text::getUserNum));
//对列表中某一属性求和
tempUserTotalScore[i] = textsByUser.stream().mapToDouble(Text::getScore).sum();

代码:

    public MBR(String paraFileName, int paraNumUsers, int paraNumItems, int paraNumRatings, boolean basedUser) throws Exception {
        if (basedUser){
            //基于用户的计算
            //step1. initialize these arrays
            numItems = paraNumItems;
            numUsers = paraNumUsers;
            numRatings = paraNumRatings;

            userDegrees = new int[numUsers];
            userAverageRatings = new double[numUsers];
            itemDegrees = new int[numItems];
            itemAverageRatings = new double[numItems];
            predictions = new double[numRatings];

            System.out.println("Reading " + paraFileName);

            //step2. Read the data file
            File tempFile = new File(paraFileName);
            if (!tempFile.exists()) {
                System.out.println("File " + paraFileName + " does not exists.");
                System.exit(0);
            }
            BufferedReader tempBufReader = new BufferedReader(new FileReader(tempFile));
            String tempString;
            String[] tempStrArray;
            while ((tempString = tempBufReader.readLine()) != null) {
                // Each line has three values
                tempStrArray = tempString.split(",");
                //把数据读入到textList列表中
                Text text = new Text(Integer.parseInt(tempStrArray[0]), Integer.parseInt(tempStrArray[1]), Integer.parseInt(tempStrArray[2]));
                textList.add(text);
            }
            tempBufReader.close();

            //按电影号分组
            textGroupByItem = textList.stream().collect(Collectors.groupingBy(Text::getItemNum));
            textGroupByUser = textList.stream().collect(Collectors.groupingBy(Text::getUserNum));
            double[] tempUserTotalScore = new double[numUsers];
            double[] tempItemTotalScore = new double[numItems];
            for (int i = 0; i < numUsers; i++) {
                // 用户的总分
                List<Text> textsByUser = textGroupByUser.get(i);
                tempUserTotalScore[i] = textsByUser.stream().mapToDouble(Text::getScore).sum();
                userDegrees[i] = textsByUser.size();
                userAverageRatings[i] = tempUserTotalScore[i] / userDegrees[i];
            }

            for (int i = 0; i < numItems; i++) {
                try {
                    // 电影的总分
                    List<Text> textsByItem = textGroupByItem.get(i);
                    tempItemTotalScore[i] = textsByItem.stream().mapToDouble(Text::getScore).sum();
                    itemDegrees[i] = textsByItem.size();
                    itemAverageRatings[i] = tempItemTotalScore[i] / itemDegrees[i];
                } catch (Exception e) {
                    System.out.println(e.getMessage());
                }

            }
        }
    }

2.3 leave-one-out测试

leave-one-out测试中,以文本中第一条记录为例子(0,0,5)我们要预测对项目0的评分
(1)第一步:排除用户0对项目0的评分(用户0评论了272个项目),重新计算用户0的平均分(271个项目)
(2)第二步:我们看对项目0评分的用户个数(452个),依次遍历用户的平均分与我们重新计算的平均分之差是否在半径范围内,从而累计邻居个数以及他们的总分。
(3)第三步:预测用户0对项目0的得分

stream流的使用:

// 对列表过滤数据
textsByUser = textsByUser.stream().filter(e -> !e.getItemNum().equals(outItem)).collect(Collectors.toList());

代码:

    public void leaveOneOutPredictionByUser() {
        double tempItemAverageRating;
        // Make each line of the code shorter.
        int tempUser, tempItem, tempRating;
        System.out.println("\r\nLeaveOneOutPredictionUser for radius " + radius);

        numNonNeighbors = 0;
        for (int i = 0; i < numRatings; i++) {
            Text text = textList.get(i);
            tempUser = text.getUserNum();
            tempItem = text.getItemNum();
            tempRating = text.getScore();

            // Step 1. Recompute average rating of the current user.
            List<Text> textsByUser = textGroupByUser.get(tempUser);
            Integer outItem = tempItem;
            textsByUser = textsByUser.stream().filter(e -> !e.getItemNum().equals(outItem)).collect(Collectors.toList());
            tempItemAverageRating = textsByUser.stream().mapToDouble(Text::getScore).sum() / textsByUser.size();

            // Step 2. Recompute neighbors, at the same time obtain the ratings
            // Of neighbors.
            int tempNeighbors = 0;
            double tempTotal = 0;
            List<Text> texts = textGroupByItem.get(tempItem);
            for (int j = 0; j < texts.size(); j++) {
                Text userText = texts.get(j);
                if (tempUser == j) {
                    continue;// Ignore itself.
                }

                if (Math.abs(tempItemAverageRating - userAverageRatings[userText.getUserNum()]) < radius) {
                    tempTotal += userText.getScore();
                    tempNeighbors++;
                }
            }
            // Step 3. Predict as the average value of neighbors.
            if (tempNeighbors > 0) {
                predictions[i] = tempTotal / tempNeighbors;
            } else {
                predictions[i] = DEFAULT_RATING;
                numNonNeighbors++;
            }
        }

    }

2.4 代码结果

日撸 Java 三百行day54-55文章来源地址https://www.toymoban.com/news/detail-465670.html

  • day54-55代码
package machinelearing.knn;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class MBR {
    /**
     * Default rating for 1-5 points
     */
    public static final double DEFAULT_RATING = 3.0;

    /**
     * the total number of users (参与评分的用户数量)
     */
    private int numUsers;


    /**
     * the total number of items (评分的物品数量)
     */
    private  int numItems;

    /**
     * the total number of ratings (no-zero values) (非零评分值的数量)
     */
    private int numRatings;


    /**
     * the predictions
     */
    private double[] predictions;

    /**
     * Compressed rating matrix. user-item-rating triples (压缩的评分矩阵,存储用户-物品-评分的三元组)
     */
    private int[][] compressedRatingMatrix;

    /**
     * The degree of users (how many item he has rated). (用户已评分的物品数量)
     */
    private int[] userDegrees;

    /**
     * The average rating of the current user. (当前用户的平均评分。存储每个用户的平均评分值)
     */
    private double[] userAverageRatings;

    /**
     * The degree of users (how many item he has rated). (物品被评分的次数)
     */
    private int[] itemDegrees;

    /**
     * The average rating of the current item. (当前物品的平均评分。存储每个物品的平均评分值)
     */
    private double[] itemAverageRatings;

    /**
     * The first user start from 0. Let the first user has x ratings, the second user will start from x. (用户起始索引。第一个用户的起始索引为0,第二个用户的起始索引为前一个用户评分的数量。用于定位用户的评分在compressedRatingMatrix中的位置。)
     */
    private int[] userStartingIndices;

    /**
     * Number of non-neighbor objects. (非邻居对象的数量。用于表示在某个半径内不属于邻居的对象的数量。)
     */
    private int numNonNeighbors;

    /**
     * The radius (delta) for determining the neighborhood. (: 确定邻域的半径(delta)。用于确定邻域内的对象,即在该半径范围内的对象被视为邻居。)
     */
    private double radius;

    List<Text> textList = new ArrayList<>();

    private Map<Integer, List<Text>> textGroupByItem = new HashMap<>();

    private Map<Integer, List<Text>> textGroupByUser= new HashMap<>();

    class Text{
        private Integer userNum;
        private Integer itemNum;
        private Integer score;

        public Integer getUserNum() {
            return userNum;
        }

        public void setUserNum(Integer userNum) {
            this.userNum = userNum;
        }

        public Integer getItemNum() {
            return itemNum;
        }

        public void setItemNum(Integer itemNum) {
            this.itemNum = itemNum;
        }

        public Integer getScore() {
            return score;
        }

        public void setScore(Integer score) {
            this.score = score;
        }

        public Text(Integer userNum, Integer itemNum, Integer score) {
            this.userNum = userNum;
            this.itemNum = itemNum;
            this.score = score;
        }
    }


    public MBR(String paraFileName, int paraNumUsers, int paraNumItems, int paraNumRatings) throws Exception{
        //step1. initialize these arrays
        numItems = paraNumItems;
        numUsers = paraNumUsers;
        numRatings = paraNumRatings;

        userDegrees = new int[numUsers];
        userStartingIndices = new int[numUsers + 1];
        userAverageRatings = new double[numUsers];
        itemDegrees = new int[numItems];
        compressedRatingMatrix = new int[numRatings][3];
        itemAverageRatings = new double[numItems];
        predictions = new double[numRatings];

        System.out.println("Reading " + paraFileName);

        //step2. Read the data file
        File tempFile = new File(paraFileName);
        if (!tempFile.exists()) {
            System.out.println("File " + paraFileName + " does not exists.");
            System.exit(0);
        }
        BufferedReader tempBufReader = new BufferedReader(new FileReader(tempFile));
        String tempString;
        String[] tempStrArray;
        int tempIndex = 0;
        userStartingIndices[0] = 0;
        userStartingIndices[numUsers] = numRatings;
        while ((tempString = tempBufReader.readLine()) != null) {
            // Each line has three values
            tempStrArray = tempString.split(",");
            compressedRatingMatrix[tempIndex][0] = Integer.parseInt(tempStrArray[0]);
            compressedRatingMatrix[tempIndex][1] = Integer.parseInt(tempStrArray[1]);
            compressedRatingMatrix[tempIndex][2] = Integer.parseInt(tempStrArray[2]);

            userDegrees[compressedRatingMatrix[tempIndex][0]]++;
            itemDegrees[compressedRatingMatrix[tempIndex][1]]++;

            if (tempIndex > 0) {
                // Starting to read the data of a new user.
                if (compressedRatingMatrix[tempIndex][0] != compressedRatingMatrix[tempIndex - 1][0]) {
                    userStartingIndices[compressedRatingMatrix[tempIndex][0]] = tempIndex;
                }
            }
            tempIndex++;
        }
        tempBufReader.close();

        double[] tempUserTotalScore = new double[numUsers];
        double[] tempItemTotalScore = new double[numItems];
        for (int i = 0; i < numRatings; i++) {
            tempUserTotalScore[compressedRatingMatrix[i][0]] += compressedRatingMatrix[i][2];
            tempItemTotalScore[compressedRatingMatrix[i][1]] += compressedRatingMatrix[i][2];
        }

        for (int i = 0; i < numUsers; i++) {
            userAverageRatings[i] = tempUserTotalScore[i] / userDegrees[i];
        }

        for (int i = 0; i < numItems; i++) {
            itemAverageRatings[i] = tempItemTotalScore[i] / itemDegrees[i];
        }

    }

    public MBR(String paraFileName, int paraNumUsers, int paraNumItems, int paraNumRatings, boolean basedUser) throws Exception {
        if (basedUser){
            //基于用户的计算
            //step1. initialize these arrays
            numItems = paraNumItems;
            numUsers = paraNumUsers;
            numRatings = paraNumRatings;

            userDegrees = new int[numUsers];
            userAverageRatings = new double[numUsers];
            itemDegrees = new int[numItems];
            itemAverageRatings = new double[numItems];
            predictions = new double[numRatings];

            System.out.println("Reading " + paraFileName);

            //step2. Read the data file
            File tempFile = new File(paraFileName);
            if (!tempFile.exists()) {
                System.out.println("File " + paraFileName + " does not exists.");
                System.exit(0);
            }
            BufferedReader tempBufReader = new BufferedReader(new FileReader(tempFile));
            String tempString;
            String[] tempStrArray;
            while ((tempString = tempBufReader.readLine()) != null) {
                // Each line has three values
                tempStrArray = tempString.split(",");
                //把数据读入到textList列表中
                Text text = new Text(Integer.parseInt(tempStrArray[0]), Integer.parseInt(tempStrArray[1]), Integer.parseInt(tempStrArray[2]));
                textList.add(text);
            }
            tempBufReader.close();

            //按电影号分组
            textGroupByItem = textList.stream().collect(Collectors.groupingBy(Text::getItemNum));
            textGroupByUser = textList.stream().collect(Collectors.groupingBy(Text::getUserNum));
            double[] tempUserTotalScore = new double[numUsers];
            double[] tempItemTotalScore = new double[numItems];
            for (int i = 0; i < numUsers; i++) {
                // 用户的总分
                List<Text> textsByUser = textGroupByUser.get(i);
                tempUserTotalScore[i] = textsByUser.stream().mapToDouble(Text::getScore).sum();
                userDegrees[i] = textsByUser.size();
                userAverageRatings[i] = tempUserTotalScore[i] / userDegrees[i];
            }

            for (int i = 0; i < numItems; i++) {
                try {
                    // 电影的总分
                    List<Text> textsByItem = textGroupByItem.get(i);
                    tempItemTotalScore[i] = textsByItem.stream().mapToDouble(Text::getScore).sum();
                    itemDegrees[i] = textsByItem.size();
                    itemAverageRatings[i] = tempItemTotalScore[i] / itemDegrees[i];
                } catch (Exception e) {
                    System.out.println(e.getMessage());
                }

            }
        }
    }

    public void setRadius(double paraRadius) {
        if (paraRadius > 0) {
            radius = paraRadius;
        } else {
            radius = 0.1;
        }
    }

    public void leaveOneOutPrediction() {
        double tempItemAverageRating;
        // Make each line of the code shorter.
        int tempUser, tempItem, tempRating;
       // System.out.println("\r\nLeaveOneOutPrediction for radius " + radius);

        numNonNeighbors = 0;
        for (int i = 0; i < numRatings; i++) {
            tempUser = compressedRatingMatrix[i][0];
            tempItem = compressedRatingMatrix[i][1];
            tempRating = compressedRatingMatrix[i][2];

            // Step 1. Recompute average rating of the current item.
            tempItemAverageRating = (itemAverageRatings[tempItem] * itemDegrees[tempItem] - tempRating)
                    / (itemDegrees[tempItem] - 1);

            // Step 2. Recompute neighbors, at the same time obtain the ratings
            // Of neighbors.
            int tempNeighbors = 0;
            double tempTotal = 0;
            int tempComparedItem;
            for (int j = userStartingIndices[tempUser]; j < userStartingIndices[tempUser + 1]; j++) {
                tempComparedItem = compressedRatingMatrix[j][1];
                if (tempItem == tempComparedItem) {
                    continue;// Ignore itself.
                } // Of if

                if (Math.abs(tempItemAverageRating - itemAverageRatings[tempComparedItem]) < radius) {
                    tempTotal += compressedRatingMatrix[j][2];
                    tempNeighbors++;
                }
            }
            // Step 3. Predict as the average value of neighbors.
            if (tempNeighbors > 0) {
                predictions[i] = tempTotal / tempNeighbors;
            } else {
                predictions[i] = DEFAULT_RATING;
                numNonNeighbors++;
            }
        }
    }


    public void leaveOneOutPredictionByUser() {
        double tempItemAverageRating;
        // Make each line of the code shorter.
        int tempUser, tempItem, tempRating;
        // System.out.println("\r\nLeaveOneOutPredictionUser for radius " + radius);

        numNonNeighbors = 0;
        for (int i = 0; i < numRatings; i++) {
            Text text = textList.get(i);
            tempUser = text.getUserNum();
            tempItem = text.getItemNum();
            tempRating = text.getScore();

            // Step 1. Recompute average rating of the current user.
            List<Text> textsByUser = textGroupByUser.get(tempUser);
            Integer outItem = tempItem;
            textsByUser = textsByUser.stream().filter(e -> !e.getItemNum().equals(outItem)).collect(Collectors.toList());
            tempItemAverageRating = textsByUser.stream().mapToDouble(Text::getScore).sum() / textsByUser.size();

            // Step 2. Recompute neighbors, at the same time obtain the ratings
            // Of neighbors.
            int tempNeighbors = 0;
            double tempTotal = 0;
            List<Text> texts = textGroupByItem.get(tempItem);
            for (int j = 0; j < texts.size(); j++) {
                Text userText = texts.get(j);
                if (tempUser == j) {
                    continue;// Ignore itself.
                }

                if (Math.abs(tempItemAverageRating - userAverageRatings[userText.getUserNum()]) < radius) {
                    tempTotal += userText.getScore();
                    tempNeighbors++;
                }
            }
            // Step 3. Predict as the average value of neighbors.
            if (tempNeighbors > 0) {
                predictions[i] = tempTotal / tempNeighbors;
            } else {
                predictions[i] = DEFAULT_RATING;
                numNonNeighbors++;
            }
        }

    }


    public double computeMAE() throws Exception {
        double tempTotalError = 0;
        for (int i = 0; i < predictions.length; i++) {
            tempTotalError += Math.abs(predictions[i] - compressedRatingMatrix[i][2]);
        } // Of for i

        return tempTotalError / predictions.length;
    }

    public double computeMAE_User() throws Exception {
        double tempTotalError = 0;
        for (int i = 0; i < predictions.length; i++) {
            tempTotalError += Math.abs(predictions[i] - textList.get(i).getScore());
        } // Of for i

        return tempTotalError / predictions.length;
    }


    public double computeRSME() throws Exception {
        double tempTotalError = 0;
        for (int i = 0; i < predictions.length; i++) {
            tempTotalError += (predictions[i] - compressedRatingMatrix[i][2])
                    * (predictions[i] - compressedRatingMatrix[i][2]);
        } // Of for i

        double tempAverage = tempTotalError / predictions.length;

        return Math.sqrt(tempAverage);
    }

    public double computeRSME_User() throws Exception {
        double tempTotalError = 0;
        for (int i = 0; i < predictions.length; i++) {
            tempTotalError += (predictions[i] - textList.get(i).getScore())
                    * (predictions[i] - textList.get(i).getScore());
        } // Of for i

        double tempAverage = tempTotalError / predictions.length;

        return Math.sqrt(tempAverage);
    }

    public static void main(String[] args) {
        try {
            MBR tempRecommender = new MBR("C:/Users/Desktop/sampledata/movielens-943u1682m.txt", 943, 1682, 100000);
            MBR tempRecommender1 = new MBR("C:/Users/Desktop/sampledata/movielens-943u1682m.txt", 943, 1682, 100000, true);
            for (double tempRadius = 0.2; tempRadius < 0.6; tempRadius += 0.1) {
                tempRecommender.setRadius(tempRadius);
                tempRecommender1.setRadius(tempRadius);

                tempRecommender.leaveOneOutPrediction();
                double tempMAE = tempRecommender.computeMAE();
                double tempRSME = tempRecommender.computeRSME();

                tempRecommender1.leaveOneOutPredictionByUser();
                double tempMAE1 = tempRecommender1.computeMAE_User();
                double tempRSME1 = tempRecommender1.computeRSME_User();

                System.out.println("Radius_item = " + tempRadius + ", MAE_item = " + tempMAE + ", RSME_item = " + tempRSME
                        + ", numNonNeighbors_item = " + tempRecommender.numNonNeighbors);

                System.out.println("Radius_user = " + tempRadius + ", MAE_user = " + tempMAE1 + ", RSME_user = " + tempRSME1
                        + ", numNonNeighbors_user = " + tempRecommender1.numNonNeighbors);
            }
        } catch (Exception ee) {
            System.out.println(ee);
        }
    }


}

到了这里,关于日撸 Java 三百行day54-55的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【代码随想录】刷题笔记Day54

    差单调栈就结束代码随想录一刷啦,回家二刷打算改用python补充进博客,小涛加油!!! 中心点外扩,注意中心点可能有一个元素可能有两个元素 dp数组含义 dp[i][j]:表示区间范围[i,j] (左闭右闭)的子串是否是回文子串,如果是dp[i][j]为true,否则为false 递推公式 s[i]与s[j

    2024年01月23日
    浏览(54)
  • 算法记录 | Day55 动态规划

    思路: 1.确定dp数组(dp table)以及下标的含义: dp[i][j] 表示以下标i-1为结尾的字符串s,和以下标j-1为结尾的字符串t,相同子序列的长度为 dp[i][j] 。 2.确定递推公式: if (s[i - 1] == t[j - 1]) t中找到了一个字符在s中也出现了, dp[i][j] = dp[i - 1][j - 1] + 1 if (s[i - 1] != t[j - 1]) 相当于t要

    2024年02月03日
    浏览(49)
  • Java课设-百行代码实现简易计算器

    Java程序设计 工程实践 ——简易计算器的设计 院、 系 计算机与软件学院 专业 信息安全 姓 名 指导教师 2022年 6 月 11 日 目录: 一、 设计简介 2 1、 设计背景 2 2、 开发工具及环境 2 (1)开发工具及介绍 2 (2)开发环境 2 二、 相关工作 2 1、设计基础 2 2、功能需求 2 3、系统

    2024年02月04日
    浏览(75)
  • day55 动规.p15 子序列

    - 392.判断子序列  ```cpp class Solution { public:     bool isSubsequence(string s, string t) {         vectorvectorint dp(s.size() + 1, vectorint(t.size() + 1, 0));         for (int i = 1; i = s.size(); i++) {             for (int j = 1; j = t.size(); j++) {                 if (s[i - 1] == t[j - 1]) dp[i][j] = dp[i - 1][j - 1] +

    2024年02月09日
    浏览(51)
  • day55 算法训练|动态规划part15

    给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,\\\"ace\\\"是\\\"abcde\\\"的一个子序列,而\\\"aec\\\"不是)。 其实就是最长公共子序列的变种题:如果公共子序列长度等于

    2024年02月02日
    浏览(63)
  • DAY55:动态规划(买卖股票的最佳时机3)

    这道题比上面状态更多,是因为卖出股票后,你无法在第二天买入股票 (即冷冻期为1天)。 状态 状态一:持有股票状态(今天买入股票,或者是之前就买入了股票然后没有操作,一直持有) 不持有股票状态,这里就有两种卖出股票状态 状态二:保持卖出股票的状态(两天前

    2024年02月22日
    浏览(47)
  • 【linux】:老师问什么是爱情,我说了句:软硬链接和动静态库

        文章目录 前言 一、软硬链接 二、动态库和静态库 总结   上一篇文章的最后我们讲解了文件的inode,那么文件名和inode有什么区别呢?区别就在于linux系统只认inode号,文件的inode属性中,并不存在文件名,而文件名其实是给用户用的。我们以前讲过linux文件目录,那么目

    2023年04月19日
    浏览(132)
  • java黑马头条 day5自媒体文章审核 敏感词过滤算法DFA 集成RabbitMQ实现自动审核

      做为内容类产品,内容安全非常重要,所以需要进行对自媒体用户发布的文章进行审核以后才能到app端展示给用户。2 WmNews 中 status 代表自媒体文章的状态 status字段:0 草稿 1 待审核 2 审核失败 3 人工审核 4 人工审核通过   8 审核通过(待发布) 9 已发布 当自媒体用户提交

    2024年02月06日
    浏览(41)
  • 跟着pink老师前端入门教程-day03

    6.1 表格的主要作用 主要用于 显示、展示数据 ,可以让数据显示的规整,可读性非常好,特别是后台展示数据时,能够熟练运用表格就显得很重要。 6.2 基本语法 6.3 表头单元格标签 一般表头单元格位于表格的 第一行或第一列 ,表头单元格里面的 文本内容加粗居中显示 ,突

    2024年01月18日
    浏览(46)
  • 算法训练Day55:392.判断子序列 115.不同的子序列

    Category Difficulty Likes Dislikes ContestSlug ProblemIndex Score algorithms Easy (52.43%) 858 0 - - 0 Tags Companies 给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如, \\\"ace\\\" 是 \\\"abcde\\\" 的

    2024年02月05日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包