使用ALS算法的一个电影推荐模型(java操作Spark-ML)

使用ALS算法的一个电影推荐模型(java操作Spark-ML)

ALS算法介绍

https://blog.csdn.net/qq_42448606/article/details/109214713
原理是矩阵分解

数据集

选择的数据集是经典的movielens
http://files.grouplens.org/datasets/movielens/
并将其中的一部分数据分离出来用于下面模型训练和预测:资源已上传:需要下载请到如下链接:
代码中需要的数据

代码如下

package com.cjy.bigdata.spark.ml.ALS;

import com.cjy.bigdata.spark.ml.ALS.entity.MovieScore;
import org.apache.spark.api.java.function.MapFunction;
import org.apache.spark.ml.evaluation.RegressionEvaluator;
import org.apache.spark.ml.recommendation.ALS;
import org.apache.spark.ml.recommendation.ALSModel;
import org.apache.spark.sql.*;

import java.util.ArrayList;
import java.util.List;

/**
 * @author cjy
 * @description: ALS基于交替最小二乘法的协同过滤算法
 * 数据集:http://files.grouplens.org/datasets/movielens/
 * @date: 2022$ 07/06$
 */
public class ALSMovieRecommend {
    public static void main(String[] args) {
        SparkSession sparkSession = SparkSession.builder().appName("BatchAnalysis").master("local[*]")
                .config("spark.sql.shuffle.partitions", "4")//本次测试时将分区数设置小一点,实际开发中可以根据集群规模调整大小,默认200
                .getOrCreate();
        Dataset<String> dataset = sparkSession.read().textFile("datas/u.data");

        //得到需要分析的dataset
        Dataset<MovieScore> movieScoreDataset = dataset.map((MapFunction<String, MovieScore>) line -> {
            String[] strings = line.split("\t");
            return new MovieScore(Integer.valueOf(strings[0]), Integer.valueOf(strings[1]), Double.valueOf(strings[2]));
        }, Encoders.bean(MovieScore.class));
        //new StructType(new StructField[]{new StructField("name", DataTypes.StringType,true),})

        //按照8:2的比例划分数据集
        Dataset<MovieScore>[] datasets = movieScoreDataset.randomSplit(new double[]{0.8, 0.2},50);
        Dataset<MovieScore> trainSet = datasets[0];
        Dataset<MovieScore> testSet = datasets[1];

        //构建ALS算法推荐模型并训练
        ALS als = new ALS()
                .setUserCol("userId")//设置用户id是哪一列
                .setItemCol("movieId") //设置产品id是哪一列
                .setRatingCol("score") //设置评分列
                .setColdStartStrategy("drop")  //设置冷启动,预测时处理未知或新用户/item的策略。这在交叉验证或生产场景中可能很有用,对于处理模型在训练数据中没有看到的用户/项目id。支持的值:“nan”、“drop”。
                .setRank(15) //可以理解为Cm*n = Am*k X Bk*n 里面的k的值,矩阵的秩
                .setMaxIter(10) //最大迭代次数
                .setAlpha(1.0);//迭代步长
                //.setRegParam(0.02);//正则化参数
        //训练模型
        ALSModel alsModel = als.fit(trainSet);

        //模型评估,rmse均方误差(求差,开方,求平均,开根);
        Dataset<Row> predictions = alsModel.transform(testSet);
        predictions.show();
        //创建误差评估器
        RegressionEvaluator regressionEvaluator = new RegressionEvaluator()
                .setMetricName("rmse")//设置要计算的误差名称,均方根误差 (sum((y-y')^2)/n)^0.5
                .setLabelCol("score")//设置真实值是哪一列
                .setPredictionCol("prediction");//设置预测值是哪一列
        //对数据中的真实值和预测值进行误差计算
        double rmse = regressionEvaluator.evaluate(predictions);
        System.out.println("rmse为:" + rmse);
        //模型评估,mae平均绝对误差(求差的绝对值,后平均,个人认为这个评估值更能表示所写模型);
        regressionEvaluator.setMetricName("mae")//设置要计算的误差名称,mae
                .setLabelCol("score")//设置真实值是哪一列
                .setPredictionCol("prediction");//设置预测值是哪一列
        //对数据中的真实值和预测值进行误差计算
        double mae = regressionEvaluator.evaluate(predictions);
        System.out.println("mae为:" + mae);
        //可以得到分数的区间是0-5分,那么误差率可以求得为
        System.out.println("平均绝对误差率" + (mae/5.0));

        //使用测试集测试模型,给测试集中的每个用户推荐与其5个相关性最高的电影
        Dataset<Row> rowDataset = alsModel.recommendForUserSubset(testSet, 5);
        rowDataset.show(false);
        //使用测试集测试模型,给测试集中的每个电影推荐与其相关性最高的5个用户
        alsModel.recommendForItemSubset(testSet, 5).orderBy(functions.desc("movieId")).show(false);
        //预测测试集中的每个用户给一个电影的评分
        alsModel.transform(testSet).show();

        //给指定用户推荐
        List<MovieScore> data = new ArrayList<>();
        data.add(new MovieScore(0,163,0.0));
        Dataset<MovieScore> appoint = sparkSession.createDataset(data, Encoders.bean(MovieScore.class));
        alsModel.recommendForUserSubset(appoint,5).show(false);
    }
}

目前写的感觉只是简单的推荐,用到了其中的一个数据集,并没有对其他数据的关联关系进行操作。个人理解,ALS算法已经是很成熟了,因此如果训练模型的数据相关性越高,那么其推荐的准确率越高,因此构建相关性的数据处理是针对一种业务更换的解决方式,后续有深入学习再进行补充。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
项目完整可用,配合压缩包内数据库可直接运行使用。 eclipse+mysql5.7+jdk1.8 功能:推荐引擎利用特殊的信息过滤(IF,Information Filtering)技术,将不同的内容(例如电影、音乐、书籍、新闻、图片、网页等)推荐给可能感兴趣的用户。通常情况下,推荐引擎的实现是通过将用户的个人喜好与特定的参考特征进行比较,并试图预测用户对一些未评分项目的喜好程度。参考特征的选取可能是从项目本身的信息中提取的,或是基于用户所在的社会或社团环境。 根据如何抽取参考特征,我们可以将推荐引擎分为以下四大类: • 基于内容的推荐引擎:它将计算得到并推荐给用户一些与该用户已选择过的项目相似的内容。例如,当你在网上购书时,你总是购买与历史相关的书籍,那么基于内容的推荐引擎就会给你推荐一些热门的历史方面的书籍。 • 基于协同过滤的推荐引擎:它将推荐给用户一些与该用户品味相似的其他用户喜欢的内容。例如,当你在网上买衣服时,基于协同过滤的推荐引擎会根据你的历史购买记录或是浏览记录,分析出你的穿衣品位,并找到与你品味相似的一些用户,将他们浏览和购买的衣服推荐给你。 • 基于关联规则的推荐引擎:它将推荐给用户一些采用关联规则发现算法计算出的内容。关联规则的发现算法有很多,如 Apriori、AprioriTid、DHP、FP-tree 等。 • 混合推荐引擎:结合以上各种,得到一个更加全面的推荐效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值