【问题标题】:Decision tree too big Scikit Learn决策树太大 Scikit Learn
【发布时间】:2020-04-05 23:18:41
【问题描述】:

我有一个包含 1025 个输入和 14 列的数据。首先,我通过将它们放在单独的表中来设置标签。

x = dataset.drop('label', axis=1)
y = dataset['label']

标签值只有 1 或 0。然后我使用以下方法拆分数据:

X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.30)

然后我制作我的分类器:

from sklearn.tree import DecisionTreeClassifier
classifier = DecisionTreeClassifier()
classifier.fit(X_train, y_train)

然后每当我制作决策树时,它都会变得太大:

from sklearn import tree
tree.plot_tree(classifier.fit(X_train, y_train))

结果输出 8 个级别,结果太大了。我认为这没问题,但在观察了混淆矩阵和分类报告后:

from sklearn.metrics import classification_report, confusion_matrix
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))

结果是:

[[155   3]
[  3 147]]
precision    recall  f1-score   support
0       0.98      0.98      0.98       158
1       0.98      0.98      0.98       150

    accuracy                           0.98       308
   macro avg       0.98      0.98      0.98       308
weighted avg       0.98      0.98      0.98       308

高精度让我怀疑我的解决方案。我的代码有什么问题,如何降低决策树和准确度得分?

【问题讨论】:

  • 你能定义太大是什么意思吗?为什么你希望你的决策树不准确?
  • 这棵树有 95 个节点和 8 个层级。我认为它的分支过多无法概括其决定
  • 那么您是否正在寻找防止决策树中过度拟合的方法?我们需要确保问题的范围适当,以便我们可以提供足够的答案:)
  • 您可以验证您的模型。您可能还想看看这个:en.wikipedia.org/wiki/Hyperparameter_optimization
  • 如果这解决了您的问题,请不要忘记标记为正确@rnlxs

标签: python machine-learning scikit-learn decision-tree


【解决方案1】:

看起来您需要做的是检查以确保您的树没有过度拟合。我们可以通过两种主要方式使用决策树和 sklearn 完成此任务。

验证曲线

首先,您应该检查以确保您的树 过拟合。您可以使用验证曲线 (see here)。

验证曲线示例如下:

import numpy as np
from sklearn.model_selection import validation_curve
from sklearn.datasets import load_iris
from sklearn.linear_model import Ridge

np.random.seed(0)
X, y = load_iris(return_X_y=True)
indices = np.arange(y.shape[0])
np.random.shuffle(indices)
X, y = X[indices], y[indices]

train_scores, valid_scores = validation_curve(Ridge(), X, y, "alpha",
                                              np.logspace(-7, 3, 3),
                                              cv=5)
train_scores



valid_scores

一旦你确认你的树过度拟合,你需要做一个叫做pruning的事情,你可以使用@e-zeytinci提到的超参数优化来完成。你可以用GridSearchCV来做到这一点

GridSearchCV

GridSearchCV 允许我们优化决策树或任何模型的超参数,以查看最大深度和最大节点(这似乎是 OP 关注的问题)之类的东西,还可以帮助我们完成适当的修剪。

An example of that implementation can be read here

来自this post 的一组工作代码示例如下:

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import GridSearchCV

def dtree_grid_search(X,y,nfolds):
    #create a dictionary of all values we want to test
    param_grid = { 'criterion':['gini','entropy'],'max_depth': np.arange(3, 15)}
    # decision tree model
    dtree_model=DecisionTreeClassifier()
    #use gridsearch to test all values
    dtree_gscv = GridSearchCV(dtree_model, param_grid, cv=nfolds)
    #fit model to data
    dtree_gscv.fit(X, y)
    return dtree_gscv.best_params_

随机森林

或者,Random Forests can help with Decision Tree overfitting

您可以实现 RandomForestClassifier 并遵循上述相同的超参数调整。

this post 的示例如下:

from sklearn.grid_search import GridSearchCV
from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
# Build a classification task using 3 informative features
X, y = make_classification(n_samples=1000,
                           n_features=10,
                           n_informative=3,
                           n_redundant=0,
                           n_repeated=0,
                           n_classes=2,
                           random_state=0,
                           shuffle=False)


rfc = RandomForestClassifier(n_jobs=-1,max_features= 'sqrt' ,n_estimators=50, oob_score = True) 

param_grid = { 
    'n_estimators': [200, 700],
    'max_features': ['auto', 'sqrt', 'log2']
}

CV_rfc = GridSearchCV(estimator=rfc, param_grid=param_grid, cv= 5)
CV_rfc.fit(X, y)
print CV_rfc.best_params_

【讨论】:

    【解决方案2】:

    如果您还包括您的训练和测试分数(您已经进行了测试),您可以验证您的决策树分数:

    print(confusion_matrix(y_train, clf.predict(y_train))
    print(classification_report(y_train, clf.predict(y_train))
    

    如果您有类似的结果,则您的树在准确度(精确度)方面非常合适。您还可以检查this 是否存在过度拟合和欠拟合。

    关于过拟合和欠拟合的概念:

    蓝色曲线是训练数据的误差,红色曲线哪里是测试误差,这里你可以看到蓝色误差下降,哪里红色卡住。这是过拟合——这意味着训练数据对数据的影响很大。

    但是您对测试数据的错误已经很低,这表明:

    过拟合的函数可能比最优函数请求更多关于验证数据集中每个项目的信息;收集这些额外的不需要的数据可能会很昂贵或容易出错,尤其是在必须通过人工观察和手动数据输入来收集每条信息的情况下。

    时刻提醒自己只有 14 个条件可用。您可以在这里找到完整的参数:https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html

    如果您对平衡数据有如此准确的结果,我会问自己是否有直接影响您的目标变量的特征(列)。关键词是数据泄露。这意味着你有一个特性,它只是因为你的目标变量而存在,而在实际测试中你不会提前拥有它。获得想法的一个提示是:https://scikit-learn.org/stable/auto_examples/ensemble/plot_forest_importances.html

    如果你仍然觉得你的树太深,你可以调整你的最大深度:

    classifier = DecisionTreeClassifier(max_depth= 4)
    

    【讨论】:

    • 您很可能收到了反对票,因为您的答案主要是链接——对 OP 发布代码更有利; OP 可以帮助他们解决问题的示例。
    • 你已经有考试成绩了,挺好的,你需要问自己的问题,你的火车成绩有多好?
    • 对我来说,这更像是一个概念问题,与编码无关
    猜你喜欢
    • 2017-02-23
    • 2017-03-26
    • 2017-01-21
    • 1970-01-01
    • 2015-03-05
    • 2014-06-26
    • 2016-08-12
    • 2013-12-12
    相关资源
    最近更新 更多