PySpark回归模型简明教程

一、PySpark机器学习模块

   pyspark.ml为机器学习模块,提供了分类,回归,聚类,推荐等算法模型。如下表所示。

类别模型功能
分类模型LogisticRegression逻辑回归模型,分类的基准模型
DecisionTreeClassifier决策树模型
GBTClassifier梯度提升决策树模型
RandomForestRegressor随机森林模型
NaiveBayes贝叶斯模型
回归模型DecisionTreeRegressor决策树回归模型
RandomForestRegressor随机森林回归模型
GBTRegressor梯度提升回归树模型
LinearRegression线性回归模型
GeneralizedLinearRegression广义线性回归模型
聚类模型LDA主题生成模型,用于获取文本文档的主题
KMeansK均值聚类模型
BisectingKMeans结合K均值算法和层次聚类算法,将数据迭代分解为K类
推荐模型ALS协同过滤算法(基于交替最小二乘法)
   在构建完回归模型后,需要对模型进行评估,以确定模型的优劣,评估预测的准确性。pyspark.ml.evaluation模块提供了模型评估方法,如下表所示。
类别评估方法功能
分类模型BinaryClassificationEvaluator评估二分类模型的方法
MulticlassClassificationEvaluator评估多分类模型的方法
MultilabelClassificationEvaluator评估多标签分类模型的方法
回归模型RegressionEvaluator评估回归模型的方法
聚类模型ClusteringEvaluator评估聚类模型的方法
推荐模型RankingEvaluator评估排名模型的方法

   pyspark.ml.tuning模块提供了模型优化方法,通过对模型的参数进行 调整,可以获得较好的预测 结果。先设定参数的可选范围,然后遍历参数,从中选择最优的参数组合。模型优化方法如下:

优化方法功能
ParamGridBuilder参数网格,设置参数值的范围,遍历搜索网格
CrossValidatorK折交叉验证,将数据集分成K份,选择其中1份作为测试数据集,剩下的K-1份数据分别作用来训练模型,总共进行K次训练,取K次估计值的平均值。
TrainValidationSplit根据参数划分训练数据集和测试数据集,模型只训练一次。

二、回归模型应用案例1:广告投入后,销售额预测

   回归算法是一类用于预测数值型数据的算法。回归算法的目标是找到一个函数,该函数能够将输入变量(特征)映射到输出变量(目标),以便预测新的、未见过的数据的目标值。
   本案例根据商品的广告投入,预测商品销售额,数据集为advertising.csv,“微信”、“微博”、“其他”三个字段为特征,表示在微信、微博和其他平台的广告投入,“销售额”为目标值,表示投入广告后,商品的销售额。部分数据如下图所示。
在这里插入图片描述
   待预测数据集为:advertising_pred.csv,没有目标值,使用训练好的回归模型,预测目标值(销售额)。该数据集的数据如下所示。
在这里插入图片描述
   数据集advertising.csv和advertising_pred.csv已上传至HDFS系统的/data目录下。

1.数据读取

   PySpark从HDFS的目录/data/下,读取数据集advertising.csv。

from pyspark import SparkConf
from pyspark.ml.feature import StringIndexer, VectorAssembler, OneHotEncoder, MinMaxScaler
from pyspark.sql import SparkSession, Row
from pyspark.sql.functions import *
from pyspark.ml.classification import *
from pyspark.ml.evaluation import *
from pyspark.ml import Pipeline, tuning
from pyspark.ml.linalg import Vectors
from pyspark.ml.regression import *

conf = SparkConf().setAppName("回归模型3").setMaster('spark://192.168.126.10:7077')
sc = SparkContext.getOrCreate(conf)
spark = SparkSession(sc)
# -----------------1.数据获取-------------------
filename = "advertising.csv"
advertising = spark.read.csv('hdfs://192.168.126.10:9000/data/' + filename, header=True,
                             inferSchema=True)  # 训练集包含标题行,inferSchema=True自动推断数据类型
