推荐系统打散算法--权重

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

 

比如有如下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));
    }

控制台打印结果如下

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

posted @ 2021-07-29 10:39  ID_小汤  阅读(1419)  评论(0编辑  收藏  举报