sklearn决策树:获取每个节点和叶的记录(**有效**)



我正在一些Panda数据帧X上训练决策树分类器。

clf = DecisionTreeClassifier()
clf = clf.fit(X, y)

现在,我遍历树clf.tree_,并希望获得属于该内部节点或叶的记录(最好是作为数据帧(。我现在所做的事情如下。

fn = [ X.columns[i] if i != TREE_UNDEFINED else "undefined!"  for i in clf.tree_.feature ]
def recurse(node, tmp):
tree = clf.tree_
if self.test_node(tmp):
return

if tree.feature[node] != TREE_UNDEFINED:
mask = tmp[fn[node]] <= tree.threshold[node]
recurse(tree.children_left[node], tmp[mask])
recurse(tree.children_right[node], tmp[~mask])

recurse(0, X)

这显然是有效的,但当对10K树执行此操作时,我使用探查器发现,代码中95%以上的时间都花在了拆分数据帧上。数据的运行拟合可能是2%,我对每个节点的数据帧所做的就是剩下的

是否有更高效的方法来拆分数据?

我假设DT内部必须拆分数据(我可以得到每个节点的记录数(。我可以以某种方式将df附加到节点上吗?

**更新**

建议使用CCD_ 3。在该矩阵中,每列j表示一个节点,而行i中的1表示它通过该节点。

我试了几个";方法";使用这个矩阵得到每个节点的df。所有这些都比我目前使用的天真方法慢。

Walk tree: default: 2.4888 s +- 0.01 s per loop (mean +- std. dev. of 10 runs, 50 loops each)
Walk tree: no recursion: 2.5427 s +- 0.07 s per loop (mean +- std. dev. of 10 runs, 50 loops each)
Walk tree: decision path Numpy : 16.5346 s +- 0.08 s per loop (mean +- std. dev. of 10 runs, 50 loops each)
Walk tree: decision path Scipy: 8.8154 s +- 0.56 s per loop (mean +- std. dev. of 10 runs, 50 loops each)
Walk tree: decision path Pandas: 28.3901 s +- 0.69 s per loop (mean +- std. dev. of 10 runs, 50 loops each)

对于使用该数组的方法中速度最快的Scipy,我还试图了解获取索引还是部分df是最耗时的。

Walk tree: decision path Scipy: 5.3404 s +- 0.20 s per loop (mean +- std. dev. of 10 runs, 30 loops each)
Walk tree: decision path Scipy (take=False): 4.5698 s +- 0.27 s per loop (mean +- std. dev. of 10 runs, 30 loops each)

我还尝试将上面的基本递归更改为使用df.query(..),但速度也较慢。

我相信

pd.DataFrame(clf.decision_path(X).toarray())

可能是你想要的。如果观察i经过树的节点j,则结果中的条目[i, j]将为1。这里还有一个关于决策树结构的很好的例子,可能会有所帮助。

最新更新