决策树的高级概述

这篇文章将作为决策树的高级概述。它将涵盖决策树如何训练,与“信息增益”和“基尼指数”相关信息。我还将进行超参数调整和决策树剪枝以进行优化。本文介绍的两种决策树算法是CART和ID3。

决策树是非常流行的模型,支持分类和回归。决策树是高度可解释的,并为更复杂的算法,例如随机森林提供了基础。

决策树的结构可以看作是一个有向无环图,是一个节点序列。这个图形是单向的,没有对象可以是其自身的子代。

看看上面的DAG,我们可以看到它从根节点开始,最好的属性变成内部节点,即决策节点。然后,内部节点检查条件并执行决策,将样本空间分为两部分。叶子节点代表一个分类,当记录到达叶子节点时,算法将相应的叶子分配标签。这个过程称为样本空间的递归划分。决策树的术语:

  • 父节点-具有子节点的节点
  • 子节点-父节点的孩子节点
  • 根节点-表示将拆分为两个或多个集(子节点)的样本空间/总体
  • 决策节点-分为多个子节点的节点(子节点)
  • 叶节点-没有子节点的节点(子节点)
  • 分支-决策树的一个子部分
  • 剪枝-通过删除节点来减少决策树的大小

拆分标准

决策树使用一些代价函数来选择最优分割。我们试图找到在分类数据方面表现最好的最佳属性/特征。这个过程一直重复,直到到达一个叶节点,因此被称为递归二元分割。

当执行这个过程时,所有的值都被排成一行,树将测试不同的拆分,并选择一个返回最低成本的拆分,这使得这是一个贪婪的方法。

需要注意的是,由于该算法将数据重复划分为更小的子集,因此最终的子集(叶节点)由几个或只有一个数据点组成。这使得算法具有低偏差和高方差。

熵与信息增益

一个广泛使用的决策树度量是熵。香农熵,以香农的名字命名,为我们提供了不确定性的度量。当涉及到数据时,熵告诉我们数据有多混乱。高熵值表示预测能力较低,可以将特征的熵视为该特征中的信息量。

决策树可以在进行拆分时最大限度地提高类的纯度,从而使叶节点中的类更加清晰。熵是在每次分割前后计算出来的。如果熵增加,将尝试另一次拆分。如果熵减小,分割将保持不变。计算整个数据集熵的公式:

式中,是簇的数目,()是属于第i个簇的概率。假设我们有一个包含462个正(1)标签和438个负(0)标签的数据集。我们可以通过以下方法计算数据集的熵:

class_1_count = 462class_0_count = 438prob_class_1 = (class_1_count / (class_1_count + class_0_count))prob_class_0 = (class_0_count / (class_1_count + class_0_count))entropy = (-prob_class_0) * np.log2(prob_class_0) - prob_class_1 * np.log2(prob_class_1)#熵: 0.9994869809508898

信息增益使用熵作为不纯度的度量。它是分割前和分割后的熵之差,它会给我们一个不确定性降低多少的数字。这也是ID3分类树算法中使用的关键准则,公式如下。

基尼不纯度

在执行分类任务时,使用基尼指数函数。这个函数告诉我们树中的叶节点有多“纯净”。基尼不纯度总是在0到0.5之间,值越高,簇越无序。公式如下:

其中()是属于第i个簇的概率。上面的公式表明,基尼系数的不确定性是1减去每个分割中不同概率的总和。

决策树剪枝

当决策树通过递归进行训练时,我们还可以设置停止树的参数。决策树越复杂,越容易过拟合。我们可以使用超参数修剪树:

  • max_depth-决定我们希望树有多深
  • min_samples_leaf—每个叶节点中的最小训练样本数
  • max_leaf_nodes-最大叶节点数
  • min_impurity_decrease—阈值,以确定节点将分裂还是成为叶子

有更多可以更改的参数,有关列表和更详细的说明,请查看文档:https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html

使用Scikit-learn的决策树

让我们用sklearn构建一个决策树分类器。我将使用泰坦尼克号数据集,目标是Survived特征。我正在加载的数据集之前已经被清理过。有关数据集中特征的描述,请参阅下面的数据字典。

导入必要的库

