待完成:
1、先看习题部分有什么问题,带着问题
2、整体过一遍,记录
3、各平台关于该 知识点 的教程
3、做习题,再次整理,补充。
问题:
1、各种决策树划分选择准则的特点、优缺点
2、数据集含冲突数据怎么办?
3、未剪枝、预剪枝、后剪枝决策树有什么区别和联系?
4、统计显著性检验是什么?
决策树的生成, 递归过程。
递归返回的三种情形:
1、当前结点包含的样本全属于同一类别,无需划分。
2、当前属性集为空,或是所有样本在所有属性上取值相同,无法划分。
3、当前结点包含的样本集合为空,不能划分。
如何选择最优划分属性。
目标:
信息熵(information entropy ): 度量 样本集合 纯度 最常用的 指标
样 本 集 合 D 中 第 k 类 样 本 所 占 的 比 例 为 p k ( k = 1 , 2 , 3 , . . ∣ Y ∣ ) 样本集合D中第k类样本所占的比例为p_k(k=1,2,3,..|\mathcal{Y}|) 样本集合D中第k类样本所占的比例为pk(k=1,2,3,..∣Y∣)
D D D的信息熵: E n t ( D ) = − ∑ k = 1 ∣ Y ∣ p k l o g 2 P k Ent(D)=-\sum\limits_{k=1}^{|\mathcal{Y}|}p_klog_2P_k Ent(D)=−k=1∑∣Y∣pklog2Pk
离 散 属 性 a 有 V 个 可 能 的 取 值 { a 1 , a 2 , . . . , a V } 离散属性a有V个可能的取值\left\{a^1,a^2,...,a^V\right\} 离散属性a有V个可能的取值{a1,a2,...,aV}
D v : 第 v 个 分 支 结 点 包 含 了 D 中 所 有 在 属 性 a 上 的 取 值 为 a v 的 样 本 D^v:第v个分支结点包含了D中所有在属性a上的取值为a^v的样本 Dv:第v个分支结点包含了D中所有在属性a上的取值为av的样本
样本数越多,分支结点的影响越大。
属 性 a 对 样 本 集 D 进 行 划 分 获 得 的 " 信 息 增 益 " : G a i n ( D , a ) = E n t ( D ) − ∑ v = 1 V ∣ D v ∣ ∣ D ∣ E n t ( D v ) 属性a对样本集D进行划分获得的"信息增益":Gain(D,a)=Ent(D)-\sum\limits_{v=1}^V\frac{|D^v|}{|D|}Ent(D^v) 属性a对样本集D进行划分获得的"信息增益":Gain(D,a)=Ent(D)−v=1∑V∣D∣∣Dv∣Ent(Dv)
将4.2 算法中第8行选择属性改为 a ∗ = arg max a ∈ A G a i n ( D , a ) a_*=\arg\max\limits_{a \in A}Gain(D, a) a∗=arga∈AmaxGain(D,a)
ID3 决策树算法
1、计算,选择第一个划分属性
划分:
2、进行第二层划分,以最左的子集为例:
同样计算各属性的信息增益
问题:信息增益准则对可选取数目多的属性有偏好。
C4.5决策树算法, 增益率
增益率(gain ratio):
G a i n _ r a t i o ( D , a ) = G a i n ( D , a ) I V ( a ) Gain\_ratio(D, a)=\frac{Gain(D, a)}{IV(a)} Gain_ratio(D,a)=IV(a)Gain(D,a)
I V ( a ) = − ∑ v = 1 V ∣ D v ∣ ∣ D ∣ l o g 2 ∣ D v ∣ ∣ D ∣ IV(a)=-\sum\limits_{v=1}^V\frac{|D^v|}{|D|}log_2\frac{|D^v|}{|D|} IV(a)=−v=1∑V∣D∣∣Dv∣log2∣D∣∣Dv∣, 属性a的固有值(intrinsic value)
增益率准则对 可取值数目较少的属性有所偏好。
CART(Classification and Regression Tree), 可用于分类和回归任务。
数据集 D D D的纯度可用基尼值来度量:
G i n i ( D ) = ∑ k = 1 ∣ Y ∣ ∑ k ′ ≠ k p k p k ′ = 1 − ∑ k = 1 ∣ Y ∣ p k 2 Gini(D)=\sum\limits_{k=1}^{|\mathcal{Y}|}\sum\limits_{k^{'}\neq k}p_kp_{k^{'}}=1-\sum\limits_{k=1}^{|\mathcal{Y}|}p_k^2 Gini(D)=k=1∑∣Y∣k′=k∑pkpk′=1−k=1∑∣Y∣pk2
G i n i ( D ) Gini(D) Gini(D)反映了从数据集 D D D中随机抽取两个样本,其类别不一致的概率。
G i n i ( D ) Gini(D) Gini(D)越小,数据集 D D D的纯度越高。
最优划分属性: 基尼指数小的。
决策树算法 对付 过拟合
过拟合: 把训练集自身的一些特点当作所有数据都具有的一般性质。
主动去掉一些分支, 降低过拟合的风险。
决策树剪枝的基本策略 | 特点 |
---|---|
预剪枝(prepruning) | 1、决策树生成过程中;2、结点划分前进行估计:若当前结点的划分不能带来决策树泛化性能的提升,停止划分。 |
后剪枝(postpruning) | 1、完整的决策树已生成;2、自底向上对非叶结点进行考察: 若将该结点对应的子树替换为叶结点能带来决策树泛化性能的提升,则将该子树替换为叶结点。 |
如何判断决策树泛化性能是否提升呢?
留出法
注: 类别标记为训练样例最多的类别。
1、对划分前后的泛化性能进行估计。
1、预剪枝使得决策树的很多分支都没有展开。
2、预剪枝基于"贪心"本质禁止分支展开,有欠拟合风险。
同样处理图4.5的决策树,其验证集精度为42.9%。
后剪枝:
1、考察结点⑥,训练集包含{7,15},替换成叶结点"好瓜", 再看验证集中{8,9}都将是好瓜。剪枝后,8号判断正确,精确度为4/7=51.7%。
2、考察结点⑤,训练集包括{6,7,15}, 替换成叶结点"好瓜",对验证集无影响,可以不剪枝。
3、考察结点②,训练集包括{1,2,3,14},替换成叶结点"好瓜",对验证集{4,13,5},相比于剪枝前,{5}将判定正确,此时验证集精度为5/7=71.4%,进行剪枝。
①②③④⑤⑥⑦⑧⑨⑩
后剪枝决策树通常比预剪枝决策树保留了更多的分支。
1、后剪枝决策树的欠拟合风险很小,泛化性能往往优于预剪枝决策树。
2、后剪枝过程是在生成完全决策树之后进行的,并且需要自底向上地对树中的所有非叶子结点进行逐一考察
决策树学习 使用 连续属性
连续属性离散化。
二分法
样 本 集 D 和 连 续 属 性 a , 假 定 a 在 D 上 出 现 了 n 个 不 同 的 取 值 , 样本集D和连续属性a,假定a在D上出现了n个不同的取值, 样本集D和连续属性a,假定a在D上出现了n个不同的取值,
将 这 些 值 进 行 从 小 到 大 的 排 序 , 记 为 { a 1 , a 2 , . . . , a n } 将这些值进行从小到大的排序,记为\left\{a^1,a^2,...,a^n\right\} 将这些值进行从小到大的排序,记为{a1,a2,...,an}
相 邻 的 属 性 取 值 a i 和 a i + 1 相邻的属性取值a^i和a^{i+1} 相邻的属性取值ai和ai+1
包含n-1个元素的候选划分点:
T a = { a i + a i + 1 2 ∣ 1 ≤ i ≤ n − 1 } T_a=\left\{\frac{a^i+a^{i+1}}{2}|1\le i\le n-1\right\} Ta={2ai+ai+1∣1≤i≤n−1}
像离散属性值一样考察这些划分点。
G a i n ( D , a ) = max t ∈ T a G a i n ( D , a , t ) = max t ∈ T a E n t ( D ) − ∑ λ ∈ { − , + } ∣ D t λ ∣ ∣ D ∣ E n t ( D t λ ) Gain(D,a)=\max\limits_{t\in T_a }Gain(D,a,t)=\max\limits_{t\in T_a }Ent(D)-\sum\limits_{\lambda\in\left\{-,+\right\}}\frac{|D_t^{\lambda}|}{|D|}Ent(D_t^{\lambda}) Gain(D,a)=t∈TamaxGain(D,a,t)=t∈TamaxEnt(D)−λ∈{−,+}∑∣D∣∣Dtλ∣Ent(Dtλ)
P85
诊测成本、隐私保护。
1、把每个属性视为坐标空间的一个坐标轴,则d个属性描述的样本就对应了d维空间中的一个数据点。
问题:
若是分类边界需要很多段划分,需要进行大量的属性测试,测试时间开销就会很大。
多变量决策树: 实现斜划分甚至更复杂划分的决策树。
决策树学习算法的三大代表: ID3, C4.5,CART
增量学习: 调整分支路径上的划分属性次序来对树进行重构。
CLS(Concept Learning System)
4.1 试证明对于不含冲突数据(即特征向量完全相同但标记不同)的训练集,必存在与训练集一致(即训练误差为0)的决策树。
4.2 试析使用"最小训练误差"作为决策树划分选择准则的缺陷。
4.3 试编程实现基于信息熵进行划分选择的决策树算法,并为表4.3中的树生成一棵决策树。
4.4 试编程实现基于基尼指数进行划分选择的决策树算法算法,为表4.2中数据生成预剪枝、后剪枝决策树,并与未剪枝决策树进行比较。
4.5 试编程实现基于对率回归进行划分选择的决策树算法,并为表4.3中数据生成一棵决策树。
4.6 试选择4个UCI数据集,对上述3种算法所产生的未剪枝、预剪枝、后剪枝决策树实验进行比较,并进行适当的统计显著性检验。
4.7 图4.2 是一个递归算法,若面临巨量数据,则决策树的层数会很深,使用递归方法易导致“栈”溢出。试使用“队列”数据结构,以参数 M a x D e p t h MaxDepth MaxDepth控制树的最大深度,写出与图4.2等价、但不使用递归的决策树算法。
4.8 试将决策树生成的深度优先搜索过程修改为广度优先搜索,以参数 M a x N o d e MaxNode MaxNode控制树的最大结点数,将题4.7中基于队列的决策树算法进行改写,对比题4.7中的算法,试析哪种方式更易于控制决策树所需存储不超过内存。
4.9 试将4.2.2节对缺失值的处理机制推广到基尼指数的计算当中去。
4.10 从网上下载或自己编程实现任意一种多变量决策树算法,并观察其在西瓜数据集3.0上产生的结果。
天池课程链接_决策树分类
金融风控,医疗辅助诊断
基于树结构对数据进行划分
优点:
1、解释性好
2、可以发现特征的重要程度
3、模型的计算复杂度较低
缺点:
1、模型易过拟合,需剪枝
2、预测能力有限
3、方差较高,数据分布的轻微改变很容易造成树结构完全不同。
以决策树作为基模型的集成模型:
1、梯度提升树(GBDT)
2 、XGBoost
3、LightGBM
广告计算、CTR(点击通过率)预测、金融风控。
流程:
1、库函数导入
2、模型训练
3、数据和模型可视化
4、模型预测
"""
Step1: 库函数导入
"""
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns ## 可视化库,是对matplotlib进行二次封装而成
## 导入 决策树模型函数
from sklearn.tree import DecisionTreeClassifier
from sklearn import tree
"""
Step2: 训练模型
"""
## 构造数据集
x_fearures = np.array([[-1, -2], [-2, -1], [-3, -2], [1, 3], [2, 1], [3, 2]])
y_label = np.array([0, 1, 0, 1, 0, 1])
## 调用决策树回归模型
tree_clf = DecisionTreeClassifier()
## 调用决策树模型拟合构造的数据集
tree_clf = tree_clf.fit(x_fearures, y_label)
"""
Step3: 数据和模型可视化
"""
## 可视化构造的数据样本点
plt.figure()
plt.scatter(x_fearures[:,0],x_fearures[:,1], c=y_label, s=50, cmap='viridis')
plt.title('Dataset')
plt.show()
## 可视化决策树
import graphviz
dot_data = tree.export_graphviz(tree_clf, out_file=None)
graph = graphviz.Source(dot_data)
graph.render("pengunis")
有一个报错:关于Graphviz,解决链接
"""
Step4: 模型预测
"""
## 创建新样本
x_fearures_new1 = np.array([[0, -1]])
x_fearures_new2 = np.array([[2, 1]])
## 在训练集和测试集上分布利用训练好的模型进行预测
y_label_new1_predict = tree_clf.predict(x_fearures_new1)
y_label_new2_predict = tree_clf.predict(x_fearures_new2)
print('The New point 1 predict class:\n',y_label_new1_predict)
print('The New point 2 predict class:\n',y_label_new2_predict)
import graphviz
graphviz.__version__
流程:
1、库函数导入
2、数据读取/载入
3、数据信息简单查看
4、可视化描述
5、利用 决策树模型 在二分类 上进行预测和训练
6、利用 决策树 模型 在三分类(多分类) 上进行 训练和预测
#下载需要用到的数据集
# !wget https://tianchi-media.oss-cn-beijing.aliyuncs.com/DSW/6tree/penguins_raw.csv
#################### 报错
## 需要先 pip install wget
"""
在Jupyter Notebook使用
"""
import wget
wget.download('https://tianchi-media.oss-cn-beijing.aliyuncs.com/DSW/6tree/penguins_raw.csv', 'penguins_raw.csv')
"""
Step1: 库函数导入
"""
## 基础函数库
import numpy as np
import pandas as pd
## 绘图函数库
import matplotlib.pyplot as plt
import seaborn as sns
"""
Step2: 数据读取/载入
"""
## 利用Pandas自带的read_csv函数读取并转化为DataFrame格式
data = pd.read_csv('./penguins_raw.csv')
## 为了方便,仅选取四个简单的特征
data = data[['Species','Culmen Length (mm)','Culmen Depth (mm)',
'Flipper Length (mm)','Body Mass (g)']]
"""
Step3: 数据信息简单查看
"""
## 利用.info()查看数据的整体信息
# data.info()
# data.head() ## 看前5条 信息 , 这里发现存在缺失值 NaN ,填补方法: 补-1, 中位数填补、平均数填补
data.tail() ## 看最后五条 信息
# data['Species'].unique() ## 其对应的类别标签为'Adelie Penguin', 'Gentoo penguin', 'Chinstrap penguin'三种不同企鹅的类别。
# pd.Series(data['Species']).value_counts() ## 利用value_counts函数查看每个类别数量
data.describe() ## 对于特征进行一些统计描述
## 用-1填补缺失值
data = data.fillna(-1)
"""
Step4: 可视化描述
"""
## 特征与标签组合的散点可视化
sns.pairplot(data=data, diag_kind='hist', hue= 'Species')
plt.show()
从上图可以发现,在2D情况下不同的特征组合对于不同类别的企鹅的散点分布,以及大概的区分能力。Culmen Lenth(第1行和第1列)与其他特征的组合散点的重合较少,所以对于数据集的划分能力最好。
'''为了方便我们将标签转化为数字
'Adelie Penguin (Pygoscelis adeliae)' ------0
'Gentoo penguin (Pygoscelis papua)' ------1
'Chinstrap penguin (Pygoscelis antarctica) ------2 '''
def trans(x):
if x == data['Species'].unique()[0]:
return 0
if x == data['Species'].unique()[1]:
return 1
if x == data['Species'].unique()[2]:
return 2
data['Species'] = data['Species'].apply(trans)
for col in data.columns:
if col != 'Species':
sns.boxplot(x='Species', y=col, saturation=0.5, palette='pastel', data=data)
plt.title(col)
plt.show()
# 选取其前三个特征绘制三维散点图
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(10,8))
ax = fig.add_subplot(111, projection='3d')
data_class0 = data[data['Species']==0].values
data_class1 = data[data['Species']==1].values
data_class2 = data[data['Species']==2].values
# 'setosa'(0), 'versicolor'(1), 'virginica'(2)
ax.scatter(data_class0[:,0], data_class0[:,1], data_class0[:,2],label=data['Species'].unique()[0])
ax.scatter(data_class1[:,0], data_class1[:,1], data_class1[:,2],label=data['Species'].unique()[1])
ax.scatter(data_class2[:,0], data_class2[:,1], data_class2[:,2],label=data['Species'].unique()[2])
plt.legend()
plt.show()
## 为了正确评估模型性能,将数据划分为训练集和测试集,并在训练集上训练模型,在测试集上验证模型性能。
from sklearn.model_selection import train_test_split
## 选择其类别为0和1的样本 (不包括类别为2的样本)
data_target_part = data[data['Species'].isin([0,1])][['Species']]
data_features_part = data[data['Species'].isin([0,1])][['Culmen Length (mm)','Culmen Depth (mm)',
'Flipper Length (mm)','Body Mass (g)']]
## 测试集大小为20%, 80%/20%分
x_train, x_test, y_train, y_test = train_test_split(data_features_part, data_target_part, test_size = 0.2, random_state = 2020)
## 从sklearn中导入决策树模型
from sklearn.tree import DecisionTreeClassifier
from sklearn import tree
## 定义 决策树模型
clf = DecisionTreeClassifier(criterion='entropy')
# 在训练集上训练决策树模型
clf.fit(x_train, y_train)
## 可视化
import graphviz
dot_data = tree.export_graphviz(clf, out_file=None)
graph = graphviz.Source(dot_data)
graph.render("penguins")
## 在训练集和测试集上分布利用训练好的模型进行预测
train_predict = clf.predict(x_train)
test_predict = clf.predict(x_test)
from sklearn import metrics
## 利用accuracy(准确度)【预测正确的样本数目占总预测样本数目的比例】评估模型效果
print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_train,train_predict))
print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_test,test_predict))
## 查看混淆矩阵 (预测值和真实值的各类情况统计矩阵)
confusion_matrix_result = metrics.confusion_matrix(test_predict,y_test)
print('The confusion matrix result:\n',confusion_matrix_result)
# 利用热力图对于结果进行可视化
plt.figure(figsize=(8, 6))
sns.heatmap(confusion_matrix_result, annot=True, cmap='Blues')
plt.xlabel('Predicted labels')
plt.ylabel('True labels')
plt.show()
## 测试集大小为20%, 80%/20%分
x_train, x_test, y_train, y_test = train_test_split(data[['Culmen Length (mm)','Culmen Depth (mm)',
'Flipper Length (mm)','Body Mass (g)']], data[['Species']], test_size = 0.2, random_state = 2020)
## 定义 决策树模型
clf = DecisionTreeClassifier()
# 在训练集上训练决策树模型
clf.fit(x_train, y_train)
## 在训练集和测试集上分布利用训练好的模型进行预测
train_predict = clf.predict(x_train)
test_predict = clf.predict(x_test)
## 由于决策树模型是概率预测模型(前文介绍的 p = p(y=1|x,\theta)),所有我们可以利用 predict_proba 函数预测其概率
train_predict_proba = clf.predict_proba(x_train)
test_predict_proba = clf.predict_proba(x_test)
print('The test predict Probability of each class:\n',test_predict_proba)
## 其中第一列代表预测为0类的概率,第二列代表预测为1类的概率,第三列代表预测为2类的概率。
## 利用accuracy(准确度)【预测正确的样本数目占总预测样本数目的比例】评估模型效果
print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_train,train_predict))
print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_test,test_predict))
## 查看混淆矩阵
confusion_matrix_result = metrics.confusion_matrix(test_predict,y_test)
print('The confusion matrix result:\n',confusion_matrix_result)
# 利用热力图对于结果进行可视化
plt.figure(figsize=(8, 6))
sns.heatmap(confusion_matrix_result, annot=True, cmap='Blues')
plt.xlabel('Predicted labels')
plt.ylabel('True labels')
plt.show()
英文文档:https://scikit-learn.org/stable/modules/tree.html
中文文档:https://www.sklearncn.cn/11/
可用于分类与回归, 无参 监督学习
从数据特征中 学习决策规则 预测目标变量的值。
优势:
1、便于理解和解释。 树的结构可以可视化。
2、训练需要的数据少。但不支持缺失值
3、训练模型的时间复杂度是 参与训练的数据点对数 的数量。
4、能够处理数值型数据和分类数据。
缺点:
1、容易过拟合,导致泛化性能差。
2、数据中的 微小变化可能会导致完全不同的树。
3、拟合前先对数据进行平衡
简单分类:
"""
决策树——简单分类
"""
from sklearn import tree
X = [[0, 0], [1, 1]]
Y = [0, 1]
clf = tree.DecisionTreeClassifier()
clf = clf.fit(X, Y)
## 预测类别和概率
print(clf.predict([[2., 2.]]))
print(clf.predict_proba([[2., 2.]]))
"""
决策树——多分类
"""
from sklearn.datasets import load_iris
from sklearn import tree
iris = load_iris()
clf = tree.DecisionTreeClassifier()
clf = clf.fit(iris.data, iris.target)
import graphviz ## 可视化决策树
dot_data = tree.export_graphviz(clf, out_file=None)
graph = graphviz.Source(dot_data)
graph.render("iris")
"""
美化决策树_Jupyter Notebook
"""
dot_data = tree.export_graphviz(clf, out_file=None,
feature_names=iris.feature_names,
class_names=iris.target_names,
filled=True, rounded=True,
special_characters=True)
graph = graphviz.Source(dot_data)
graph.render("iris2") ## 到文件目录里找 d对应的pdf文件
graph
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import export_text
iris = load_iris()
decision_tree = DecisionTreeClassifier(random_state=0, max_depth=2)
decision_tree = decision_tree.fit(iris.data, iris.target)
r = export_text(decision_tree, feature_names=iris['feature_names'])
print(r)
可能需要更新版本:
pip install -U scikit-learn
from sklearn.datasets import load_iris
iris = load_iris()
"""
所有特征对 决策函数
"""
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.inspection import DecisionBoundaryDisplay
# Parameters
n_classes = 3
plot_colors = "ryb"
plot_step = 0.02
for pairidx, pair in enumerate([[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3]]):
# We only take the two corresponding features
X = iris.data[:, pair]
y = iris.target
# Train
clf = DecisionTreeClassifier().fit(X, y)
# Plot the decision boundary
ax = plt.subplot(2, 3, pairidx + 1)
plt.tight_layout(h_pad=0.5, w_pad=0.5, pad=2.5)
DecisionBoundaryDisplay.from_estimator(
clf,
X,
cmap=plt.cm.RdYlBu,
response_method="predict",
ax=ax,
xlabel=iris.feature_names[pair[0]],
ylabel=iris.feature_names[pair[1]],
)
# Plot the training points
for i, color in zip(range(n_classes), plot_colors):
idx = np.where(y == i)
plt.scatter(
X[idx, 0],
X[idx, 1],
c=color,
label=iris.target_names[i],
cmap=plt.cm.RdYlBu,
edgecolor="black",
s=15,
)
plt.suptitle("Decision surface of decision trees trained on pairs of features")
plt.legend(loc="lower right", borderpad=0, handletextpad=0)
_ = plt.axis("tight")
"""
决策树 可视化
"""
from sklearn.tree import plot_tree
plt.figure()
clf = DecisionTreeClassifier().fit(iris.data, iris.target)
plot_tree(clf, filled=True)
plt.title("Decision tree trained on all the iris features")
plt.show()
from sklearn import tree
X = [[0, 0], [2, 2]]
y = [0.5, 2.5]
clf = tree.DecisionTreeRegressor()
clf = clf.fit(X, y)
clf.predict([[1, 1]])
# Import the necessary modules and libraries
import numpy as np
from sklearn.tree import DecisionTreeRegressor
import matplotlib.pyplot as plt
# Create a random dataset
rng = np.random.RandomState(1)
X = np.sort(5 * rng.rand(80, 1), axis=0)
y = np.sin(X).ravel()
y[::5] += 3 * (0.5 - rng.rand(16))
# Fit regression model
regr_1 = DecisionTreeRegressor(max_depth=2)
regr_2 = DecisionTreeRegressor(max_depth=5)
regr_1.fit(X, y)
regr_2.fit(X, y)
# Predict
X_test = np.arange(0.0, 5.0, 0.01)[:, np.newaxis]
y_1 = regr_1.predict(X_test)
y_2 = regr_2.predict(X_test)
# Plot the results
plt.figure()
plt.scatter(X, y, s=20, edgecolor="black", c="darkorange", label="data")
plt.plot(X_test, y_1, color="cornflowerblue", label="max_depth=2", linewidth=2)
plt.plot(X_test, y_2, color="yellowgreen", label="max_depth=5", linewidth=2)
plt.xlabel("data")
plt.ylabel("target")
plt.title("Decision Tree Regression")
plt.legend()
plt.show()
多输出问题: 有多个输出需要预测。
输出之间没有相关性: 构建n个独立的模型
与同一输入相关的输出值可能是相关的: 构建能够同时预测所有N输出的单个模型。
"""
决策树 多输出回归 示例
输入X: 单个实数值
输出Y: X 的正弦和余弦
"""
import numpy as np
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeRegressor
# Create a random dataset
rng = np.random.RandomState(1)
X = np.sort(200 * rng.rand(100, 1) - 100, axis=0)
y = np.array([np.pi * np.sin(X).ravel(), np.pi * np.cos(X).ravel()]).T
y[::5, :] += 0.5 - rng.rand(20, 2)
# Fit regression model
regr_1 = DecisionTreeRegressor(max_depth=2)
regr_2 = DecisionTreeRegressor(max_depth=5)
regr_3 = DecisionTreeRegressor(max_depth=8)
regr_1.fit(X, y)
regr_2.fit(X, y)
regr_3.fit(X, y)
# Predict
X_test = np.arange(-100.0, 100.0, 0.01)[:, np.newaxis]
y_1 = regr_1.predict(X_test)
y_2 = regr_2.predict(X_test)
y_3 = regr_3.predict(X_test)
# Plot the results
plt.figure()
s = 25
plt.scatter(y[:, 0], y[:, 1], c="navy", s=s, edgecolor="black", label="data")
plt.scatter(
y_1[:, 0],
y_1[:, 1],
c="cornflowerblue",
s=s,
edgecolor="black",
label="max_depth=2",
)
plt.scatter(y_2[:, 0], y_2[:, 1], c="red", s=s, edgecolor="black", label="max_depth=5")
plt.scatter(
y_3[:, 0], y_3[:, 1], c="orange", s=s, edgecolor="black", label="max_depth=8"
)
plt.xlim([-6, 6])
plt.ylim([-6, 6])
plt.xlabel("target 1")
plt.ylabel("target 2")
plt.title("Multi-output Decision Tree Regression")
plt.legend(loc="best")
plt.show()
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_olivetti_faces
from sklearn.utils.validation import check_random_state
from sklearn.ensemble import ExtraTreesRegressor
from sklearn.neighbors import KNeighborsRegressor
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import RidgeCV
# Load the faces datasets
data, targets = fetch_olivetti_faces(return_X_y=True)
train = data[targets < 30]
test = data[targets >= 30] # Test on independent people
# Test on a subset of people
n_faces = 5
rng = check_random_state(4)
face_ids = rng.randint(test.shape[0], size=(n_faces,))
test = test[face_ids, :]
n_pixels = data.shape[1]
# Upper half of the faces
X_train = train[:, : (n_pixels + 1) // 2]
# Lower half of the faces
y_train = train[:, n_pixels // 2 :]
X_test = test[:, : (n_pixels + 1) // 2]
y_test = test[:, n_pixels // 2 :]
# Fit estimators
ESTIMATORS = {
"Extra trees": ExtraTreesRegressor(
n_estimators=10, max_features=32, random_state=0
),
"K-nn": KNeighborsRegressor(),
"Linear regression": LinearRegression(),
"Ridge": RidgeCV(),
}
y_test_predict = dict()
for name, estimator in ESTIMATORS.items():
estimator.fit(X_train, y_train)
y_test_predict[name] = estimator.predict(X_test)
# Plot the completed faces
image_shape = (64, 64)
n_cols = 1 + len(ESTIMATORS)
plt.figure(figsize=(2.0 * n_cols, 2.26 * n_faces))
plt.suptitle("Face completion with multi-output estimators", size=16)
for i in range(n_faces):
true_face = np.hstack((X_test[i], y_test[i]))
if i:
sub = plt.subplot(n_faces, n_cols, i * n_cols + 1)
else:
sub = plt.subplot(n_faces, n_cols, i * n_cols + 1, title="true faces")
sub.axis("off")
sub.imshow(
true_face.reshape(image_shape), cmap=plt.cm.gray, interpolation="nearest"
)
for j, est in enumerate(sorted(ESTIMATORS)):
completed_face = np.hstack((X_test[i], y_test_predict[est][i]))
if i:
sub = plt.subplot(n_faces, n_cols, i * n_cols + 2 + j)
else:
sub = plt.subplot(n_faces, n_cols, i * n_cols + 2 + j, title=est)
sub.axis("off")
sub.imshow(
completed_face.reshape(image_shape),
cmap=plt.cm.gray,
interpolation="nearest",
)
plt.show()
输入X是面的上半部分的像素,并且输出Y是这些面的下半部分的像素。
论文:M. Dumont et al, Fast multi-class image annotation with random subwindows and multiple output randomized trees, International Conference on Computer Vision Theory and Applications 2009
1、合适的样本比例和特征数量。
2、事先进行降维(PCA, ICA)
3、使用 max_depth=3 作为初始树深度,让决策树知道如何适应您的数据,然后再增加树的深度。
4、使用 max_depth 来控制输的大小防止过拟合。
5、尝试 min_samples_leaf=5 作为初始值。如果样本的变化量很大,可以使用浮点数作为这两个参数中的百分比。两者之间的主要区别在于 min_samples_leaf 保证叶结点中最少的采样数,而 min_samples_split 可以创建任意小的叶子,尽管在文献中 min_samples_split 更常见。
6、训练之前平衡数据集
7、如果输入的矩阵X为稀疏矩阵,建议您在调用fit之前将矩阵X转换为稀疏的csc_matrix ,在调用predict之前将 csr_matrix 稀疏。当特征在大多数样本中具有零值时,与密集矩阵相比,稀疏矩阵输入的训练时间可以快几个数量级。
1、ID3(Iterative Dichotomiser 3)由 Ross Quinlan 在1986年提出。该算法创建一个多路树,找到每个节点(即以贪心的方式)分类特征,这将产生分类目标的最大信息增益。决策树发展到其最大尺寸,然后通常利用剪枝来提高树对未知数据的泛化能力。
4、CART 使用在每个节点产生最大信息增益的特征和阈值来构造二叉树。
scikit-learn 使用 CART 算法的优化版本。
后剪枝一些参考资料