个人技术总结-协同过滤

131802110-黄宏鹏 学生 2022-06-28 18:20:45
这个作业属于哪个课程软工实践2022年春-F班社区
这个作业要求在哪里软件工程实践总结&个人技术博客
这个作业的目标个人技术博客
其他参考文献CSDN社区

目录

  • 基于用户的协同过滤算法
  • 技术概述
  • 技术实现
  • 皮尔森系数LIst的计算
  • 通过皮尔森系数LIst确定最近邻LIst
  • 通过最近邻LIst进行推荐
  • 技术总结

基于用户的协同过滤算法

技术概述

本次软件工程实践,主要的工作是后端的开发工作。所运用的框架是springboot2,主要负责后端的推荐设计和推荐算法编写。
推荐算法用到的主要技术是基于用户的协同过滤算法。

协同过滤(简称CF)是推荐系统最重要的思想之一。在早期,协同过滤几乎等同于推荐系统。主要的功能是预测和推荐。算法通过对用户历史行为数据的挖掘发现用户的偏好,基于不同的偏好对用户进行群组划分并推荐品味相似的商品。协同过滤推荐算法分为两类,分别是:1、基于用户的协同过滤算法(user-based collaboratIve filtering)(相似的用户可能喜欢相同物品);2、基于物品的协同过滤算法(item-based collaborative filtering)(相似的物品可能被同个用户喜欢)。

技术实现

推荐算法的主要思想就是运用一定的数学公式构造各个关系之间的相似度并进行推荐。我主要使用的公式为皮尔森相关系数的推荐,即计算两个用户之间的对于文章点赞的相似度,进行相似度排序。通过选择前某几个相似度高的用户的相关非重复事物进行推荐。以下为皮尔森相关系数的计算公式:

img

皮尔森系数LIst的计算

这里的计算主要是将两个用户之间对于某个帖子的点赞数作为两者的相似度计算的XY值,然后通过计算每个用户的皮尔森系数来得到皮尔森系数的表,也就是皮尔森系数计算公式的实现。

 public double pearson_dis(List<likelist> rating1, List<likelist> rating2) {
        double sum_xy = 0.0D;
        double sum_x = 0.0D;
        double sum_y = 0.0D;
        double sum_x2 = 0.0D;
        double sum_y2 = 0.0D;
        double n = 0.0D;
        double avg_x = 0.0D;
        double avg_y = 0.0D;

        double sup_xy;
        double sup_x22;
        for(int i = 0; i < rating1.size(); ++i) {
            likelist userName = (likelist)rating1.get(i);

            for(int j = 0; j < rating2.size(); ++j) {
                likelist recommendUser = (likelist)rating2.get(j);
                if (userName.getPostid().equals(recommendUser.getPostid())) {
                    ++n;
                    sup_xy = (double)(userName.getCount() * 10);
                    sup_x22 = (double)(recommendUser.getCount() * 10);
                    sum_xy += sup_xy * sup_x22;
                    sum_x += sup_xy;
                    sum_y += sup_x22;
                    sum_x2 += Math.pow(sup_xy, 2.0D);
                    sum_y2 += Math.pow(sup_x22, 2.0D);
                }
            }
        }

        avg_x = sum_x / n;
        avg_y = sum_y / n;
        System.out.println("N=" + n + " avg" + avg_x + "avg_x" + avg_y);
        double sup_x2 = 0.0D;
        double sup_y2 = 0.0D;
        sup_xy = 0.0D;
        sup_x22 = 0.0D;
        double sup_y22 = 0.0D;

        for(int i = 0; i < rating1.size(); ++i) {
            likelist userName2 = (likelist)rating1.get(i);

            for(int j = 0; j < rating2.size(); ++j) {
                likelist recommendUser2 = (likelist)rating2.get(j);
                if (userName2.getPostid().equals(recommendUser2.getPostid())) {
                    double x = (double)(userName2.getCount() * 10);
                    double y = (double)(recommendUser2.getCount() * 10);
                    sup_x2 += x - avg_x;
                    sup_y2 += y - avg_y;
                    sup_x22 += Math.pow(sup_x2, 2.0D);
                    sup_y22 += Math.pow(sup_y2, 2.0D);
                    sup_xy += sup_y2 * sup_x2;
                }
            }
        }

        double denominator2 = Math.sqrt(sup_x22 * sup_y22);
        System.out.println("denominator2   " + sup_xy + " " + sup_xy + " sup_x2 " + sup_xy + " " + sup_xy + " supy2 " + sup_xy / denominator2);
        double denominator = Math.sqrt(sum_x2 - Math.pow(sum_x, 2.0D) / n) * Math.sqrt(sum_y2 - Math.pow(sum_y, 2.0D) / n);
        if (denominator2 == 0.0D) {
            return 0.0D;
        } else {
            return sup_xy / denominator2;
        }
    }

