从SKlearn决策树中检索决策边界线(x,y坐标格式)

从SKlearn决策树中检索决策边界线(x,y坐标格式),第1张

从SKlearn决策树中检索决策边界线(x,y坐标格式)

决策树没有很好的边界。它们具有多个边界,这些边界将要素空间按层次划分为矩形区域。

在我的Node
Harvest的
实现中,我编写了解析scikit决策树并提取决策区域的函数。对于这个答案,我修改了部分代码以返回与树决策区域相对应的矩形列表。使用任何绘图库绘制这些矩形应该很容易。这是使用matplotlib的示例:

n = 100np.random.seed(42)x = np.concatenate([np.random.randn(n, 2) + 1, np.random.randn(n, 2) - 1])y = ['b'] * n + ['r'] * nplt.scatter(x[:, 0], x[:, 1], c=y)dtc = DecisionTreeClassifier().fit(x, y)rectangles = decision_areas(dtc, [-3, 3, -3, 3])plot_areas(rectangles)plt.xlim(-3, 3)plt.ylim(-3, 3)

不同颜色的区域相遇的地方都有决策边界。我想只要花些力气就可以提取这些边界线,但我会将其留给任何有兴趣的人。

rectangles
是一个numpy数组。每一行对应一个矩形,列为
[left, right, top, bottom, class]


更新:适用于虹膜数据

虹膜数据集包含三个类别,而不是2个类别,如示例中所示。因此,我们必须在

plot_areas
函数中添加另一种颜色:
color = ['b', 'r','g'][int(rect[4])]
。此外,数据集是4维的(它包含四个要素),但是我们只能在2D中绘制两个要素。我们需要选择要绘制的特征并告诉
decision_area
功能。该函数带有两个参数,
x
并且
y
-这分别是x和y轴上的功能。默认值
x=0,y=1
适用于具有多个功能的任何数据集。但是,在虹膜数据集中,第一个维度不是很有趣,因此我们将使用其他设置。

该函数

decision_areas
也不知道数据集的范围。决策树通常具有向无穷大延伸的开放决策范围(例如,当 萼片长度 小于 xyz时,
它就是B类)。在这种情况下,我们需要人为地缩小绘图范围。我
-3..3
为示例数据集选择了数据,但对于虹膜数据集选择了其他范围是适当的(永远不会出现负值,某些功能会超过3)。

在这里,我们在0..7和0..5范围内的最后两个特征上绘制决策区域:

from sklearn.datasets import load_irisdata = load_iris()x = data.datay = data.targetdtc = DecisionTreeClassifier().fit(x, y)rectangles = decision_areas(dtc, [0, 7, 0, 5], x=2, y=3)plt.scatter(x[:, 2], x[:, 3], c=y)plot_areas(rectangles)

请注意,左上方的红色和绿色区域之间有奇怪的重叠。发生这种情况是因为树在四个维度上做出决策,但我们只能显示两个维度。真的没有一个干净的方法可以解决此问题。高维分类器在低维空间中通常没有很好的决策边界。

因此,如果您对分类器更感兴趣,那么您将获得。您可以沿尺寸的各种组合生成不同的视图,但是表示的有用性受到限制。

但是,如果您对数据比对分类器更感兴趣,则可以在拟合之前限制维数。在这种情况下,分类器仅在二维空间中做出决策,我们可以绘制出不错的决策区域:

from sklearn.datasets import load_irisdata = load_iris()x = data.data[:, [2, 3]]y = data.targetdtc = DecisionTreeClassifier().fit(x, y)rectangles = decision_areas(dtc, [0, 7, 0, 3], x=0, y=1)plt.scatter(x[:, 0], x[:, 1], c=y)plot_areas(rectangles)


最后,这是实现:

import numpy as npfrom collections import dequefrom sklearn.tree import DecisionTreeClassifierfrom sklearn.tree import _tree as ctreeimport matplotlib.pyplot as pltfrom matplotlib.patches import Rectangleclass AABB:    """Axis-aligned bounding box"""    def __init__(self, n_features):        self.limits = np.array([[-np.inf, np.inf]] * n_features)    def split(self, f, v):        left = AABB(self.limits.shape[0])        right = AABB(self.limits.shape[0])        left.limits = self.limits.copy()        right.limits = self.limits.copy()        left.limits[f, 1] = v        right.limits[f, 0] = v        return left, rightdef tree_bounds(tree, n_features=None):    """Compute final decision rule for each node in tree"""    if n_features is None:        n_features = np.max(tree.feature) + 1    aabbs = [AABB(n_features) for _ in range(tree.node_count)]    queue = deque([0])    while queue:        i = queue.pop()        l = tree.children_left[i]        r = tree.children_right[i]        if l != ctree.TREE_LEAF: aabbs[l], aabbs[r] = aabbs[i].split(tree.feature[i], tree.threshold[i]) queue.extend([l, r])    return aabbsdef decision_areas(tree_classifier, maxrange, x=0, y=1, n_features=None):    """ Extract decision areas.    tree_classifier: Instance of a sklearn.tree.DecisionTreeClassifier    maxrange: values to insert for [left, right, top, bottom] if the interval is open (+/-inf)     x: index of the feature that goes on the x axis    y: index of the feature that goes on the y axis    n_features: override autodetection of number of features    """    tree = tree_classifier.tree_    aabbs = tree_bounds(tree, n_features)    rectangles = []    for i in range(len(aabbs)):        if tree.children_left[i] != ctree.TREE_LEAF: continue        l = aabbs[i].limits        r = [l[x, 0], l[x, 1], l[y, 0], l[y, 1], np.argmax(tree.value[i])]        rectangles.append(r)    rectangles = np.array(rectangles)    rectangles[:, [0, 2]] = np.maximum(rectangles[:, [0, 2]], maxrange[0::2])    rectangles[:, [1, 3]] = np.minimum(rectangles[:, [1, 3]], maxrange[1::2])    return rectanglesdef plot_areas(rectangles):    for rect in rectangles:        color = ['b', 'r'][int(rect[4])]        print(rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1])        rp = Rectangle([rect[0], rect[2]],  rect[1] - rect[0],  rect[3] - rect[2], color=color, alpha=0.3)        plt.gca().add_artist(rp)


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5661908.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存