Spark-MLlib的快速使用之十五( 保序回归)

(1) 描述

这种回归,是这一种单调函数的回归,回归模型中后一个x一定比前一个x大,也就是有序,具体的数学公式在上面两个网址中都有。

保序回归并不需要制定的目标函数。

保序回归的应用之一就是用来做统计推断,比如药量和毒性的关系,一般认为毒性随着药量是不减或者递增的关系,借此可以来估计最大药量。

问题描述:给定一个无序数字序列y,通过修改每个元素的值得到一个非递减序列 y‘ ,问如何使y和 y’ 误差(该处取平方差)最小?

保序回归法:从该序列y的首元素往后观察,一旦出现乱序现象停止该轮观察,从该乱序元素开始逐个吸收紧跟在后面的元素组成一个子序列sub_y,直到子序列sub_y所有元素的平均值小于或等于下一个待吸收的元素。

举例:

原始序列:<9, 10, 14>

结果序列:<9, 10, 14>

分析:从9往后观察,到最后的元素14都未发现乱序情况,不用处理。

原始序列:<9, 14, 10>

结果序列:<9, 12, 12>

分析:从9往后观察,观察到14时发生乱序(14>10),停止该轮观察转入吸收元素处理,吸收元素10后子序列为<14, 10>,取该序列所有元素的平均值得12,故用序列<12, 12>替代<14, 10>。吸收10后已经到了最后的元素,处理操作完成。

原始序列:<14, 9, 10,  15>

结果序列:<11, 11, 11, 15>

分析:从14往后观察,观察到9时发生乱序(14>9),停止该轮观察转入吸收元素处理,吸收元素9后子序列为<14, 9>。求该序列所有元素的平均值得12.5,由于12.5大于下个带吸收的元素10,所以再吸收10,得序列<14, 9, 10>。求该序列所有元素的平均值得11,由于11小于下个带吸收的元素15,所以停止吸收操作,用序列<11, 11, 11>替代<14, 9, 10>。

(2)测试数据

0.24579296,0.01

0.28505864,0.02

0.31208567,0.03

0.35900051,0.04

0.35747068,0.05

0.16675166,0.06

0.17491076,0.07

0.04181540,0.08

0.04793473,0.09

0.03926568,0.10

(3)测试程序

public class JavaIsotonicRegressionExample {

public static void main(String[] args) {

SparkConf sparkConf = new SparkConf().setAppName("JavaIsotonicRegressionExample").setMaster("local");

JavaSparkContext jsc = new JavaSparkContext(sparkConf);

// $example on$

JavaRDD<String> data = jsc.textFile("sample_isotonic_regression_data.txt");

// Create label, feature, weight tuples from input data with weight set to default value 1.0.

JavaRDD<Tuple3<Double, Double, Double>> parsedData = data.map(

new Function<String, Tuple3<Double, Double, Double>>() {

public Tuple3<Double, Double, Double> call(String line) {

String[] parts = line.split(",");

return new Tuple3<>(new Double(parts[0]), new Double(parts[1]), 1.0);

}

}

);

System.out.println( parsedData.take(10));

// 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

final IsotonicRegressionModel model = new IsotonicRegression().setIsotonic(true).run(training);

 

// Create tuples of predicted and real labels.

JavaPairRDD<Double, Double> predictionAndLabel = test.mapToPair(

new PairFunction<Tuple3<Double, Double, Double>, Double, Double>() {

@Override

public Tuple2<Double, Double> call(Tuple3<Double, Double, Double> point) {

Double predictedLabel = model.predict(point._2());

return new Tuple2<Double, Double>(predictedLabel, point._1());

}

}

);

System.out.println( predictionAndLabel.take(10));

// Calculate mean squared error between predicted and real labels.

Double meanSquaredError = new JavaDoubleRDD(predictionAndLabel.map(

new Function<Tuple2<Double, Double>, Object>() {

@Override

public Object call(Tuple2<Double, Double> pl) {

return Math.pow(pl._1() - pl._2(), 2);

}

}

).rdd()).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");

// $example off$

}

}

(4)测试结果

[(0.16868944399999988,0.31208567), (0.16868944399999988,0.35900051), (0.16868944399999988,0.03926568), (0.16868944399999988,0.12952575), (0.16868944399999988,0.0), (0.16868944399999988,0.01376849), (0.16868944399999988,0.13105558), (0.19545421571428565,0.13717491), (0.19545421571428565,0.19020908), (0.19545421571428565,0.19581846)]

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值