%load_ext autoreload%autoreload 2import osimport sysmodule_path = os.path.abspath(os.path.join(os.pardir, os.pardir))if module_path not in sys.path:    sys.path.append(module_path)import pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport seaborn as snsimport warningswarnings.filterwarnings('ignore')from sklearn.metrics import confusion_matrix, plot_confusion_matrix, accuracy_scorefrom sklearn.tree import DecisionTreeClassifierfrom sklearn.model_selection import train_test_split, cross_val_scorefrom sklearn.preprocessing import OneHotEncoder, StandardScalerfrom sklearn import tree

加载和预览数据集

df = pd.read_csv('titanic_cleaned.csv')df.head()

定义预测和目标特征,执行训练测试集分割,并对数据进行预处理

X = df.drop('Survived', axis=1)y = df.Survived# 训练测试分割X_train, X_test, y_train, y_test = train_test_split(X,y, random_state=42)# 导入scaler和encoderfrom sklearn.preprocessing import StandardScaler, OneHotEncoder# 在数据帧中定义数字和分类特征numerical = ['Age', 'Fare']categorical = ['Pclass', 'SibSp', 'Parch', 'male']# 定义训练和测试索引变量来转换数据帧中的数值X_train_index = X_train.indexX_test_index = X_test.index# 实例化一个hotencoder并定义训练和测试ohe = OneHotEncoder()X_train_ohe = X_train[categorical]X_test_ohe = X_test[categorical]# 拟合并转换X_train_encoded = ohe.fit_transform(X_train_ohe)X_test_encoded = ohe.transform(X_test_ohe)# 实例化StandardScaler并定义连续变量ss = StandardScaler()X_train_cont = X_train[numerical].astype(float)X_test_cont = X_test[numerical].astype(float)# 缩放连续特征并将结果转换为数据帧X_train_scaled = pd.DataFrame(ss.fit_transform(X_train_cont), columns=X_train_cont.columns,                              index=X_train_index)X_test_scaled = pd.DataFrame(ss.transform(X_test_cont), columns=X_test_cont.columns,                             index=X_test_index)# 定义训练和测试的列train_columns = ohe.get_feature_names(input_features=X_train_ohe.columns)test_columns = ohe.get_feature_names(input_features=X_test_ohe.columns)# 将已编码的X_train和X_test转换为数据帧X_train_processed = pd.DataFrame(X_train_encoded.todense(), columns=train_columns, index=X_train_index)X_test_processed = pd.DataFrame(X_test_encoded.todense(), columns=test_columns, index=X_test_index)# 为预处理过的X_train和X_test组合编码和缩放的数据帧X_train = pd.concat([X_train_scaled, X_train_processed], axis=1)X_test = pd.concat([X_test_scaled, X_test_processed], axis=1)

训练决策树分类器

# 用熵函数实例化决策树分类器以获取信息增益dtree = DecisionTreeClassifier(criterion='entropy')# 拟合dtree.fit(X_train, y_train)fsm_train_acc = dtree.score(X_train, y_train)fsm_test_acc = dtree.score(X_test, y_test)print('BASELINE TRAIN ACCURACY: {}\nBASELINE TEST ACCURACY:  {}'.format(fsm_train_acc, fsm_test_acc))

决策树分类器在训练集上的性能优于测试集,表明模型过拟合。决策树容易过拟合,因为递归分割过程将一直持续到叶节点,从而导致模型过于复杂。在这里,我们将执行超参数调整和修剪以优化分类器。


绘制树

为了直观地看到拆分,绘制树可能会有所帮助。我们可以用几个额外的库来绘制这棵树。

from sklearn import externalsfrom sklearn.externals.six import StringIO  from IPython.display import Image  from sklearn.tree import export_graphvizimport pydotplusdot_data = StringIO()export_graphviz(dtree, out_file=dot_data,                  filled=True, rounded=True,                special_characters=True,                feature_names=X_train.columns)graph = pydotplus.graph_from_dot_data(dot_data.getvalue())  Image(graph.create_png())

特征重要性

如果我们想检查模型的特征重要性,可以使用决策树分类器中的.feature_importances_属性。特征重要性使用基尼计算。

# 离散列的one-hot encoded特征与.get_feature_names方法ohe_cols = list(ohe.get_feature_names(input_features=categorical))# 数值列feats = list(numerical)feats.extend(ohe_cols)# 使用explain_weights_df函数按升序包含特征重要性feat_imp = eli5.explain_weights_df(dtree, feature_names=feats)feat_imp

