回帰 - 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
は、隣接違反者プールアルゴリズムをサポートしており、等尺性回帰の並列化のアプローチを使用しています。トレーニング入力は、ラベル、特徴量、重みをこの順序で表す3つの倍精度浮動小数点値のタプルからなるRDDです。同じ特徴量を持つタプルが複数ある場合、これらのタプルは次のように単一のタプルに集約されます。
- 集約されたラベルは、すべてのラベルの加重平均です。
- 集約された特徴量は、一意の特徴量値です。
- 集約された重みは、すべての重みの合計です。
さらに、IsotonicRegressionアルゴリズムには、デフォルトでtrueに設定されている$isotonic$というオプションのパラメータが1つあります。この引数は、等尺性回帰が等尺性(単調増加)か反等尺性(単調減少)かを指定します。
トレーニングは、既知の特徴量と未知の特徴量の両方のラベルを予測するために使用できるIsotonicRegressionModelを返します。等尺性回帰の結果は、区分線形関数として扱われます。したがって、予測のルールは次のとおりです。
- 予測入力とトレーニング特徴量が完全に一致する場合、関連付けられた予測が返されます。
- 予測入力がすべてのトレーニング特徴量よりも低い場合、または高い場合は、それぞれ最も低い特徴量または最も高い特徴量の予測が返されます。
- 予測入力が2つのトレーニング特徴量の間にある場合、予測は区分線形関数として扱われ、最も近い2つの特徴量の予測から補間値が計算されます。
例
データは、各行がラベル、特徴量(例:4710.28,500.00)の形式を持つファイルから読み込まれます。データはトレーニングセットとテストセットに分割されます。トレーニングセットを使用してモデルが作成され、テストセットの予測ラベルと実際のラベルから平均二乗誤差が計算されます。
APIの詳細については、IsotonicRegression
PythonドキュメントとIsotonicRegressionModel
Pythonドキュメントを参照してください。
import math
from pyspark.mllib.regression import IsotonicRegression, IsotonicRegressionModel
from pyspark.mllib.util import MLUtils
# Load and parse the data
def parsePoint(labeledData):
return (labeledData.label, labeledData.features[0], 1.0)
data = MLUtils.loadLibSVMFile(sc, "data/mllib/sample_isotonic_regression_libsvm_data.txt")
# Create label, feature, weight tuples from input data with weight set to default value 1.0.
parsedData = data.map(parsePoint)
# Split data into training (60%) and test (40%) sets.
training, test = parsedData.randomSplit([0.6, 0.4], 11)
# Create isotonic regression model from training data.
# Isotonic parameter defaults to true so it is only shown for demonstration
model = IsotonicRegression.train(training)
# Create tuples of predicted and real labels.
predictionAndLabel = test.map(lambda p: (model.predict(p[1]), p[0]))
# Calculate mean squared error between predicted and real labels.
meanSquaredError = predictionAndLabel.map(lambda pl: math.pow((pl[0] - pl[1]), 2)).mean()
print("Mean Squared Error = " + str(meanSquaredError))
# Save and load model
model.save(sc, "target/tmp/myIsotonicRegressionModel")
sameModel = IsotonicRegressionModel.load(sc, "target/tmp/myIsotonicRegressionModel")
データは、各行がラベル、特徴量(例:4710.28,500.00)の形式を持つファイルから読み込まれます。データはトレーニングセットとテストセットに分割されます。トレーニングセットを使用してモデルが作成され、テストセットの予測ラベルと実際のラベルから平均二乗誤差が計算されます。
APIの詳細については、IsotonicRegression
ScalaドキュメントとIsotonicRegressionModel
Scalaドキュメントを参照してください。
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()
// Create label, feature, weight tuples from input data with weight set to default value 1.0.
val parsedData = data.map { labeledPoint =>
(labeledPoint.label, labeledPoint.features(0), 1.0)
}
// Split data into training (60%) and test (40%) sets.
val splits = parsedData.randomSplit(Array(0.6, 0.4), seed = 11L)
val training = splits(0)
val test = splits(1)
// Create isotonic regression model from training data.
// Isotonic parameter defaults to true so it is only shown for demonstration
val model = new IsotonicRegression().setIsotonic(true).run(training)
// Create tuples of predicted and real labels.
val predictionAndLabel = test.map { point =>
val predictedLabel = model.predict(point._2)
(predictedLabel, point._1)
}
// Calculate mean squared error between predicted and real labels.
val meanSquaredError = predictionAndLabel.map { case (p, l) => math.pow((p - l), 2) }.mean()
println(s"Mean Squared Error = $meanSquaredError")
// Save and load model
model.save(sc, "target/tmp/myIsotonicRegressionModel")
val sameModel = IsotonicRegressionModel.load(sc, "target/tmp/myIsotonicRegressionModel")
データは、各行がラベル、特徴量(例:4710.28,500.00)の形式を持つファイルから読み込まれます。データはトレーニングセットとテストセットに分割されます。トレーニングセットを使用してモデルが作成され、テストセットの予測ラベルと実際のラベルから平均二乗誤差が計算されます。
APIの詳細については、IsotonicRegression
JavaドキュメントとIsotonicRegressionModel
Javaドキュメントを参照してください。
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();
// Create label, feature, weight tuples from input data with weight set to default value 1.0.
JavaRDD<Tuple3<Double, Double, Double>> parsedData = data.map(point ->
new Tuple3<>(point.label(), point.features().apply(0), 1.0));
// Split data into training (60%) and test (40%) sets.
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];
// Create isotonic regression model from training data.
// Isotonic parameter defaults to true so it is only shown for demonstration
IsotonicRegressionModel model = new IsotonicRegression().setIsotonic(true).run(training);
// Create tuples of predicted and real labels.
JavaPairRDD<Double, Double> predictionAndLabel = test.mapToPair(point ->
new Tuple2<>(model.predict(point._2()), point._1()));
// Calculate mean squared error between predicted and real labels.
double meanSquaredError = predictionAndLabel.mapToDouble(pl -> {
double diff = pl._1() - pl._2();
return diff * diff;
}).mean();
System.out.println("Mean Squared Error = " + meanSquaredError);
// Save and load model
model.save(jsc.sc(), "target/tmp/myIsotonicRegressionModel");
IsotonicRegressionModel sameModel =
IsotonicRegressionModel.load(jsc.sc(), "target/tmp/myIsotonicRegressionModel");