问题描述
使用Spark MLlib的pipeline创建模型。在idea(windows的)上测试时模型运行正常,打成jar包到linux系统上提交时最后一列数据丢失了。(图中absences在当时测试时被调整到了最后一列,原数据集最后一列为isPass)
下面是Pipeline的创建代码,用的scala语言
private def getPipeline = {
//标签索引
val indexedColumns = for (str <- dealColumns) yield str + "_indexed"
val indexer = new StringIndexer()
.setInputCols(dealColumns)
.setOutputCols(indexedColumns)
//独热编码
val oneHotColumns = for (str <- dealColumns) yield str + "_onehot"
val oneHotEncoder = new OneHotEncoder()
.setInputCols(indexedColumns)
.setOutputCols(oneHotColumns)
val features = oneHotColumns ++ restColumns; //合并特征列
//生成特征列
val vectorAssembler = new VectorAssembler()
.setInputCols(features)
.setOutputCol("features0")
//归一化
val minMaxScaler = new MinMaxScaler()
.setInputCol("features0")
.setOutputCol("features")
//svm
val svm = new LinearSVC()
.setLabelCol("isPass")
.setFeaturesCol("features")
.setPredictionCol("isPass_pred")
.setTol(1e-7)
//创建工作流
new Pipeline()
.setStages(Array(indexer, oneHotEncoder, vectorAssembler, minMaxScaler, svm))
}
linux上提交spark任务的命令
spark-submit --class xyz.hyhy.GradeForecastTest /home/hadoop/homework/6/GradeForecast-1.0.jar
总之在idea上测试完全没问题,到linux上pipeline里就要丢一列
解决方案
好在Spark MLlib的模型创建都是指定列的,增加额外的列不会有影响,因此可以在数据集增加一列额外的列来保护最后一列数据。训练集和测试集都要(要进入pipline的都要)。
当然这种方法只是权宜之计,虽然不影响结果,不过还是挺膈应的。
不知道这个问题是不是版本不兼容造成的bug,还是其他的。
如果也遇到这种情况且知道原因或有其他处理办法的朋友,求在评论区提点一下🙏