商品推荐之认识Mahout

/ 后端 / 没有评论 / 420浏览

推荐

类似于淘宝,京东,抖音等等的各种不同地方的推荐推送,他们都有各自的一套推荐系统,并且有自己的一波算法工程师,大数据工程师来支撑着每个用户个性化的推荐;

现实

那么一般业务量较小,用户群体商品较少,又或者说小公司怎么做呢? 1.要么直接查出一系列最新上架或者最受欢迎的商品,直接推送给用户; 2.可能稍微用心点的会将用户购买过的商品排除,然后随机找点商品推荐; 3.在以上基础上,对比根据该用户类似的其他用户的购买产品中,寻找一些商品进行推荐; 4.根据该用户已购买的商品,寻找类似的商品,进行一些个性化推荐; 5.使用ES全文索引系统,根据商品信息等相关字段,排除已购买商品,查询出匹配度最高的进行推荐;

推荐算法

其实根据上述一些情景,就能归纳出了两种推荐方式: 1.以用户纬度来进行对比推荐 2.以商品纬度进行对比推荐

当然那些高大上的算法,前人已经设计出来了,我们直接拿来用就行了;其中Mahout这个工具包就集成了各种推荐算法,它可以直接根据数据文件导入计算方式,MySQL JBDC接入方式,以及其他比如spark等大数据接入方式,不过原理都是大同小异;

简单单机使用(JDBC)

1.配置数据源 此处使用的是ReloadFromJDBCDataModel包裹了MySQLJDBCDataModel,可以将性能大幅提升,由原来数据库计算改为内存计算;

数据需要配置用户id,商品id,喜好值,发生时间;

    @Bean(value = "mySQLDataModel")
    public DataModel getMySQLJDBCDataModel() throws TasteException {
        return new ReloadFromJDBCDataModel(new MySQLJDBCDataModel(dataSource,
                "rating","user_id","movie_id","rating", "timestamp"));
    }

2.进行算法推荐 由于数据库中的用户商品偏好数据会随机变化,所以需要使用dataModel.refresh(null)方法来刷新内存中的缓存数据,否则最后推荐的商品不会变化;

    @Resource(name = "mySQLDataModel")
    private DataModel dataModel;
  
    public List<Long> userBasedRecommend(long userID, int size) throws TasteException {
        //由于在内存中,如果喜好参数有变化则需要刷新
        dataModel.refresh(null);

        UserSimilarity similarity = new EuclideanDistanceSimilarity(dataModel);
        int NEIGHBORHOOD_NUM = 10;
        NearestNUserNeighborhood neighbor = new NearestNUserNeighborhood(NEIGHBORHOOD_NUM, similarity, dataModel);
        Recommender recommender = new CachingRecommender(new GenericUserBasedRecommender(dataModel, neighbor, similarity));

        List<RecommendedItem> recommendations = recommender.recommend(userID, size);
        return recommendations.stream().map(m -> m.getItemID()).collect(Collectors.toList());
    }

    public List<Long> itemBasedRecommend(long userID, int size) throws TasteException {
        dataModel.refresh(null);

        ItemSimilarity itemSimilarity = new CityBlockSimilarity(dataModel);
        Recommender recommender = new CachingRecommender(new GenericItemBasedRecommender(dataModel, itemSimilarity));

        List<RecommendedItem> recommendations = recommender.recommend(userID, size);
        return recommendations.stream().map(m -> m.getItemID()).collect(Collectors.toList());
    }

3.一个简单的使用用例,使用的是springboot集成Mahout,例子查找于Github,对其进行了一些调整; 点我获取