用网格搜索优化决策树分类器

通过运行交叉验证的网格搜索,我们可以输入一个参数字典,其中包含决策树超参数的不同值。我使用了上面提到的超参数和默认的5倍交叉验证。

param_grid = [  {'criterion': ['gini', 'entropy'],    'max_leaf_nodes': list(range(1,15)),   'max_depth': list(range(2,10)),   'min_impurity_decrease': [0.00005,0.0001,0.0002,0.0005,0.001,0.0015,0.002,0.005,0.01],   'min_samples_leaf': list(range(1,39))}              ]from sklearn.model_selection import GridSearchCVsearch = GridSearchCV(DecisionTreeClassifier(), param_grid=param_grid, cv=5)search.fit(X_train, y_train)
# 训练集平均准确度得分train_acc = search.best_estimator_.score(X_train, y_train)# 测试集的平均准确度得分test_acc = search.best_estimator_.score(X_test, y_test)print('GRID SEARCH BEST PARAMETERS:\n\n\t\t{}\n\n'.format(search.best_estimator_))print('TRAIN ACCURACY: {}\nTEST ACCURACY:  {}\n'.format(train_acc, test_acc))

通过运行交叉验证网格搜索,最佳参数改善了我们的偏差-方差权衡。具有默认参数的第一个模型在训练集上的表现比测试集好20%,表明树中的低偏差和高方差。调整后的决策树表明,训练集和测试集的方差减小了5%,精度下降了5%。


CART回归

执行回归任务的决策树也将样本划分为更小的集合。回归树的目标是递归地划分样本空间,直到一个简单的回归模型可以拟合。

回归树中的叶节点是分区。简单回归模型去拟合每个分区,然后取分区因变量的均值,即用样本均值进行预测。

我们使用上面的熵作为不纯度的度量来进行分类。对于回归,CART算法使用均方误差作为不纯度的度量。

  • 是节点中的训练子集
  • 是节点中的训练样本数
  • 是第i个样本的目标值
  • ̂是预测目标值,样本的平均值

在评估模型的性能时,我们将关注均方根误差(RMSE)。这只是平方误差平均值的平方根。通过平方根,我们可以测量误差的大小,它比平均值对较大误差的权重更大。我们评估模型拟合程度的度量是R方。R方告诉我们因变量中方差的百分比。

使用Scikit-learn回归树

让我们继续用sklearn构建一个决策树回归器。我将使用从kaggle检索到的Ames住房数据集。在本教程中,我将只使用3个连续特征和目标特征。

加载到数据集中,定义预测和目标特征,并执行训练测试集分割

df = pd.read_csv('ames.csv')X = df.SalePricey = df[['LotArea', '1stFlrSF', 'GrLivArea']]X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)

训练决策树回归器

from sklearn.tree import DecisionTreeRegressorfrom sklearn.metrics import mean_squared_error# 实例化DecisionTreeRegressordtree_reg = DecisionTreeRegressor()# 拟合回归函数到训练集dtree_reg.fit(X_train, y_train)reg_train_r2 = dtree_reg.score(X_train, y_train)reg_train_rmse = mean_squared_error(y_train, dtree_reg.predict(X_train), squared=False)reg_test_r2 = dtree_reg.score(X_test, y_test)reg_test_rmse = mean_squared_error(y_test, dtree_reg.predict(X_test), squared=False)print('BASELINE TRAIN R-SQUARED: {} | BASELINE TRAIN RMSE {}\      \nBASELINE TEST R-SQUARED:  {} | BASELINE TEST RMSE {}'.format(reg_train_r2, reg_train_rmse,                                                                   reg_test_r2, reg_test_rmse))

再一次,决策树对训练集的拟合度过高。与分类类似,我们可以运行交叉验证的网格搜索来优化决策树。

用网格搜索cv优化决策树回归器