advertising.describe().show()  # 查看数据集的基本数据信息
advertising.printSchema()  # 输出数据集的结构
advertising.show(5)
print(f"训练数据集总的记录数:{advertising.count()}, 总列数:{len(advertising.columns)}")

   程序运行结果如下所示。
在这里插入图片描述

2. 特征工程

   特征工程(Feature Engineering)是指在机器学习中,通过对原始数据进行选择、提取、变换等操作,生成更能够表达数据本质特征的特征集合。特征工程主要包括以下几个方面:
   (1)数据预处理:指在特征工程中对原始数据进行清洗、标准化、归一化等操作,以便更好地被算法使用。数据预处理的目的是消除数据的噪声和异常值,提高数据的质量和可用性。
   (2)特征选择:指从原始数据中选择一部分最具有代表性的特征,以减少特征的维度和冗余性,提高模型的泛化能力和效率。
   (3)特征提取:指从原始数据中提取一些可以代表数据特征的新特征,以帮助机器学习算法更好地发现数据之间的关系。特征提取的方法包括主成分分析(PCA)、独立成分分析(ICA)、局部线性嵌入(LLE)等。
   (4)特征变换:指对原始数据进行变换,以产生新的特征,以便更好地被算法使用。常见的特征变换包括多项式变换、对数变换、指数变换等。
特征工程不一定要做完上面所提的全部内容,需要根据具体问题的特点和数据的属性进行合理的选择和调整。
   本案例比较简单,字段很少,并且全部为数值型数据,因此不需要做太复杂的特征工程。
   本案例选择所有的特征字段,然后将选择的字段转换为一个向量,最后将数据集划分为训练集和测试集。代码如下:

# ----------------------2. 特征工程---------------------
#  特征选择:选择数值型的字段,用于后期的目标值预测
features = ['微信', '微博', '其他']
# 将选择的特征列转换为一个向量
data_assembler = VectorAssembler(inputCols=features,
                                 outputCol='向量化后特征')  # 构建特征向量转换器。将给定的特征列,转换为一个向量列,列名自定义为向量化后特征
advertising_assembler = data_assembler.transform(advertising)  # 使用特征向量转换器,向量化数据集的特征。
advertising_assembler.show(5)
advertising_train, advertising_test = advertising_assembler.randomSplit([0.7, 0.3], seed=3)  # 划分训练集和测试集,种子为3(用于重现实验结果)

   向量化后的特征如下图所示。
在这里插入图片描述

3.构建模型:线性回归模型

   待预测目标值为销售额,是一个连续值,因此选择回归模型。

# -------------3.模型构建:线性回归模型----------------
lr = LinearRegression(labelCol='销售额', featuresCol='向量化后特征', regParam=0.1)  # 构建线性回归模型。模型的构建需要两列数据:标签列和特征列
lrModel = lr.fit(advertising_train)  # 模型训练:拟合训练数据,得到 线性回归模型

# 模型评估,方法一:训练模型后的基本摘要summary
trainingSummary = lrModel.summary  # 内部评估,使用训练数据评估模型基本性能
print("均方误差,接近0模型性能最优:", trainingSummary.meanSquaredError)
print("判定系数R^2,接近1模型性能最优:", trainingSummary.r2)

# 模型评估,方法二:用外部测试集评估模型,模型评估方法RegressionEvaluator
lr_predictions = lrModel.transform(advertising_test)  # 用训练好的模型,预测测试集数据
lr_predictions.show()  # 查看预测结果,发现有预测结果,列名为prediction
re_evaluator = RegressionEvaluator(labelCol='销售额',
                                   predictionCol='prediction',
                                   metricName='rmse')  # 构建评估器,真实值(标签)为y列,预测值为prediction,评价指标为均方误差rmse
print("均方误差,接近0模型性能最优:", re_evaluator.evaluate(lr_predictions))

re_evaluator = RegressionEvaluator(labelCol='销售额',
                                   predictionCol='prediction',
                                   metricName='r2')
