我们可以使用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
无论如何会调用所有这些变换的拟合方法,那么我们需要在手前调用它?
如果在两个地方调用拟合,哪个获得偏好?
注意:上面的代码只是为讨论/怀疑创建的,并不代表正确的执行代码。
答案 0 :(得分:2)
您正在混淆变形金刚与估算器,这是两个可能的管道阶段。
Transformer没有fit
方法,只有transform
方法。同样,估算工具没有transform
方法,而是使用fit
方法生成变换器。
在管道定义中,您可以将变形金刚和估算器作为阶段。当您调用管道fit
方法时,它仅在Estimators上调用fit
方法来生成变换器,输出是PipelineModel,它只是变形金刚的集合。
例如,如果您的管道具有以下阶段:[transformerA, estimatorB, transformerC]
,则管道fit(dataset)
调用将执行以下操作:
dataset = transformerA.transform(dataset)
//懒人电话transformerB = estimatorB.fit(dataset)
//它将执行先前的延迟调用dataset = transformerB.transform(dataset)
//懒惰的电话,从未执行dataset = transformerC.transform(dataset)
//懒惰的电话,从未执行未返回已转换的dataset
,因为它仅用于从估算器生成变换器。然后,此调用将生成具有以下变换器的PipelineModel:[transformerA, transformerB, transformerC]
。您可以将整个PipelineModel视为单个Transformer。
如果您的Pipeline仅包含Transformers,则管道fit
调用将仅检查架构一致性,因为这些转换是惰性求值的。
例如,如果你有这样的东西:
model = EstimatorA.fit(dataset)
pipeline = Pipeline(stages=[model])
pipelineModel = pipeline.fit(dataset)
model
是一个变形金刚,所以当你pipeline.fit(dataset)
执行pipelineModel
时,你不会再进行另一次拟合,事实上dataset
的创建应该非常快,因为你不会执行对fit
的任何计算(估算器中只有tv4
可以触发执行)。
我希望这会有所帮助。