机器学习的过程 :
机器学习(Machine Learning): 一种计算过程:
模型训练 (Model Training) : 调整模型参数的过程
模型测试 (Model Testing) :
机器学习开发步骤 :
房屋数据中的不同文件 :
机器学习分类 :
房价预测的预测标的(Label)是房价,而房价是连续的数值型字段,所以用回归模型(Regression Model)来拟合数据
要想准确预测房价,就要先确定那些属性对房价的影响最大
特征选择时 , 先查看 Schema
import org.apache.spark.sql.DataFrameval rootPath: String = _
val filePath: String = s"${rootPath}/train.csv"// 从CSV文件创建DataFrame
val trainDF: DataFrame = spark.read.format("csv")
.option("header", true).load(filePath)trainDF.show
trainDF.printSchema
选择对房价影响大的特征,要计算每个特征与房价之间的相关性
从 CSV 创建 DataFrame,所有字段的类型默认都是 String
import org.apache.spark.sql.types.IntegerType// 提取用于训练的特征字段与预测标的(房价SalePrice)
val selectedFields: DataFrame = trainDF.select("LotArea", "GrLivArea", "TotalBsmtSF", "GarageArea", "SalePrice");// 将所有字段都转换为整 型Int
val typedFields = selectedFields.withColumn("LotAreaInt",col("LotArea").cast(IntegerType)).drop("LotArea").withColumn("GrLivAreaInt",col("GrLivArea").cast(IntegerType)).drop("GrLivArea").withColumn("TotalBsmtSFInt",col("TotalBsmtSF").cast(IntegerType)).drop("TotalBsmtSF").withColumn("GarageAreaInt",col("GarageArea").cast(IntegerType)).drop("GarageArea").withColumn("SalePriceInt",col("SalePrice").cast(IntegerType)).drop("SalePrice")typedFields.printSchema
/** 结果打印
root
|-- LotAreaInt: integer (nullable = true)
|-- GrLivAreaInt: integer (nullable = true)
|-- TotalBsmtSFInt: integer (nullable = true)
|-- GarageAreaInt: integer (nullable = true)
|-- SalePriceInt: integer (nullable = true)
*/
把要训练的多个特征字段,捏合成一个特征向量(Feature Vectors)
import org.apache.spark.ml.feature.VectorAssembler// 待捏合的特征字段集合
val features: Array[String] = Array("LotAreaInt", "GrLivAreaInt", "TotalBsmtSFInt", "GarageAreaInt", "SalePriceInt")// 准备“捏合器”,指定输入特征字段集合,与捏合后的特征向量字段名
val assembler = new VectorAssembler().setInputCols(features).setOutputCol("featuresAdded")// 调用捏合器的transform函数,完成特征向量的捏合
val featuresAdded: DataFrame = assembler.transform(typedFields).drop("LotAreaInt").drop("GrLivAreaInt").drop("TotalBsmtSFInt").drop("GarageAreaInt")featuresAdded.printSchema
/** 结果打印
root
|-- SalePriceInt: integer (nullable = true)
|-- features: vector (nullable = true) // 注意,features的字段类型是Vector
*/
把训练样本按比例分成两份 : 一份用于模型训练,一份用于初步验证模型效果
val Array(trainSet, testSet) = featuresAdded.randomSplit(Array(0.7, 0.3))
用训练样本来构建线性回归模型
import org.apache.spark.ml.regression.LinearRegression// 构建线性回归模型,指定特征向量、预测标的与迭代次数
val lr = new LinearRegression().setLabelCol("SalePriceInt").setFeaturesCol("features").setMaxIter(10)// 使用训练集trainSet训练线性回归模型
val lrModel = lr.fit(trainSet)
迭代次数 :
标准的制定 :
烘焙/模型训练的对比 :
完成模型的训练过程
import org.apache.spark.ml.regression.LinearRegression// 构建线性回归模型,指定特征向量、预测标的与迭代次数
val lr = new LinearRegression().setLabelCol("SalePriceInt").setFeaturesCol("features").setMaxIter(10)// 使用训练集trainSet训练线性回归模型
val lrModel = lr fit(trainSet)
在线性回归模型的评估中,有很多的指标,用来量化模型的预测误差
val trainingSummary = lrModel.summaryprintln(s"RMSE: ${trainingSummary.rootMeanSquaredError}")
/** 结果打印
RMSE: 45798.86
*/
房价的值域在(34,900,755,000)之间,而预测是 45,798.86 。这说明该模型是欠拟合的状态