Lin*_* Ma 18 python machine-learning decision-tree python-2.7 scikit-learn
对random_state参数感到困惑,不确定为什么决策树训练需要一些随机性.我的想法,(1)它与随机森林有关吗?(2)是否与分裂训练测试数据集有关?如果是这样,为什么不直接使用训练测试分割方法(http://scikit-learn.org/stable/modules/generated/sklearn.cross_validation.train_test_split.html)?
http://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html
>>> from sklearn.datasets import load_iris
>>> from sklearn.cross_validation import cross_val_score
>>> from sklearn.tree import DecisionTreeClassifier
>>> clf = DecisionTreeClassifier(random_state=0)
>>> iris = load_iris()
>>> cross_val_score(clf, iris.data, iris.target, cv=10)
...
...
array([ 1. , 0.93..., 0.86..., 0.93..., 0.93...,
0.93..., 0.93..., 1. , 0.93..., 1. ])
Run Code Online (Sandbox Code Playgroud)
问候,林
Ami*_*ory 19
这在文档中有解释
已知在最优性的几个方面甚至对于简单的概念,学习最优决策树的问题是NP完全的.因此,实际的决策树学习算法基于启发式算法,例如贪婪算法,其中在每个节点处进行局部最优决策.这种算法不能保证返回全局最优决策树.这可以通过在集合学习器中训练多个树来减轻,其中特征和样本随替换而被随机采样.
因此,基本上,使用特征和样本的随机选择(在随机森林中使用的类似技术)重复次优贪心算法若干次.该random_state参数允许控制这些随机选择.
该接口文件明确规定:
如果是int,则random_state是随机数生成器使用的种子; 如果是RandomState实例,则random_state是随机数生成器; 如果为None,则随机数生成器是np.random使用的RandomState实例.
因此,随机算法将在任何情况下使用.传递任何值(无论是特定的int,例如0,还是RandomState实例)都不会改变它.传递int值(0或其他)的唯一理由是使调用之间的结果保持一致:如果用random_state=0(或任何其他值)调用它,那么每次都会得到相同的结果.
random_statescikit-learn 中决策树的参数决定了当(且仅当)有两个同样好的分割时选择哪个特征进行分割(即两个特征在所选分割标准(例如基尼系数)中产生完全相同的改进))。如果不是这种情况,则该random_state参数无效。
Teatrader 的答案中链接的问题对此进行了更详细的讨论,并且由于该讨论,以下部分已添加到文档中(添加了重点):
random_state int,RandomState实例或None,默认=None
控制估计器的随机性。即使拆分器设置为“最佳”,特征在每次拆分时始终会随机排列。当 max_features < n_features 时,算法将在每次分割时随机选择 max_features,然后找到其中的最佳分割。但是,即使 max_features=n_features,找到的最佳分割也可能在不同的运行中有所不同。如果标准的改进对于多个分割是相同的并且必须随机选择一个分割,则情况就是这样。为了在拟合过程中获得确定性行为,random_state 必须固定为整数。详细信息请参见术语表。
为了说明这一点,让我们考虑以下示例,其中包含 iris 样本数据集和仅包含单个分割的浅层决策树:
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier, plot_tree
iris = load_iris(as_frame=True)
clf = DecisionTreeClassifier(max_depth=1)
clf = clf.fit(iris.data, iris.target)
plot_tree(clf, feature_names=iris['feature_names'], class_names=iris['target_names']);
Run Code Online (Sandbox Code Playgroud)
该代码的输出将根据所random_state使用的树在以下两个树之间交替。
这样做的原因是,对任一petal length <= 2.45或petal width <= 0.8两者进行分割将完美地将 setosa 类与其他两个类分开(我们可以看到最左边的 setosa 节点包含所有 50 个 setosa 观测值)。
如果我们仅更改数据的一个观察结果,从而使前两个分割标准之一不再产生完美的分离,则将random_state不起作用,并且我们将始终得到相同的结果,例如:
# Change the petal width for first observation of the "Setosa" class
# so that it overlaps with the values of the other two classes
iris['data'].loc[0, 'petal width (cm)'] = 5
clf = DecisionTreeClassifier(max_depth=1)
clf = clf.fit(iris.data, iris.target)
plot_tree(clf, feature_names=iris['feature_names'], class_names=iris['target_names']);
Run Code Online (Sandbox Code Playgroud)
现在,第一次分割将始终如此petal length <= 2.45,因为分割petal width <= 0.8只能分离出 50 个 setosa 类别中的 49 个(换句话说,基尼系数的下降幅度较小)。
对于随机森林(由许多决策树组成),我们将使用随机选择的特征和样本来创建每个单独的树(请参阅https://scikit-learn.org/stable/modules/ensemble.html#random-forest -参数用于详细信息),因此参数的作用更大random_state,但是当仅训练单个决策树时,情况并非如此(默认参数也是如此,但值得注意的是,某些参数可能会受到随机性(如果它们从默认值更改,最值得注意的是设置splitter="random")。
几个相关问题:
| 归档时间: |
|
| 查看次数: |
16787 次 |
| 最近记录: |