print("判定系数R^2,接近1模型性能最优:", re_evaluator.evaluate(lr_predictions))

上面的代码中,
   (1)构建模型:首先构建线性回归模型 lr = LinearRegression(labelCol=‘销售额’, featuresCol=‘向量化后特征’, regParam=0.1)。模型的构建需要两列数据:标签列和特征列。标签列(目标列)为“销售额”,特征列为已经向量化的特征列:“向量化后特征”。设置正则化参数regParam为0.1
   (2)训练模型:# 模型训练:使用训练数据集advertising_train拟合线性回归模型 。lrModel = lr.fit(advertising_train)
   (3)模型评估
   方法一: 获取模型的摘要信息,用于内部评估 ,trainingSummary = lrModel.summary。可以打印均方误差,该值越接近0表示模型性能越好。或打印判定系数R^2,该值越接近1表示模型性能越好 。
在这里插入图片描述

   方法二:使用外部测试集评估模型性能。

  • 先使用训练好的模型对测试集advertising_test进行预测,得到预测结果。
    在这里插入图片描述

  • 构建评估器,用于计算均方误差(RMSE)。re_evaluator = RegressionEvaluator(labelCol=‘销售额’, predictionCol=‘prediction’, metricName=‘rmse’) 。评估指标有:

评估指标指标具体名字含义
rmseRoot Mean Square Error,均方根误差表示预测值与真实值之间的平均偏差大小。RMSE越小,表示模型的预测精度越高。
mseMean Square Error,均方误差与RMSE类似,但MSE是平方差的平均值,不取平方根。MSE越小,同样表示模型的预测精度越高。
r2R-squared,判定系数表示模型对数据的拟合程度。R²的值越接近1,表示模型的拟合效果越好,预测能力越强。
maeMean Absolute Error,平均绝对误差表示预测值与真实值之间的平均绝对偏差。MAE越小,表示模型的预测精度越高。
varVariance,方差表示数据的离散程度。在模型评估中,方差通常用于衡量模型的稳定性或泛化能力。方差越小,表示模型对数据的拟合越稳定,泛化能力可能越强(但也要注意避免过拟合)。

由参数metricName决定评估指标。

  • 由评估器对测试集的预测结果进行评估:re_evaluator.evaluate(lr_predictions),得到评估结果。
    在这里插入图片描述

4.模型应用:使用训练好的模型预测数据

   模型使用步骤:
(1)导入待预测数据。
(2)使用前面构建的特征向量转换器,将待预测 数据的多个特征列转换为向量。
(3)使用前面训练好的线性回归模型,预测数据(销售量)。
   代码如下:

#  ----------4.模型应用:使用训练好的模型预测数据--------------
filename = "advertising_pred.csv"
newData = spark.read.csv('hdfs://192.168.126.10:9000/data/' + filename, header=True,
                         inferSchema=True)  # 训练集包含标题行,inferSchema=True自动推断数据类型
newData2 = data_assembler.transform(newData)  # 利用前面构建的特征向量转换器,将多个特征列转换为向量
newDataPred = lrModel.transform(newData2)  # 使用训练好的线性回归模型,预测数据。
newDataPred.show()  # 可以看到待预测数据集多了一列预测数据prediction,

   预测的销售额(prediction)为10.12,结果如下:
在这里插入图片描述

三、其他回归模型的构建与应用:决策树回归模型(DecisionTreeRegressor)

1. 构建决策树回归模型

   构建决策树回归模型,指定标签列(销售额)和特征列(向量化后特征)
dtr = DecisionTreeRegressor(labelCol=‘销售额’, featuresCol=‘向量化后特征’)

2. 训练模型

   使用训练数据集advertising_train训练决策树回归模型,dtrModel = dtr.fit(advertising_train)。

3. 预测

   使用训练好的决策树回归模型对测试集advertising_test进行预测,得到预测结果

