我使用Python训练了一个随机森林算法,并希望将它应用于PySpark的大数据集。
我首先加载了训练有素的sklearn RF模型(使用joblib),将包含这些功能的数据加载到Spark数据帧中,然后添加一个包含预测的列,并使用用户定义的函数:
def predictClass(features):
return rf.predict(features)
udfFunction = udf(predictClass, StringType())
new_dataframe = dataframe.withColumn('prediction',
udfFunction('features'))
它需要花费很多时间才能运行,是否有更有效的方法来做同样的事情? (不使用Spark ML)
答案 0 :(得分:2)
在最近的项目中,我不得不做同样的事情。对于pyspark每次必须读取sklearn模型的每一行都应用udf的坏事,这就是为什么要花很多时间才能完成的原因。我发现的最佳解决方案是在rdd上使用.mapPartitions或foreachPartition方法,此处的确是一个很好的解释
https://github.com/mahmoudparsian/pyspark-tutorial/blob/master/tutorial/map-partitions/README.md
它之所以能够快速运行,是因为它确保您没有改组,并且对于每个分区pyspark都必须读取模型并仅预测一次。因此,流程为:
答案 1 :(得分:0)
sklearn RF模型在酸洗时可能会非常大。在任务调度期间频繁的模型挖掘/解开可能会导致问题。您可以考虑使用广播变量。
广播变量允许程序员在每台机器上保留一个只读变量,而不是随副本一起发送它的副本。例如,它们可用于以有效的方式为每个节点提供大输入数据集的副本。 Spark还尝试使用高效的广播算法来分发广播变量,以降低通信成本。
答案 2 :(得分:0)
现在,您还可以使用spark 2.3中引入的pandas_udf
,以实现较高的处理速度和分布式计算。它基于pyarrow
用于内存中计算的 Apache Arrow 的python实现。