我刚开始使用Spark和Spark ML,我发现它比Python和sklearn困难得多。
开发时间要长得多,所以我想知道是否可以制作适用于任何(足够小)数据集并训练随机森林分类器的通用管道。理想情况下,我会创建一个像
这样的函数def trainClassifier(df: DataFrame, labelColumn: String) {
...
}
Spark中的大量开发时间用于将列编码为数字列,然后从特征中形成向量,以便Spark ML的随机森林可以实际使用它。所以最终会写出像
这样的行val indexer = new StringIndexer()
.setInputCol("category")
.setOutputCol("categoryIndex")
.fit(df)
val indexed = indexer.transform(df)
val encoder = new OneHotEncoder()
.setInputCol("categoryIndex")
.setOutputCol("categoryVec")
val encoded = encoder.transform(indexed)
所以我的问题更多的是一个设计问题(如果合适的话,请指导我到另一个网站)关于如何编写适用于任何DataFrame
的分类的通用训练函数,但它也是一个关于Spark的问题,我在询问Spark中是否有这种东西是可行的(所以这是一个API问题,所以它更适合stackoverflow)?
编辑:我的意思是我没有指定列并为每个新数据帧手动转换列。我想要一个函数trainClassifier
,它将接收具有不同列和不同列类型的各种数据帧。迭代除labelColumn之外的所有列的东西,并将它们一起编译成分类器可以使用的特征向量。
答案 0 :(得分:3)
您可以创建自定义管道:
val start = "category"; // can be parameter of method or function
val indexer = new StringIndexer()
.setInputCol(start )
.setOutputCol(start + "Index")
.fit(df)
val encoder = new OneHotEncoder()
.setInputCol(encoder.outputCol)
.setOutputCol(start + "encoded")
这些步骤可以在函数中返回Array [Stage] - Array(索引器,编码器)。现在你可以用here写一些函数来连接所有数组并创建Pipeline:
val randomForest = ...
val pipeline = new Pipeline()
.setStages(allStepsArray(indexer , encoder , randomForest))
然后你可以在Pipeline上调用fit,甚至可以在link中构建CrossValidator:
val model = pipeline.fit(testData)