是否可以在Spark ML中为随机森林制作通用培训管道?

时间:2017-08-16 18:51:59

标签: scala apache-spark machine-learning apache-spark-mllib

我刚开始使用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之外的所有列的东西,并将它们一起编译成分类器可以使用的特征向量。

1 个答案:

答案 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)