PySpark ML特征变换,调用拟合/变换方法两次或覆盖它?

问题描述 投票:0回答:1

我们可以使用Spark-ML库中提供的各种预处理类。

from pyspark.ml.feature import StringIndexer, VectorIndexer,VectorAssembler

labelIndexer = StringIndexer(inputCol = label_name, outputCol="indexedLabel")
string_feature_indexers = [
   StringIndexer(inputCol=x, outputCol="int_{0}".format(x))
   for x in char_col_toUse_names
]
assembler = VectorAssembler(inputCols=[col for col in all_columns], outputCol="features")    
featureIndexer = VectorIndexer(inputCol="features", outputCol="indexedFeatures", maxCategories=100)
rf = RandomForestClassifier(labelCol="indexedLabel", featuresCol="indexedFeatures", numTrees=1)
pipeline = Pipeline(stages=[labelIndexer] + string_feature_indexers + [assembler, featureIndexer, rf])

model = pipeline.fit(trainingData)
predictions = model.transform(testData)

现在,当我们在管道上调用fit时,上面使用的所有变换的拟合也被调用,并且类似于变换。我是正确的假设吗?

但是对于所有这些变换,我们也可以在将它们添加到管道之前调用fit/ transform函数,as give here

上面的代码类似,下面给出,

labelIndexer = StringIndexer(inputCol = label_name, outputCol="indexedLabel").fit(data)
string_feature_indexers = [
   StringIndexer(inputCol=x, outputCol="int_{0}".format(x)).fit(data)
   for x in char_col_toUse_names
]
assembler = VectorAssembler(inputCols=[col for col in all_columns], outputCol="features")
assembler.transform(data)    
featureIndexer = VectorIndexer(inputCol="features", outputCol="indexedFeatures", maxCategories=100).fit(data)
rf = RandomForestClassifier(labelCol="indexedLabel", featuresCol="indexedFeatures", numTrees=1)
pipeline = Pipeline(stages=[labelIndexer] + string_feature_indexers + [assembler, featureIndexer, rf])

model = pipeline.fit(trainingData)
predictions = model.transform(testData)

现在我怀疑,pipeline.fit无论如何都会调用所有这些变换的拟合方法,那么我们需要在手边调用它? 如果在两个地方调用拟合,哪个获得偏好?

注意:上面的代码只是为讨论/怀疑创建的,并不代表正确的执行代码。

pyspark apache-spark-mllib apache-spark-ml
1个回答
2
投票

您正在混淆变形金刚与估算器,这是两个可能的管道阶段。

变形金刚没有fit方法,它只有transform方法。类似地,Estimator没有transform方法,但它有一个生成Transformer的fit方法。

在管道定义中,您可以将变形金刚和估算器作为阶段。当您调用管道fit方法时,它仅在Estimators上调用fit方法来生成Transformers,输出是PipelineModel,它只是Transformers的集合。

例如,如果您的管道具有以下阶段:[transformerA, estimatorB, transformerC],管道fit(dataset)调用将执行以下操作:

  1. dataset = transformerA.transform(dataset) //懒惰的电话
  2. transformerB = estimatorB.fit(dataset) //它将执行先前的懒惰调用
  3. dataset = transformerB.transform(dataset) //懒惰的电话,从未执行过
  4. dataset = transformerC.transform(dataset) //懒惰的电话,从未执行过

转换的dataset不会被返回,因为它仅用于从估算器生成变形金刚。然后,此调用将生成具有以下变换器的PipelineModel:[transformerA, transformerB, transformerC]。您可以将整个PipelineModel视为单个Transformer。

如果您的管道仅包含变换器,则管道fit调用将仅检查模式一致性,因为这些变换是惰性求值的。例如,如果你有这样的东西:

model = EstimatorA.fit(dataset)
pipeline = Pipeline(stages=[model])
pipelineModel = pipeline.fit(dataset)

model是一个变形金刚,所以当你做pipeline.fit(dataset)你将不会执行另一个拟合,事实上pipelineModel的创建应该非常快,因为你不会对dataset执行任何计算(只有来自Estimators的fit才能触发执行)。

我希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.