PySpark ML feature transform,调用拟合/变换方法两次或两次以上?

PySpark ML feature transform,调用拟合/变换方法两次或两次以上?,pyspark,apache-spark-mllib,apache-spark-ml,Pyspark,Apache Spark Mllib,Apache Spark Ml,我们可以使用Spark ML库中提供的各种预处理类 from pyspark.ml.feature import StringIndexer, VectorIndexer,VectorAssembler labelIndexer = StringIndexer(inputCol = label_name, outputCol="indexedLabel") string_feature_indexers = [ StringIndexer(inputCol=x, outputCol="i

我们可以使用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也被调用,对于变换也是如此。我的假设正确吗

但对于所有这些已转换的函数,我们也可以在将它们添加到管道之前调用
fit/transform
函数

下面给出了与上述代码类似的内容

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
是否会调用所有这些转换的fit方法,那么我们需要先调用它什么呢?
如果fit在两个位置都被调用,那么哪一个会得到首选


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

您将转换器与估计器混淆了,这是两个可能的管道阶段

转换器没有
fit
方法,它只有
transform
方法。类似地,估计器没有
transform
方法,而是有一个
fit
方法来产生变压器

在管道定义中,可以将转换器和估计器作为阶段。当您调用pipeline
fit
方法时,它仅对估计器调用
fit
方法以生成变压器,并且输出是一个PipelineModel,它是一个仅变压器的集合

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

  • dataset=transformerA.transform(数据集)
    //延迟调用
  • transformerB=estimatorB.fit(dataset)
    //它将执行以前的延迟调用
  • dataset=transformerB.transform(dataset)
    //延迟调用,从未执行
  • dataset=transformerC.transform(dataset)
    //延迟调用,从未执行
  • 转换后的
    数据集
    不会返回,因为它仅用于从估计器生成转换器。然后,此调用将生成具有以下转换器的管道模型:
    [transformerA,transformerB,transformerC]
    。可以把整个流水线模型看作一个单独的变压器。

    如果您的管道仅包含转换器,那么管道
    fit
    调用将只检查模式一致性,因为这些转换是惰性计算的。 例如,如果你有这样的东西:

    model = EstimatorA.fit(dataset)
    pipeline = Pipeline(stages=[model])
    pipelineModel = pipeline.fit(dataset)
    
    模型
    是一个转换器,因此当您执行
    pipeline.fit(数据集)
    时,您不会执行另一次拟合,事实上
    pipelineModel
    的创建应该非常快,因为您不会对
    数据集
    执行任何计算(只有估计器中的
    fit
    可以触发执行)


    我希望这会有所帮助。

    您将变压器与估计器混为一谈,这是两个可能的管道阶段

    转换器没有
    fit
    方法,它只有
    transform
    方法。类似地,估计器没有
    transform
    方法,而是有一个
    fit
    方法来产生变压器

    在管道定义中,可以将转换器和估计器作为阶段。当您调用pipeline
    fit
    方法时,它仅对估计器调用
    fit
    方法以生成变压器,并且输出是一个PipelineModel,它是一个仅变压器的集合

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

  • dataset=transformerA.transform(数据集)
    //延迟调用
  • transformerB=estimatorB.fit(dataset)
    //它将执行以前的延迟调用
  • dataset=transformerB.transform(dataset)
    //延迟调用,从未执行
  • dataset=transformerC.transform(dataset)
    //延迟调用,从未执行
  • 转换后的
    数据集
    不会返回,因为它仅用于从估计器生成转换器。然后,此调用将生成具有以下转换器的管道模型:
    [transformerA,transformerB,transformerC]
    。可以把整个流水线模型看作一个单独的变压器。

    如果您的管道仅包含转换器,那么管道
    fit
    调用将只检查模式一致性,因为这些转换是惰性计算的。 例如,如果你有这样的东西:

    model = EstimatorA.fit(dataset)
    pipeline = Pipeline(stages=[model])
    pipelineModel = pipeline.fit(dataset)
    
    模型
    是一个转换器,因此当您执行
    pipeline.fit(数据集)
    时,您不会执行另一次拟合,事实上
    pipelineModel
    的创建应该非常快,因为您不会对
    数据集
    执行任何计算(只有估计器中的
    fit
    可以触发执行)

    我希望这有帮助