param_grid = [  {'criterion': ['mse', 'mae'],   'max_features': ['sqrt', 'log2', 0.1],   'max_leaf_nodes': list(range(2,15)),   'max_depth': list(range(2,32)),   'min_impurity_decrease': [0.00005,0.0001,0.0002,0.0005,0.001,0.0015,0.002,0.005,0.01],   'min_samples_leaf': list(range(1,39))}              ]reg_search = GridSearchCV(DecisionTreeRegressor(), param_grid=param_grid, cv=5)reg_search.fit(X_train, y_train)
train_r2 = reg_search.best_estimator_.score(X_train, y_train)grid_train_rmse = mean_squared_error(y_train, reg_search.best_estimator_.predict(X_train), squared=False)test_r2 = reg_search.best_estimator_.score(X_test, y_test)grid_test_rmse = mean_squared_error(y_test, reg_search.best_estimator.predict(X_test), squared=False)print('REGRESSION GRID SEARCH BEST PARAMETERS:\n\n\t\t{}\n\n'.format(reg_search.best_estimator_))print('TRAIN R-SQUARED: {}\nTEST R-SQUARED:  {}\n'.format(train_r2, test_r2))print('\nTRAIN RMSE: {}\nTEST RMSE: {}'.format(grid_train_rmse, grid_test_rmse))

通过使用决策树回归器运行交叉验证网格搜索,我们提高了测试集的性能。使用网格搜索中的参数,我们将测试集上的r方从0.42增加到0.56。r方为0.58告诉我们模型没有对训练数据进行过拟合,并且在看不见的测试集上也会有类似的表现。


结论

决策树是一种很好的预测模型,可以用于分类和回归。对于大量的机器学习问题,它们具有高度的可解释性和强大的功能。虽然分类和回归任务之间有许多相似之处,但了解每个任务使用的不同度量是很重要的。

决策树的超参数有助于克服它们对训练数据的过拟合倾向。需要注意的是,虽然执行网格搜索有助于为决策树找到最佳的超参数,但它们的计算成本也非常高。根据可能选择的参数,网格搜索可能会运行数小时甚至数天。


参考引用

  • 1.10. Decision Trees. (n.d.). Retrieved from https://scikit-learn.org/stable/modules/tree.html#
  • Sklearn.tree.DecisionTreeClassifier. (n.d.). Retrieved from https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html
  • Sklearn.tree.DecisionTreeRegressor. (n.d.). Retrieved from https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeRegressor.html
  • Ronaghan, S. (2019, November 01). The Mathematics of Decision Trees, Random Forest and Feature Importance in Scikit-learn and Spark. Retrieved from https://towardsdatascience.com/the-mathematics-of-decision-trees-random-forest-and-feature-importance-in-scikit-learn-and-spark-f2861df67e3
  • 14.2 — Recursive Partitioning. (n.d.). Retrieved from https://online.stat.psu.edu/stat555/node/100/
  • Brownlee, J. (2020, August 14). Classification And Regression Trees for Machine Learning. Retrieved from https://machinelearningmastery.com/classification-and-regression-trees-for-machine-learning/
  • Frost, J., Lombardi, J., Hadero, M., Aksamitova, J., Lamessa, Laurie, . . . Dubey, D. (2020, November 03). How To Interpret R-squared in Regression Analysis. Retrieved from https://statisticsbyjim.com/regression/interpret-r-squared-regression/
  • RMSE: Root Mean Square Error. (2020, July 06). Retrieved from https://www.statisticshowto.com/probability-and-statistics/regression-analysis/rmse-root-mean-square-error/
  • Sklearn.metrics.mean_squared_error. (n.d.). Retrieved from https://scikit-learn.org/stable/modules/generated/sklearn.metrics.mean_squared_error.html
  • Titanic — Machine Learning from Disaster. (n.d.). Retrieved from https://www.kaggle.com/c/titanic
  • Ames Housing Data Summer 2018. (n.d.). Retrieved from https://www.kaggle.com/c/ames-housing-data-summer-2018/data
(0)

