• 使用Spark MLlib中推荐算法ALS对电影评分数据MovieLens推荐


    数据集下载地址:http://files.grouplens.org/datasets/movielens/

    #!usr/bin/env python
    # -*- coding:utf-8 _*-
    
    """
    @author: Ivan
    @version: v1.0
    @time: 2018-12-14 12:36
    """
    # 使用Spark MLlib中推荐算法ALS对电影评分数据MovieLens推荐
    from pyspark.sql import SparkSession
    from pyspark.mllib.recommendation import ALS, Rating, MatrixFactorizationModel
    from pyspark.mllib.regression import LabeledPoint, LinearRegressionWithSGD
    from pyspark.mllib.evaluation import RegressionMetrics
    from pyspark.mllib.linalg import DenseVector
    
    
    def alsModelEvaluate(model, testing_rdd):
        # 对测试数据集预测评分,针对测试数据集进行预测
        predict_rdd = model.predictAll(testing_rdd.map(lambda r: (r[0], r[1])))
        print(predict_rdd.take(5))
        predict_actual_rdd = predict_rdd.map(lambda r: ((r[0], r[1]), r[2])) 
            .join(testing_ratings.map(lambda r: ((r[0], r[1]), r[2])))
    
        print(predict_actual_rdd.take(5))
        # 创建评估指标实例对象
        metrics = RegressionMetrics(predict_actual_rdd.map(lambda pr: pr[1]))
    
        print("MSE = %s" % metrics.meanSquaredError)
        print("RMSE = %s" % metrics.rootMeanSquaredError)
    
        # 返回均方根误差
        return metrics.rootMeanSquaredError
    
    
    def train_model_evaluate(training_rdd, testing_rdd, rank, iterations, lambda_):
        # 定义函数,训练模型与模型评估
        # 使用超参数的值,训练数据和ALS算法训练模型
        model = ALS.train(training_rdd, rank, iterations, lambda_)
    
        # 模型的评估
        rmse_value = alsModelEvaluate(model, testing_rdd)
    
        # 返回多元组
        return (model, rmse_value, rank, iterations, lambda_)
    
    
    if __name__ == "__main__":
        # 构建SparkSession实例对象
        spark = SparkSession.builder 
            .appName("SparkSessionExample") 
            .master("local") 
            .getOrCreate()
    
        # 获取SparkContext实例对象
        sc = spark.sparkContext
    
        # 读取数据
        raw_ratings_rdd = sc.textFile("/wsh/project/Python/spark/data/u.data")
        # print(raw_ratings_rdd.count())
        # print(raw_ratings_rdd.first())
    
        # 获取评分数据前三个字段,构建Rating实例对象
        ratings_rdd = raw_ratings_rdd.map(lambda line: line.split('	')[0:3])
        # print(ratings_rdd.first())
    
        ratings_datas = ratings_rdd.map(lambda x: Rating(int(x[0]), int(x[1]), float(x[2])))
        # print(ratings_datas.first())
    
        # 查看评分数据中有多少电影
        # print(ratings_datas.map(lambda x: x[1]).distinct().count())
    
        # 查看评分数据中有多少用户
        # print(ratings_datas.map(lambda x: x[0]).distinct().count())
    
        # 将数据集分为训练数据集和测试数据集
        training_ratings, testing_ratings = ratings_datas.randomSplit([0.8, 0.2])
    
        '''
            # 使用ALS算法来训练模型
            # help(ALS)
            # 采用显示评分函数训练模型
            alsModel = ALS.train(training_ratings, 10, iterations=10, lambda_=0.01)
        
            # 用户特征因子矩阵
            user_feature_matrix = alsModel.userFeatures()
            print(type(user_feature_matrix))
            print(user_feature_matrix.take(10))
        
            # 物品因子矩阵
            item_feature_matrix = alsModel.productFeatures()
            print(type(item_feature_matrix))
            print(item_feature_matrix.take(10))
        
            # 预测某个用户对某个电影的评分
            
            # 假设用户196,对电影242的评分,实际评分为3分
            
            predictRating = alsModel.predict(196, 242)
            print(predictRating)
        
            # 为用户推荐(10部电影)
            rmdMovies = alsModel.recommendProducts(196, 10)
            print(rmdMovies)
        
            # 为电影推荐(10个用户)
            rmdUsers = alsModel.recommendUsers(242, 10)
            print(rmdUsers)
        '''
    
        # 怎么评价模型的好坏,ALS模型评估指标(类似回归算法模型预测值,连续值),使用回归模型中
        # RMSE(均方根误差)评估模型
        # 找到最佳模型
        '''
            如何找到最佳模型??
                -a. 模型的评估
                    计算RMSE
                -b. 模型的优化,两个方向
                    1、数据
                    2、超参数的调整,选择合适的超参数的值,得到最优模型
                交叉验证
                    训练数据集、验证数据集、测试数据集
                K-Folds交叉验证
        '''
    
        # ALS算法的超参数的调整
        # 定义一个函数,用于对模型进行评估
        # 使用三层for循环,设置不同参数的值,分别使用ALS算法训练模型,评估获取RMSE的值
        metrix_list = [train_model_evaluate(training_ratings, testing_ratings, param_rank, param_iterations, param_lambda)
                       for param_rank in [10, 20]
                       for param_iterations in [10, 20]
                       for param_lambda in [0.001, 0.01]
                       ]
        print(type(metrix_list))
        sorted(metrix_list, key=lambda k: k[1], reverse=False)
        model, rmse_value, rank, iterations, lambda_ = metrix_list[0]
        print("The best parameters, rank=%s, iterations=%s, lambda_=%s" % rank % iterations % lambda_)
    
        # 保存模型
        model.save(sc, "/wsh/project/Python/spark/data/als_model")
    
        # 加载模型
        load_model = MatrixFactorizationModel.load(sc, "/wsh/project/Python/spark/data/als_model")
  • 相关阅读:
    算法题
    AIO和NIO的理解
    Redis面试考点
    对MVVM的理解
    Vuex状态管理模式
    vue 的computed 和 watch 两者的区别
    vue之组件通信
    vue生命周期钩子函数
    angularjs 运行时报错ERROR in node_modules/rxjs/internal/types.d.ts(81,44): error TS1005: ';' expected. node_modules/rxjs/internal/types.d.ts(81,74): error TS1005: ';' expected. node_modules/rxjs/internal/t
    浅入不深出--vuex的简单使用
  • 原文地址:https://www.cnblogs.com/ltolstar/p/10119435.html
Copyright © 2020-2023  润新知