一.决策树简介
1.什么是决策树
决策树是一种树形结构,树中每个内部节点表示一个特征上的判断,每个分支代表一个判断结果的输出,每个叶子节点代表一种分类结果。它主要用于分类和回归任务,通过递归地分裂数据集构建树状结构。
2.决策树构建过程(三要素)
① 特征选择:
选择较强分类能力的特征
② 决策树的生成:
根据选择的特征生成决策树
③ 决策树的剪枝:
决策树也容易过拟合,采用剪枝的方法缓解过拟合
3.优缺点及应用
优点:
- 可解释性强
- 能处理非线性关系
- 对缺失值有一定鲁棒性
缺点:
- 容易过拟合
- 对数据变化敏感
- 可能产生不稳定树结构
应用:分类问题(如是否批准贷款),回归问题(如房价预测),多阶段决策问题
二.核心树结构
先介绍一下信息熵:随机变量不确定度的度量,信息熵越大,信息的不确定性越大,信息的确定性越小,信息的纯度越低,分类的效果越差。
1.ID3决策树
① 使用信息增益作为分裂标准:信息增益=经验熵-条件熵
信息增益公式:g(D,A)=H(D)-H(D|A)
用两张图表示一下分类条件:
特征a |
目标值 |
α |
A |
α |
A |
β |
B |
α |
A |
β |
B |
α |
B |
② 用ID3生成决策树:
1.计算每个特征的信息增益
2.使用信息增益最大的特征将数据集拆分为子集
3.使用该特征(信息增益最大的特征)作为决策树的一个节点
4.若该节点已成功分类(节点中只有一个类的样本)或该节点达到停止生长条件,则停止生长,否则使用剩余特征对子集重复上述(1,2,3)过程
③ ID3树的不足之处:基于信息增益计算的方式,会偏向于选择种类多的特征作为分裂依据
2.C4.5树结构
- 改进ID3,使用增益率避免偏向多值属性
① 特征选择
以信息增益率选择特征:信息增益率=信息增益/特征熵
② 决策树的生成:类似ID3,只是调整为基于信息增益率进行特征选择
3.CART树结构
此树会用到基尼系数(Gini Index):是衡量数据集纯度或分类不确定性的核心指标
CART算法的优点是:可以进行分类和回归,可处理离散属性,也可以处理连续属性;
采用基尼指数,计算量减小且一定是二叉树
① CART树结构
是一种决策树模型,二叉树结构,既可以用于分类又可以用于回归
② CART分类树:
特征选择:选择使划分后基尼系数和最小的特征作为最优划分特征
生成决策树:类似ID3,调整为基于基尼系数进行特征选择
③ CART回归树:
特征选择:最小化回归树预测结果的平方误差(可以处理非线性关系)
生成决策树:
1. 选择一个特征,将该特征的值进行排序,取相邻点计算均值作为待划分点
2. 根据所有划分点,将数据集分成两部分:R1、R2
3. R1 和 R2 两部分的平方损失相加作为该切分点平方损失
4. 取最小的平方损失的划分点,作为当前特征的划分点
5. 以此计算其他特征的最优划分点、以及该划分点对应的损失值
6. 在所有的特征的划分点中,选择出最小平方损失的划分点,作为当前树的分裂点
三.决策树的剪枝处理
1.什么是决策树的剪枝:把子树的节点全部删掉,并将该节点作为叶子节点
目的是防止过拟合,提高泛化能力
2.决策树的剪枝方法:
① 预剪枝
指在决策树生成过程中,对每个节点在划分前先进行估计,若当前节点的划分不能带来决策树泛化性能提升,则停止划分并将当前节点标记为叶节点。
优点:
减少了决策树的训练、测试时间开销
缺点:
带来了欠拟合的风险
② 后剪枝
是先从训练集生成一棵完整的决策树,然后自底向上地对非叶节点进行考察,若将该节点对应的子树替换为叶节点能带来决策树泛化性能提升,则将该子树替换为叶节点。
优点:
泛化性能往往优于预剪枝
缺点:
训练时间开销比未剪枝的决策树和预剪枝的决策树都要大得多
四.CART决策树可视化案例:
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import classification_report, precision_score, recall_score, f1_score, roc_auc_score
import matplotlib.pyplot as plt
from sklearn.tree import plot_tree
"""
演示决策树分层
"""
# 1、读取数据
train_df = pd.read_csv("data/train.csv")
train_df.info()
# 2、数据预处理
# 2-1 获取特征列 和标签列 船舱等级 、 性别 、年龄
x = train_df[['Pclass', 'Sex', 'Age', 'Embarked', 'Ticket']]
y = train_df['Survived']
# 2-2 用age 处理 age列求平均值
x['Age'] = x['Age'].fillna(x['Age'].mean())
# 2-3 查看数据
# x.info()
print(x.head(5))
# 分析 age需要处理 采用热编码
x = pd.get_dummies(x)
print(x.head(5))
x.drop('Sex_male', axis=1, inplace=True)
print(x.head(5))
# 拆分训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=24)
print(x_train.head(5))
# 是否需要特征工程
f = StandardScaler()
x_train = f.fit_transform(x_train)
x_test = f.transform(x_test)
# 4训练模型
model = DecisionTreeClassifier(criterion="gini")
model.fit(x_train, y_train)
y_pre = model.predict(x_test)
print(f"打印预测结果{y_pre}") # 0已故 1 活着
# 模型评估
print(f"准确率:{model.score(x_test, y_test)}")
print(f"精确率:{precision_score(y_test, y_pre)}")
print(f"召回率:{recall_score(y_test, y_pre)}")
print(f"F1:{f1_score(y_test, y_pre)}")
print(f"ROC_AUC:{roc_auc_score(y_test, y_pre)}")
print(f"分类报告{classification_report(y_test, y_pre, target_names=['Died', 'Survivor'])}")
# TODO 绘CART决策树图
# TODO 1设置画布大小
plt.figure(figsize=(50, 30))
# TODO 2.绘制决策树
# decision_tree:决策树模型 filled 填充颜色
# 注意: 可以提前设置层数 max_depth=15,达到预剪枝效果!!!
plot_tree(model, filled=True)
# TODO 3.保存图片
plt.savefig('data/cart.png')
# TODO 4.展示图片
plt.show()