4.构建评估器

   (1)构建评估器,指定标签列(销售额)、预测列(prediction)和评价指标为均方根误差(rmse)。均方根误差越接近0,模型性能越好。
   (2) 再次构建评估器,但这次使用判定系数R^2作为评价指标, 判定系数越接近1,模型性能越好 。

5. 模型应用

   使用训练好的决策树回归模型对新的数据集newData2进行预测,得到预测结果 。需要注意的是,newData2数据在上一节已经做了向量化处理。

#  ---------决策树回归模型DecisionTreeRegressor----------------
print("\n\n---------------决策树模型------------------\n")
dtr = DecisionTreeRegressor(labelCol='销售额',
                            featuresCol='向量化后特征')  # 1.构建决策树回归模型
dtrModel = dtr.fit(advertising_train)  # 2.训练模型,得到决策树回归模型

dtr_predictions = dtrModel.transform(advertising_test)  # 3.预测 测试集的销售额,用于评估模型

dtr_evaluator = RegressionEvaluator(labelCol='销售额',
                                    predictionCol='prediction',
                                    metricName='rmse')  # 4.构建评估器,确定评价指标:均方误差rmse
print("决策树模型均方误差,接近0模型性能最优:", dtr_evaluator.evaluate(dtr_predictions))

dtr_evaluator = RegressionEvaluator(labelCol='销售额',
                                    predictionCol='prediction',
                                    metricName='r2')  # 4.构建评估器,确定评价指标:均方误差rmse
print("决策树模型判定系数R^2,接近1模型性能最优:", dtr_evaluator.evaluate(dtr_predictions))

# 决策树模型应用
newDataPred = dtrModel.transform(newData2)   # 5.使用决策树回归模型 预测销售额
newDataPred.show()

   程序运行结果如下:
在这里插入图片描述

四、回归模型应用案例2:小费预测

1.数据集介绍

   使用线性回归模型LinearRegression类预测小费。数据集tips共有244个样本,各字段的含义如下:
   total_bill:顾客的总账单金额(美元)。这个字段表示顾客在餐厅消费的总金额,是小费金额计算的一个重要参考。
   sex:顾客的性别。通常表示为“Male”(男性)或“Female”(女性)。这个字段用于分析性别是否对小费金额有影响。
   smoker:顾客是否吸烟。通常表示为“Yes”(是)或“No”(否)。这个字段用于分析吸烟习惯是否与小费金额有关。
   day:用餐的星期几。这个字段可能包含“Thur”(周四)、“Fri”(周五)、“Sat”(周六)、“Sun”(周日)等,用于分析星期几是否会影响小费金额。
   time:用餐的时间。通常表示为“Lunch”(午餐)或“Dinner”(晚餐)。这个字段用于分析用餐时间是否会影响小费金额。
   size:用餐的顾客人数。这个字段表示一桌顾客的数量,用于分析顾客人数是否与小费金额有关。
   tip:顾客给出的小费金额(美元)。这是数据集预测的主要目标,即根据其他字段的信息来预测顾客可能会给出的小费金额。
   其中,sex,smoker,day,time字段的值为字符型数据,需要转换为数值型数据,即:数值化。tips数据集的部分数据如下图所示:
在这里插入图片描述

2. 读取数据

from pyspark import SparkConf
from pyspark.ml.feature import StringIndexer, VectorAssembler, OneHotEncoder, MinMaxScaler
from pyspark.sql import SparkSession, Row
from pyspark.sql.functions import *
from pyspark.ml.classification import *
from pyspark.ml.evaluation import *
from pyspark.ml import Pipeline, tuning
from pyspark.ml.linalg import Vectors
from pyspark.ml.regression import *

conf = SparkConf().setAppName("预测小费").setMaster('spark://192.168.126.10:7077')
sc = SparkContext.getOrCreate(conf)
spark = SparkSession(sc)
# -----------------1.数据获取-------------------
filename = "tips.csv"
tips = spark.read.csv('hdfs://192.168.126.10:9000/data/' + filename, header=True,
                      inferSchema=True)  # 训练集包含标题行,inferSchema=True自动推断数据类型
