传送门:回归树
1、概述
决策树算法是一种监督学习算法。
优点:可用于回归、也可用于分类,易于解释且不需要特征缩放。
缺点:容易过拟合。
-
造成过拟合(Overfitting)的原因:
训练集中样本量较小。如果决策树选择的属性过多,构造出来的决策树一定能够“完美”地把训练集中的样本分类,但是这样就会把 train_set 中一些数据的特点当成所有数据的特点,但这个特点不一定是全部数据的特点,这就使得这个决策树在真实的数据分类中出现错误,也就是模型的“泛化能力”差。
*泛化能力:指的分类器是通过训练集抽象出来的分类能力,你也可以理解是举一反三的能力。如果我们太依赖于训练集的数据,那么得到的决策树容错率就会比较低,泛化能力差。因为训练集只是全部数据的抽样,并不能体现全部数据的特点。 -
“停止分裂”——剪枝
剪枝就是给决策树瘦身,这一步想实现的目标就是,不需要太多的判断,同样可以得到不错的结果。之所以这么做,是为了防止“过拟合”现象的发生。剪枝的方法:
- 预剪枝:在决策树构造时就进行剪枝。方法是,在构造的过程中对节点进行评估,如果对某个节点进行划分,在验证集中不能带来准确性的提升,那么对这个节点进行划分就没有意义,这时就会把当前节点作为叶节点,不对其进行划分。
- 后剪枝:在生成决策树之后再进行剪枝。通常会从决策树的叶节点开始,逐层向上对每个节点进行评估。如果剪掉这个节点子树,与保留该节点子树在分类准确性上差别不大,或者剪掉该节点子树,能在验证集中带来准确性的提升,那么就可以把该节点子树进行剪枝。方法是:用这个节点子树的叶子节点来替代该节点,类标记为这个节点子树中最频繁的那个类。
2、Decision Tree的生成过程
Decision Tree的生成过程主要分以下两步,这两步通常通过学习已经知道分类结果的样本来实现。
-
节点的分裂:一般当一个节点所代表的属性无法给出判断时,则选择将这一节点分成2个
子节点(如不是二叉树的情况会分成n个子节点) - 阈值的确定:选择适当的阈值使得分类错误率最小 (Training Error)。
3、决策树的生成算法
决策树的生成算法有ID3、C4.5、C5.0、CART(Classification And Regression Tree)等。CART的分类效果一般优于其他决策树。
三种方法对比:
- ID3的缺点,倾向于选择水平数量较多的变量,可能导致训练得到一个庞大且深度浅的树;另外输入变量必须是分类变量(连续变量必须离散化);最后无法处理空值。
- C4.5选择了信息增益率替代信息增益。
- CART以基尼系数替代熵;最小化不纯度而不是最大化信息增益。
4、Demo
- Scikit-learn使用了CART算法的优化版本。
# coding=utf-8
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
# 画图支持中文显示
from pylab import *
mpl.rcParams['font.sans-serif'] = ['SimHei']
# 显示所有列
pd.set_option('display.max_columns', None)
# 显示所有行
pd.set_option('display.max_rows', None)
# 设置value的显示长度为10000,默认为50
pd.set_option('display.width',10000)
pd.set_option('display.unicode.ambiguous_as_wide', True)
pd.set_option('display.unicode.east_asian_width', True)
data = load_iris()
df = pd.DataFrame(data.data, columns=data.feature_names)
df['target'] = data.target # 将结果合并至最后一列
print(df.tail())
print((df.groupby('target')).size())
X_train,X_test,Y_train,Y_test = train_test_split(df[data.feature_names], df['target'], random_state=0, test_size=0.25) # random_satate 随机数种子 使每次随机生成的参数一致,以下此参数都设置成相同的
clf = DecisionTreeClassifier(max_depth=2, random_state=0)
# ---------train---------
clf.fit(X_train, Y_train)
# --------predict--------
# predict for 1 observation
print(clf.predict(X_test.iloc[0].values.reshape(1, -1)))
# predict for multiple observation
print(clf.predict(X_test[0:10]))
# 评估模型性能
# 评估模型性能的方式有:精度、召回率、F1得分、ROC曲线等,这里我们选择准确率作为评估的标准。
# The score method returns the accuracy of the model
# 准确率的定义为:正确预测的比例=正确预测的数量/总数据量
score = clf.score(X_test, Y_test)
print(score)
# 模型调优
max_depth_range = list(range(1, 6)) # List of values to try for max_depth
# max_depth_range = np.linspace(1, 5, 5) # 从(1, 5)均匀取5个点
# print(max_depth_range)
# print(type(max_depth_range[0]))
accuracy = []
for depth in max_depth_range:
clf = DecisionTreeClassifier(max_depth=depth, random_state=0)
clf.fit(X_train, Y_train)
score = clf.score(X_test, Y_test)
accuracy.append(score)
plt.plot(max_depth_range, accuracy, color='red', linewidth=3.0, linestyle='--', label='准确率曲线')
plt.xlim(1, 8) # 设置坐标轴
plt.ylim(0, 2)
plt.xlabel("max_depth") # 坐标轴名称
plt.ylabel("准确率")
plt.legend(loc = 'upper right') #简单地设置legend(设置图例位置),位置在右上角
plt.title("分类树")
plt.show()
# max_depth和决策树的深度并不是一回事。Max_depth是对决策树进行预剪枝的一个方法。
# 换而言之,如果一棵树在某个深度纯度已经足够高,将会停止分裂。
# 特征的重要性
importances = pd.DataFrame({'feature':X_train.columns,'importance':np.round(clf.feature_importances_,3)})
print(importances)
importances = importances.sort_values('importance',ascending=False)
print(importances)
accurary line
网友评论