我正在尝试访问PySpark中随机森林模型的各个树元素。特别是,我试图从各个树中获得所有预测;我出于特殊原因需要这个。
不幸的是,Spark ML API只暴露单个树而不是预测。
首先,我将一个简单的随机森林模型拟合到一个n = 200的数据集,其中70/30列车/测试分裂。
from pyspark.ml.linalg import Vectors
from pyspark.ml.feature import VectorAssembler
# Create model
featureCols = ["age", "shoeSize", "score"]
assembler = VectorAssembler(inputCols = featureCols,
outputCol = "features")
train_feat = assembler.transform(train)
test_feat = assembler.transform(test)
# Fit model
model = rf.fit(train_feat)
然后,我时间:
随机森林的结果:
# How fast is the overall random forest prediction?
%timeit model.transform(test_feat).select('rowNum','probability')
%timeit model.transform(test_feat).select('rowNum','probability').collect()
24.9 ms ± 2 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 2.51 s ± 36.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
单个树的结果:
# How fast is accessing a single tree?
%timeit model.trees[0].transform(test_feat).select('rowNum','probability')
%timeit model.trees[0].transform(test_feat).select('rowNum','probability').collect()
627 ms ± 12.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 3.12 s ± 280 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
关键问题:为什么从单个树中获取结果要慢得多?
我实际上需要来自所有树的所有预测(即ndata x nTree集),因此循环遍历各个树将非常慢。有500棵树,我正在寻找~0.6s x 500棵树=最少约5分钟来获得所有树木的预测。
有没有快速获取所有单个树预测的方法?我是否需要进入Scala才能做到这一点?
替代方法:是否有矢量化方式来执行此操作?
即使单个树的概率稍慢,我是否可以通过某种方式使用map / reduce函数来有效地对其进行矢量化,或者在没有开销的情况下将各个计算变为不可用?
我试图通过创建一个向量
来做到这一点treeNum = range(0,nTrees)
其中nTrees = 500,然后使用我的训练数据计算此笛卡尔连接。
我尝试应用UDF并索引treeNum所需的模型编号,但我无法解决如何在PySpark中执行此操作。