tips.show(5)
tips.describe().show()  # 查看数据集的基本数据信息
tips.printSchema()  # 输出数据集的结构
print(f"训练数据集总的记录数:{tips.count()}, 总列数:{len(tips.columns)}")

3.特征工程

3.1 数值化字符串型数据

  • 创建标签索引转换器StringIndexer,用于将字符串类型的列转换为索引值。
  • 然后用数据集tips 拟合数据,得到数值化转换模型model ;
  • 最后使用转换模型model ,将数据集tips中的字符串类型列(sex,smoker,day,time)转为数值型数据,并添加到原数据集tips中。
#  将字符型数据列 数值化
labelIndex = StringIndexer(inputCols=['sex', 'smoker', 'day', 'time'],
                           outputCols=['indexed_sex', 'indexed_smoker', 'indexed_day', 'indexed_time'])  # 构建标签索引转换器
model = labelIndex.fit(tips)  # 拟合数据,得到 数值化转换模型
tips = model.transform(tips)  # 将tips中的字符型数据数值化,并把转化后的列添加到原数据集tips
print("字符型列的数据数值化后的数据集data:")
tips.show(5)

程序运行结果 如下:
在这里插入图片描述

3.2 选择、向量化特征

  • 选择数值型特征(total_bill,size)和已数值化的特征(indexed_sex,indexed_smoker,indexed_day,indexed_time)。
  • 创建向量转换器data_assembler ,用于将多个特征列合并成一个向量列。
  • 使用向量转换器data_assembler,将选定的特征列合并成向量,并添加到数据集中,形成新的一列:raw_features。
  • 最后将数据集划分为训练集tips_train和测试集tips_test 。
#  选择特征:选择数值型特征和已数值化的特征
features = ['total_bill', 'size', 'indexed_sex', 'indexed_smoker', 'indexed_day', 'indexed_time']
# 将选择的特征向量化为一列
data_assembler = VectorAssembler(inputCols=features, outputCol='raw_features')  # 实例化 向量转换器,用于将多个特征列合并成一个向量列
tips = data_assembler.transform(tips)  # 将选定的特征列合并成向量,并添加到数据集中,形成新的一列:raw_features
tips.show(5)
tips_train, tips_test = tips.randomSplit([0.7, 0.3], seed=3)

程序运行结果如下:
在这里插入图片描述

4.创建模型:线性回归模型LinearRegression

4.1 创建模型

  • 创建线性回归模型,指定目标列、特征列和正则化参数。
  • 使用 训练数据集 训练模型,得到训练好的模型lrModel 。
  • 使用训练好的模型lrModel 对测试集tips_test进行预测,结果自动生成预测值列’prediction’。
#  ---------------5.构建模型:线性回归模型LinearRegression-----------------------
lr = LinearRegression(labelCol='tip', featuresCol='raw_features', regParam=0.1)  # 创建线性回归模型,指定目标列、特征列和正则化参数
lrModel = lr.fit(tips_train)  # 使用 训练数据集 训练模型
lr_pred = lrModel.transform(tips_test)  # 使用训练好的模型对测试集进行预测,结果将包含预测值列'prediction'
lr_pred.show(5)

4.2 模型评估

  • 创建模型评估器,指定真实标签列名为’tip’,预测结果列名为’prediction’,使用RMSE作为评估指标。
  • 输出模型的RMSE值,值越小表示模型性能越好。
  • 再次创建评估器,确定评估指标为r^2。
# 模型评估
lr_evaluator = RegressionEvaluator(labelCol='tip',  # 指定真实标签列名为'tip'
                                   predictionCol='prediction',  # 指定预测结果列名为'prediction'
                                   metricName='rmse')    # 使用RMSE作为评估指标
print("线性回归模型的均方误差,接近0模型性能最优:", lr_evaluator.evaluate(lr_pred))  # 输出模型的RMSE值,值越小表示模型性能越好

