2016-03-10 47 views
2

我目前正在尝试学习Spark Sparkline(Spark 1.6.0)。我将数据集(train和test)导入为oas.sql.DataFrame对象。执行以下代码后,生成的模型是一个oas.ml.tuning.CrossValidatorModel。您可以使用model.transform(test)根据Spark中的测试数据进行预测。但是,我想比较模型用于预测的权重和来自R的权重。如何提取预测变量的权重和拦截(如果有的话)模型?斯卡拉码是:从火花管道物流模型中提取变量权重?

import sqlContext.implicits._ 
import org.apache.spark.mllib.linalg.{Vectors, Vector} 
import org.apache.spark.SparkContext 
import org.apache.spark.mllib.regression.LabeledPoint 
import org.apache.spark.ml.Pipeline 
import org.apache.spark.ml.classification.{LogisticRegression, LogisticRegressionModel} 
import org.apache.spark.ml.evaluation.BinaryClassificationEvaluator 
import org.apache.spark.ml.tuning.{ParamGridBuilder, CrossValidator} 

val conTrain = sc.textFile("AbsolutePath2Train.txt") 
val conTest = sc.textFile("AbsolutePath2Test.txt") 

// parse text and convert to sql.DataFrame 
val train = conTrain.map { line => 
val parts = line.split(",") 
LabeledPoint(parts(0).toDouble, Vectors.dense(parts(1).split(" +").map(_.toDouble))) 
}.toDF() 
val test =conTest.map{ line => 
val parts = line.split(",") 
LabeledPoint(parts(0).toDouble, Vectors.dense(parts(1).split(" +").map(_.toDouble))) 
}.toDF() 

// set parameter space and evaluation method 
val lr = new LogisticRegression().setMaxIter(400) 
val pipeline = new Pipeline().setStages(Array(lr)) 
val paramGrid = new ParamGridBuilder().addGrid(lr.regParam, Array(0.1, 0.01)).addGrid(lr.fitIntercept).addGrid(lr.elasticNetParam, Array(0.0, 0.5, 1.0)).build() 
val cv = new CrossValidator().setEstimator(pipeline).setEvaluator(new BinaryClassificationEvaluator).setEstimatorParamMaps(paramGrid).setNumFolds(2) 

// fit logistic model 
val model = cv.fit(train) 

// If you want to predict with test 
val pred = model.transform(test) 

我的火花环境不可访问。因此,这些代码被重新输入并重新检查。我希望他们是正确的。到目前为止,我试图在网上搜索,询问其他人。关于我的编码,欢迎提出建议和批评。谢谢。

回答

0

我一直在寻找完全一样的东西。你可能已经有了答案,但无论如何,这就是它。

import org.apache.spark.ml.classification.LogisticRegressionModel 
val lrmodel = model.bestModel.asInstanceOf[LogisticRegressionModel] 
print(model.weight, model.intercept) 
+1

在Spark1.6.0上尝试了这个,但产生了一个错误“oas.ml.PipelineModel无法转换为oas.ml.Classification.LogisticRegressionModel”。我添加了一个关于如何以类似的方式实现这一点的答案。谢谢〜 – Jazzy

+0

对不起,我在Spark 1.5.2上 –

0

我还不确定如何从上面的“模型”中提取权重。但是,改制过程中对the official tutorial,以下作品的火花1.6.0:

import org.apache.spark.ml.evaluation.BinaryClassificationEvaluator 
import org.apache.spark.ml.tuning.{ParamGridBuilder, TrainValidationSplit} 
val lr = new LogisticRegression().setMaxIter(400) 
val paramGrid = new ParamGridBuilder().addGrid(lr.regParam, Array(0.1, 0.01)).addGrid(lr.fitIntercept).addGrid(lr.elasticNetParam, Array(0.0, 0.5, 1.0)).build() 
val trainValidationSplit = new TrainValidationSplit().setEstimator(lr).setEvaluator(new BinaryClassificationEvaluator).setEstimatorParamMaps(paramGrid).setTrainRatio(0.8) 
val restructuredModel = trainValidationSplit.fit(train) 
val lrmodel = restructuredModel.bestModel.asInstanceOf[LogisticRegressionModel] 
lrmodel.weigths 
lrmodel.intercept 

我注意到了“lrmodel”之间在这里和“模式”上面产生的差异:

model.bestModel - >给oas.ml.Model [_] =管道_ ****

restructuredModel.bestModel - >给oas.ml.Model [_] = logreg _ ****

这就是为什么我们可以投resturcturedModel.bestModel为LogisticRegressionModel,但不是model.bestMo的模型德尔。当我了解差异的原因时,我会添加更多。

2
// set parameter space and evaluation method 
val lr = new LogisticRegression().setMaxIter(400) 
val pipeline = new Pipeline().setStages(Array(lr)) 
val paramGrid = new ParamGridBuilder().addGrid(lr.regParam, Array(0.1, 0.01)).addGrid(lr.fitIntercept).addGrid(lr.elasticNetParam, Array(0.0, 0.5, 1.0)).build() 
val cv = new CrossValidator().setEstimator(pipeline).setEvaluator(new BinaryClassificationEvaluator).setEstimatorParamMaps(paramGrid).setNumFolds(2) 
// you can print lr model coefficients as below 
val model = cv.bestModel.asInstanceOf[PipelineModel] 
val lrModel = model.stages(0).asInstanceOf[LogisticRegressionModel] 
println(s"LR Model coefficients:\n${lrModel.coefficients.toArray.mkString("\n")}") 

两个步骤:

  1. 获得来自交叉验证结果的最佳管道。
  2. 从最佳管道获取LR模型。这是你的代码示例中的第一个阶段。