相关推荐

  • ML之xgboost:利用xgboost算法(sklearn+3Split)训练mushroom蘑菇数据集(22+1,6513+1611)来预测蘑菇是否毒性(二分类预测)

    ML之xgboost:利用xgboost算法(sklearn+3Split)训练mushroom蘑菇数据集(22+1,6513+1611)来预测蘑菇是否毒性(二分类预测) 输出结果 设计思路 核心代码 ...

  • 成功解决ModuleNotFoundError: No module named ‘sklearn.cross_validation‘

    成功解决ModuleNotFoundError: No module named 'sklearn.cross_validation' 解决问题 ModuleNotFoundError: No mod ...

  • 如何用几行代码运行 40 个回归模型

    这篇文章教你如何使用 Lazy Predict 运行超过 40 个机器学习模型进行回归项目. 假设你需要执行一项回归机器学习项目.你已经分析了你的数据,进行了一些数据清洗,创建了一些虚拟变量,现在,是 ...

  • DL之RBM:基于RBM实现手写数字图片识别提高准确率

    DL之RBM:基于RBM实现手写数字图片识别提高准确率 输出结果 设计代码 import numpy as np import matplotlib.pyplot as plt from sklear ...

  • 人工智能基础课堂纪要7

    4.2 决策树分类原理[*****] 1.信息增益 信息增益 = entroy(前) - entroy(后) 注意:信息增益越大,我们优先选择这个属性进行计算 信息增益优先选择属性总类别比较多的进行划 ...

  • 原理 代码,总结了 11 种回归模型

    导读: 本文总结了一些常用的除线性回归模型之外的模型,其中包括一些单模型及集成学习器. 保序回归.多项式回归.多输出回归.多输出K近邻回归.决策树回归.多输出决策树回归.AdaBoost回归.梯度提升 ...

  • GBDT:梯度提升树算法

    GBDT全称为gradient boosting decision tree, 是一种基于决策树的集成学习算法.在Adaboost算法中,弱分类器的模型可以根据需要灵活选择,而GBDT则强制限定为决策 ...

  • 风湿与临床免疫学高级职称-心脏瓣膜病概述|山河医学网

    11风湿与临床免疫学高级职称-心脏瓣膜病概述|山河医学网

  • 胸心外科高级职称考试-泌尿系统概述|山河医学网

    14胸心外科高级职称考试-泌尿系统概述|山河医学网

  • 生态旅游概述

    生态旅游被广泛定义为到濒危和通常未受干扰的地方进行的低影响旅游.它与传统旅游不同,因为它可以让游客对当地的自然景观和文化特征有所了解,而且经常为保护提供资金,并有利于经常贫困地区的经济发展. 生态旅游 ...

  • 经络穴位解读——手阳明大肠经概述及重要穴位

    经络穴位解读--手阳明大肠经概述及重要穴位 原创牛奶和奶牛2020-11-30 19:20:14 今天我们来解读一下手阳明大肠经.在中医学里,经络是与脏腑相匹配的.同时也是互为表里的关系.例如手太阴肺 ...

  • 区域地理学概述

    区域地理学是地理学研究世界区域的一个分支.一个地区本身被定义为地球表面的一部分,具有一个或多个类似的特征,使其有别于其他地区.区域地理学研究的是与地方的文化.经济.地形.气候.政治和环境因素有关的特定 ...

  • 想要订制高级西装选这些准没错 世界顶级五大西装面料品牌

    说到顶级西装品牌,大家能想到的品牌可能来自世界各地,例如美国.英国.意大利.但你知道世界顶级五大西装面料品牌都是来自于欧洲,欧洲工业化的蓬勃发展为西装面料的研究开发和发展提供了强有力的技术和平台,欧洲 ...

  • 5种人员分析的高级方法

    之前已经给出了多个示例,说明员工如何从数据分析中受益,本文我想探索一组不同的高级数据分析技术,以了解如何将其用于分析人员数据以提高组织的成功率. 数据科学越来越多地融入企业,产品和整个社会,事例变得越 ...

  • 一个活得高级的女人,一般都有这几个特征

    2021-04-23小小筑乔木 文/乔木 生活中有一种女人,你会发现她无惧婚姻的危机,更不怕生活的风风雨雨. 对于有的女人来说,不管自己的婚姻是怎样的状态,家庭都只是锦上添花的事,离婚也只是让自己,回 ...

  • 概述蛋白石

    蛋白石因颜色.光泽独特而名.其彩虹般绚丽耀目的光芒多彩似马赛克,充满了神秘性,足其它宝石无可比拟的. 虽然名为蛋白石,却非单一色调,如果仅仅是白色,倒反而没有价值了.透明.红色.黄色色系,在澳洲多为乳 ...