lr_evaluator = RegressionEvaluator(labelCol='tip',  # 构建评估器,确定评估指标r^2
                                   predictionCol='prediction',
                                   metricName='r2')
print("线性回归模型的判定系数R^2,接近1模型性能最优:", lr_evaluator.evaluate(lr_pred))

4.3 模型应用

  • 获取待预测数据集tips_pred,重新命名为newData。数据集tips_pred没有目标列,如下图所示。
    在这里插入图片描述

  • 使用前面的数值化转换模型model,将newData中的字符型数据数值化。

  • 使用前面创建的向量转换器data_assembler,将特征转换为一列向量。

  • 使用训练好的 线性回归模型 lrModel,预测新数据集newData的小费。

#  ---------模型应用----------
filename = "tips_pred.csv"
newData = spark.read.csv('hdfs://192.168.126.10:9000/data/' + filename, header=True,
                         inferSchema=True)  # 获取待预测数据
newData = model.transform(newData)  # 使用前面的数值化转换模型model,将newData中的字符型数据数值化
newData = data_assembler.transform(newData)    # 向量转换器data_assembler,将特征转换为一列向量
newData_pred = lrModel.transform(newData)   # 使用训练好的 线性回归模型 lrModel,预测新数据集newData的小费
newData_pred.show()

预测结果(小费)如下:
在这里插入图片描述

5.其他回归模型的应用(随机森林树回归模型:RandomForestRegressor)

   使用前面导入并且已经处理好的待预测数据newData,编程步骤如下:

  • 创建随机森林回归模型实例。
  • 训练随机森林回归模型。
  • 使用训练好的模型进行预测 测试集,用于模型评估。
  • 构建评估器,确定评估指标,评估模型。
  • 使用训练好的 随机森林树回归模型 rfrModel,预测新数据集newData的小费
#  -----------------随机森林树回归模型:RandomForestRegressor--------------
rfr = RandomForestRegressor(labelCol='tip', featuresCol='raw_features')  # 创建随机森林回归模型实例
rfrModel = rfr.fit(tips_train)  # 训练随机森林回归模型
rfr_pred = rfrModel.transform(tips_test)  # 使用训练好的模型进行预测 测试集,用于模型评估

# 模型评估
rfr_evaluator = RegressionEvaluator(labelCol='tip',  # 构建评估器,确定评估指标rmse
                                    predictionCol='prediction',
                                    metricName='rmse')
print("随机森林树回归模型的均方误差,接近0模型性能最优:", rfr_evaluator.evaluate(rfr_pred))

rfr_evaluator = RegressionEvaluator(labelCol='tip',  # 构建评估器,确定评估指标r^2
                                    predictionCol='prediction',
                                    metricName='r2')
print("随机森林树回归模型的判定系数R^2,接近1模型性能最优:", rfr_evaluator.evaluate(rfr_pred))

# -----模型应用-----
newData_pred = rfrModel.transform(newData)  # 使用训练好的 随机森林树回归模型 rfrModel,预测新数据集newData的小费
newData_pred.show()

   运行结果如下:
在这里插入图片描述

参考资料:

1.pyspark学生成绩分析与预测(上):https://blog.csdn.net/weixin_52563520/article/details/137675514
2.https://blog.csdn.net/weixin_52563520/article/details/139126270?spm=1001.2014.3001.5502
3.https://blog.csdn.net/weixin_52563520/article/details/135358767?spm=1001.2014.3001.5502
4.spark学习回归理论和实战房价预测:https://blog.csdn.net/qq_35394891/article/details/83184779
5.基于pyspark的波士顿房价预测案例:https://blog.csdn.net/weixin_46474921/article/details/121780705
6.戴刚,张良均. PySpark大数据分析与应用. 人民邮电出版社,2024.
7.汪明. PySpark实战. 清华大学出版社,2022

  • 8
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

侧耳倾听童话

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值