回归 - 基于RDD的API
等距回归
等单回归
属于回归算法的一类。形式上,等单回归是一个问题,其中给定一个有限的实数集合
$Y = {y_1, y_2, ..., y_n}$
代表观察到的响应,以及
$X = {x_1, x_2, ..., x_n}$
为待拟合的未知响应值,寻找一个最小化的函数。
\begin{equation}
f(x) = \sum_{i=1}^n w_i (y_i - x_i)^2
\end{equation}
关于完整订单,满足
$x_1\le x_2\le ...\le x_n$
其中
$w_i$
为正权重。
得到的函数称为单调回归,并且是唯一的。
它可以被视为在顺序限制下的最小二乘问题。
本质上,单调回归是一个
单调函数
最佳拟合原始数据点。
spark.mllib
支持一个
相邻违规者算法
该算法使用一种方法来
并行化等距回归
。
训练输入是一个由三个双精度值元组组成的 RDD,依次代表
标签、特征和权重。如果存在多个具有相同特征的元组,这些元组将被聚合为一个元组,如下所示:
- 聚合标签是所有标签的加权平均值。
- 聚合特征是唯一的特征值。
- 聚合权重是所有权重的总和。
此外,IsotonicRegression 算法有一个名为 $isotonic$ 的可选参数,默认为 true。此参数指定了等距回归是等距的(单调增加)还是反等距的(单调减少)。
训练返回一个 IsotonicRegressionModel,可以用于预测已知和未知特征的标签。等距回归的结果被视为分段线性函数。因此,预测的规则是:
- 如果预测输入恰好匹配一个训练特征,那么将返回相关的预测。
- 如果预测输入低于或高于所有训练特征,那么将分别返回最低或最高特征的预测。
- 如果预测输入落在两个训练特征之间,则将预测视为分段线性函数,并从两个最接近特征的预测中计算插值值。
示例
数据是从一个文件中读取的,其中每一行具有格式标签,特征,即4710.28,500.00。数据被分割为训练集和测试集。模型是使用训练集创建的,并且从预测标签和测试集中的实际标签计算均方误差。
请参阅
IsotonicRegression
Python 文档
和
IsotonicRegressionModel
Python 文档
以获取有关 API 的更多详细信息。
import math
from pyspark.mllib.regression import IsotonicRegression, IsotonicRegressionModel
from pyspark.mllib.util import MLUtils
# 加载和解析数据
def parsePoint(labeledData):
return (labeledData.label, labeledData.features[0], 1.0)
data = MLUtils.loadLibSVMFile(sc, "data/mllib/sample_isotonic_regression_libsvm_data.txt")
# 从输入数据创建标签、特征、权重元组,权重设置为默认值 1.0。
parsedData = data.map(parsePoint)
# 将数据拆分为训练集(60%)和测试集(40%)。
training, test = parsedData.randomSplit([0.6, 0.4], 11)
# 从训练数据创建等温回归模型。
# 等温参数默认值为 true,这里只为演示而显示
model = IsotonicRegression.train(training)
# 创建预测标签和真实标签的元组。
predictionAndLabel = test.map(lambda p: (model.predict(p[1]), p[0]))
# 计算预测标签和真实标签之间的均方误差。
meanSquaredError = predictionAndLabel.map(lambda pl: math.pow((pl[0] - pl[1]), 2)).mean()
print("均方误差 = " + str(meanSquaredError))
# 保存和加载模型
model.save(sc, "target/tmp/myIsotonicRegressionModel")
sameModel = IsotonicRegressionModel.load(sc, "target/tmp/myIsotonicRegressionModel")
数据是从一个文件读取的,每行有一个格式标签,特征 即 4710.28,500.00。数据被分为训练集和测试集。 模型是使用训练集创建的,并从预测标签和测试集中真实标签之间计算均方误差。
请参阅
IsotonicRegression
Scala 文档
和
IsotonicRegressionModel
Scala 文档
以获取有关API的详细信息。
import org.apache.spark.mllib.regression.{IsotonicRegression, IsotonicRegressionModel}
import org.apache.spark.mllib.util.MLUtils
val data = MLUtils.loadLibSVMFile(sc,
"data/mllib/sample_isotonic_regression_libsvm_data.txt").cache()
// 从输入数据创建标签、特征和权重元组,权重设置为默认值 1.0。
val parsedData = data.map { labeledPoint =>
(labeledPoint.label, labeledPoint.features(0), 1.0)
}
// 将数据分割为训练集(60%)和测试集(40%)。
val splits = parsedData.randomSplit(Array(0.6, 0.4), seed = 11L)
val training = splits(0)
val test = splits(1)
// 从训练数据创建等温回归模型。
// 等温参数默认值为 true,因此仅作为演示展示
val model = new IsotonicRegression().setIsotonic(true).run(training)
// 创建预测标签和真实标签的元组。
val predictionAndLabel = test.map { point =>
val predictedLabel = model.predict(point._2)
(predictedLabel, point._1)
}
// 计算预测标签和真实标签之间的均方误差。
val meanSquaredError = predictionAndLabel.map { case (p, l) => math.pow((p - l), 2) }.mean()
println(s"均方误差 = $meanSquaredError")
// 保存和加载模型
model.save(sc, "target/tmp/myIsotonicRegressionModel")
val sameModel = IsotonicRegressionModel.load(sc, "target/tmp/myIsotonicRegressionModel")
数据来自一个文件,其中每行具有格式标签,特征,即 4710.28,500.00。数据被分为训练集和测试集。模型使用训练集创建,并从预测标签和测试集中真实标签计算均方误差。
请参考
IsotonicRegression
Java 文档
和
IsotonicRegressionModel
Java 文档
以获取有关API的详细信息。
import scala.Tuple2;
import scala.Tuple3;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.mllib.regression.IsotonicRegression;
import org.apache.spark.mllib.regression.IsotonicRegressionModel;
import org.apache.spark.mllib.regression.LabeledPoint;
import org.apache.spark.mllib.util.MLUtils;
JavaRDD<LabeledPoint> data = MLUtils.loadLibSVMFile(
jsc.sc(), "data/mllib/sample_isotonic_regression_libsvm_data.txt").toJavaRDD();
// 从输入数据创建标签、特征和权重元组,权重默认为1.0。
JavaRDD<Tuple3<Double, Double, Double>> parsedData = data.map(point ->
new Tuple3<>(point.label(), point.features().apply(0), 1.0));
// 将数据分割为训练集(60%)和测试集(40%)。
JavaRDD<Tuple3<Double, Double, Double>>[] splits =
parsedData.randomSplit(new double[]{0.6, 0.4}, 11L);
JavaRDD<Tuple3<Double, Double, Double>> training = splits[0];
JavaRDD<Tuple3<Double, Double, Double>> test = splits[1];
// 从训练数据创建等温回归模型。
// 等温参数默认为真,因此仅用于演示
IsotonicRegressionModel model = new IsotonicRegression().setIsotonic(true).run(training);
// 创建预测标签和真实标签的元组。
JavaPairRDD<Double, Double> predictionAndLabel = test.mapToPair(point ->
new Tuple2<>(model.predict(point._2()), point._1()));
// 计算预测标签和真实标签之间的均方误差。
double meanSquaredError = predictionAndLabel.mapToDouble(pl -> {
double diff = pl._1() - pl._2();
return diff * diff;
}).mean();
System.out.println("均方误差 = " + meanSquaredError);
// 保存和加载模型
model.save(jsc.sc(), "target/tmp/myIsotonicRegressionModel");
IsotonicRegressionModel sameModel =
IsotonicRegressionModel.load(jsc.sc(), "target/tmp/myIsotonicRegressionModel");