通过皮尔森系数LIst确定最近邻LIst

    public Map<String, Double> computeNearestNeighbor(likelist user, Map<String, List<likelist>> likelistMap) {
        Map<String, Double> distances = new TreeMap();
        Iterator var4 = likelistMap.entrySet().iterator();

        while(var4.hasNext()) {
            Entry<String, List<likelist>> entry = (Entry)var4.next();
            String mapKey = (String)entry.getKey();
            List<likelist> mapValue = (List)entry.getValue();
            if (!mapKey.equals(user.getUserid().toString())) {
                double distance = this.pearson_dis((List)likelistMap.get(user.getUserid().toString()), mapValue);
                PrintStream var10000 = System.out;
                String var10001 = (String)entry.getKey();
                var10000.println("key" + var10001 + " distance" + distance);
                distances.put(mapKey, distance);
            }
        }

        System.out.println("distance" + distances);
        return distances;
    }

通过最近邻LIst进行推荐

 public List<Integer> likeListRecommend(likelist user) {
        List<Integer> recommendations = new LinkedList();
        List<likelist> AllUser = this.likelistMapper.findByUser();
        List<String> AllUserId = new ArrayList();
        Iterator var5 = AllUser.iterator();

        while(var5.hasNext()) {
            likelist like = (likelist)var5.next();
            AllUserId.add(like.getUserid().toString());
        }

        List<String> listNew = new ArrayList(new TreeSet(AllUserId));
        Map<String, List<likelist>> likelistMap = new HashMap();
        Iterator var7 = listNew.iterator();

        while(var7.hasNext()) {
            String userN = (String)var7.next();
            likelistMap.put(userN, this.likelistMapper.findById(userN));
        }

        Map<String, Double> distances = this.computeNearestNeighbor(user, likelistMap);
        double maxKey = 0.0D;
        List<String> maxValue = new LinkedList();
        Iterator var11 = distances.entrySet().iterator();

        String neighber;
        while(var11.hasNext()) {
            Entry<String, Double> entry = (Entry)var11.next();
            neighber = (String)entry.getKey();
            Double mapValue = (Double)entry.getValue();
            if (mapValue >= 0.8D && !neighber.equals(user.getUserid())) {
                maxValue.add(neighber);
            }
        }

        List<Integer> RecommendList = new ArrayList();
        Iterator var23 = maxValue.iterator();

        Iterator var16;
        while(var23.hasNext()) {
            neighber = (String)var23.next();
            List<likelist> flag = (List)likelistMap.get(neighber);
            List<Integer> likelistFlagList = new LinkedList();
            var16 = flag.iterator();

            while(var16.hasNext()) {
                likelist likelist = (likelist)var16.next();
                likelistFlagList.add(likelist.getPostid());
            }

            RecommendList.addAll(likelistFlagList);
        }

        List<Integer> newRecommendList = new ArrayList(new TreeSet(RecommendList));
        List<likelist> userList = this.likelistMapper.findById(user.getUserid().toString());
        System.out.println("maxvalue" + maxValue);
        System.out.println("Recommendations" + RecommendList);
        System.out.println("userlist" + userList);
        System.out.println("newRecommendations" + newRecommendList);
        Iterator var27 = userList.iterator();

        while(var27.hasNext()) {
            likelist likelist = (likelist)var27.next();
            var16 = newRecommendList.iterator();

            while(var16.hasNext()) {
                Integer i = (Integer)var16.next();
                if (likelist.getPostid() == i) {
                    recommendations.add(i);
                }
            }
        }

        newRecommendList.removeAll(recommendations);
        if (recommendations.isEmpty()) {
        }

        System.out.println(newRecommendList);
        return newRecommendList;
    }

技术总结

基于用户的协同过滤适用于用户较少的场合,如果用户很多,计算用户相似度矩阵代价很大。,还需要更多的理解更多的算法,选择一个更加适合的算法来推荐用户喜欢的帖子。

...全文
110 回复 打赏 收藏 举报
写回复
回复
切换为时间正序
请发表友善的回复…
发表回复
相关推荐
发帖
软件工程实践2022年春-F班

103

社区成员

福州大学-计算机与大数据学院-傅明建
软件工程 高校
社区管理员
  • Mingjian_Fu
  • Lyu-
  • Wake_lie
加入社区
帖子事件
编辑了帖子 (查看)
2022-06-28 18:29
创建了帖子
2022-06-28 18:20
社区公告

本次作业截止时间为2022-02-18 23:59:59,请未完成的同学抓紧时间,加入社区后的同学要按照“学号-姓名”的格式修改社区昵称。