zoukankan      html  css  js  c++  java
  • 推荐系统打散算法--权重

    上一篇轮询打散算法后,本文主要介绍推荐的另一种打散算法,权重打散算法,该算法适用较多维度打散的一种算法,主要的思路大体为,约定按照一类对象的某几个属性,针对特定的某一个属性,对不同的值对应不同的权重,求当前对象计权属性下值对应的权重和,然后降序输出对象。如:对于推荐商品自营商品和非自营商品权重可能不同,价格区间高的和价格区间低的商品权重可能不同,品牌不同,权重可能也不一样。本文主要阐述推荐权重打散的大体逻辑及实现。

    比如有如下7个商品

    具体计分规则

      店铺维度(共计三种AA,BB,CC)对应的权重分别为2,1,3.5

        AA:2

        BB:1

        CC:3.5 

    ===============

      品牌维度(11,22,33)对应的权值分别为1,0,-2

        11:1

        22:0

        33:-2

    根据以上计分规则计算后商品得分如下:

    根据权重得分降序排序后商品序列如下:

     该种打散算法相对来说实现思路比较简单。

    新建商品实体Goods 新建父类商品权重实体BaseGoods(权重属性统一维护在该实体中)

    父类BaseGoods

        //店铺标识
        public String shopCode;
        //品牌标识
        public String brandCode;
        //排序权重
        public Double weight = 0d;

    子类Goods

        public Goods(String shopCode, String brandCode) {
            this.shopCode = shopCode;
            this.brandCode = brandCode;
        }
        
        //商品编码
        private String goodsCode;
        //商品名称
        private String goodsName;
        //品牌名称
        private String brandName;
        //四级商品组编码
        private String groupCode;

    初始化商品

        public static List<Goods> initGoodsList() {
            
            List<Goods> goodsList = new ArrayList<Goods>();
            Goods goods1 = new Goods("BB", "11"); //2
            Goods goods2 = new Goods("AA", "33"); //0
            Goods goods3 = new Goods("AA", "11"); //3
            Goods goods4 = new Goods("CC", "33"); //1.5
            Goods goods6 = new Goods("BB", "33"); //-1
            Goods goods7 = new Goods("BB", "22"); //1
            Goods goods8 = new Goods("CC", "11"); //4.5
            
            goodsList.add(goods1);
            goodsList.add(goods2);
            goodsList.add(goods3);
            goodsList.add(goods4);
            goodsList.add(goods6);
            goodsList.add(goods7);
            goodsList.add(goods8);
            
            return goodsList;
        }

    权重配置信息获取

        public static Map<String,Map<String,Double>> getPropertyWeight(){
            
            Map<String,Map<String,Double>> map = new HashMap<String,Map<String,Double>>();
            //店铺类型(店铺提权)
            Map<String,Double> shopCodeMap = new HashMap<String, Double>();
            shopCodeMap.put("AA", 2d);
            shopCodeMap.put("BB", 1d);
            shopCodeMap.put("CC", 3.5d);
            
            //品牌类型(品牌提权)
            Map<String,Double> brandCodeMap = new HashMap<String, Double>();
            brandCodeMap.put("11", 1d);
            brandCodeMap.put("22", 0d);
            brandCodeMap.put("33", -2d);
            
            //返回总配置信息
            map.put("shopCode", shopCodeMap);
            map.put("brandCode", brandCodeMap);
            
            return map;
        }

    计权方法

        public void countWeight(List<? extends BaseGoods> goodsList) throws IllegalArgumentException, IllegalAccessException {
            if(null == goodsList  || goodsList.size() == 0) //CollectionUtil可替代
                return;
            //获取权重配置信息
            Map<String,Map<String,Double>> weightMap = getPropertyWeight();
            Field[] fields = goodsList.get(0).getClass().getFields();//获取对象属性
            for(int i=0; i<goodsList.size(); i++) {
                if(goodsList.get(i) instanceof BaseGoods) {
                    //计算单个商品的权重 目前仅按照shopCode和priceLevel排序 统一在父类BaseGoods维护权重属性
                    BaseGoods goods = (BaseGoods) goodsList.get(i);
                    Double totalWeight = 0d;
                    for(Field f : fields) {
                        f.setAccessible(true);//允许访问私有变量
                        if(weightMap.containsKey(f.getName())) {
                            Double weight = weightMap.get(f.getName()).get(f.get(goods));
                            totalWeight += weight;
                        }
                    }
                    ((BaseGoods) goodsList.get(i)).setWeight(totalWeight);
                }
            }
        }

    调用输出最终结果信息

        public static void main(String[] args) {
            List<Goods> goodsList = initGoodsList();
            WeightShuttle weightShuttle = new WeightShuttle();
            try {
                weightShuttle.countWeight(goodsList);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            //排序
            goodsList.sort(Comparator.comparing(Goods::getWeight).reversed());
            //打印
            goodsList.forEach(o->System.out.println(o));
        }

    控制台打印结果如下

     该种方法人工干预意愿比较明显,但是依旧存在干预不均匀,从而导致商品扎堆的情况。

  • 相关阅读:
    spark编译报错信息简介
    [LintCode]各位相加
    [算法]头条面试—奇数位升序偶数位降序链表排序
    [算法]循环打印矩阵,蛇形矩阵专题
    [LeetCode]146.LRU缓存机制
    [算法]死磕递归和动态规划专题算法
    Storm学习笔记——高级篇
    fail-fast和fail-safe
    阿里巴巴面试之利用两个int值实现读写锁
    [爬虫]Python爬虫进阶
  • 原文地址:https://www.cnblogs.com/id-tangrenhui/p/14982793.html
Copyright © 2011-2022 走看看