Udacity机器学习入门笔记3-决策树
1 sklearn 决策树
决策树(DTS)是一种非参数监督学习用于方法分类和回归。我们的目标是创建一个预测通过学习从数据推断出功能简单的决策规则的目标变量的值的模型。
决策树的一些优点是:
- 简单的理解和解释。树可视化。
- 只需要很少的数据准备。其它技术通常需要数据标准化,创建虚拟变量,去除空白值。但是请注意,这个模块不支持缺失值。
- 使用树的成本(即,预测的数据)是在用于训练树数据点的数目的对数。
- 能够同时处理数字和分类数据。其他技术通常专门分析仅具有一种类型的变量的数据集。见算法以获取更多信息
- 能够处理多输出的问题。
- 采用了白色盒子模型。如果给定的情况是在一个模型中观察到的,对于条件的说明很容易通过布尔逻辑说明。相比之下,在一个黑盒子模型(例如,在人工神经网络),结果可能会更难以解释。
- 可能采用的统计测试,以验证模型。这使得它可能占模型的可靠性。
- 执行好,即使它的假设一定程度上被从其中产生的数据的真实模型侵犯。
决策树的缺点包括:
- 决策树学习者可能创建过于复杂的树并且泛化性不好。这就是所谓的过度拟合。修剪机制(目前尚不支持),设置在叶节点所需的样本的最小数目或设置树的最大深度是必要的,以避免此问题。
- 决策树可能是不稳定的,因为数据的微小变化可能会导致产生一个完全不同的树。这个问题可以通过使用整体内决策树缓解。
- 获得的最佳决策树的问题是众所周知的NP完全问题。因此,实际的决策树学习算法都基于启发式算法如贪心算法,其中局部最优决策是在每个节点做出。这种算法不能保证返回全局最优决策树。这可以通过在集合学习训练多个树来减轻,其中所述特征与样本被随机地与更换采样。
- 有些概念很难学习,因为决策树不容易表达出来,如异或,奇偶校验或多路复用器的问题。
- 决策树学习者会高偏差的树,如果一些类占据主导地位。因此,建议在使用决策树之前,进行数据平衡。
1.1 数学表示
已知训练向量
x
i
∈
R
n
,
i
=
1
,
…
,
1
x_{i} \in R^{n}, i=1, \dots, 1
xi∈Rn,i=1,…,1和标签向量
y
∈
R
l
y \in R^{l}
y∈Rl ,决策树迭代式地把空间分为拥有相同标签数据的集合。
设
Q
Q
Q表示在节点
m
m
m的数据。每一个候补的分割
θ
=
(
j
,
t
m
)
\theta=\left(j, t_{m}\right)
θ=(j,tm),它包含了一个特征
j
j
j 和阀值
t
m
t_m
tm,把数据划分为为两个子集
Q
left
(
θ
)
Q_{\text {left}}(\theta)
Qleft(θ)和
Q
right
(
θ
)
Q_{\text {right}}(\theta)
Qright(θ)
Q
left
(
θ
)
=
(
x
,
y
)
∣
x
j
<
=
t
m
Q
right
(
θ
)
=
Q
\
Q
left
(
θ
)
\begin{array}{l}{Q_{\text {left}}(\theta)=(x, y) | x_{j}<=t_{m}} \\ {Q_{\text {right}}(\theta)=Q \backslash Q_{\text {left}}(\theta)}\end{array}
Qleft(θ)=(x,y)∣xj<=tmQright(θ)=Q\Qleft(θ)
节点
m
m
m杂质度有函数
H
(
)
H()
H()计算,公式的选择有任务的类型决定(分类和回归)
G
(
Q
,
θ
)
=
n
l
e
f
t
N
m
H
(
Q
l
e
f
t
(
θ
)
)
+
n
r
i
g
h
t
N
m
H
(
Q
r
i
g
h
t
(
θ
)
)
G(Q, \theta)=\frac{n_{l e f t}}{N_{m}} H\left(Q_{l e f t}(\theta)\right)+\frac{n_{r i g h t}}{N_{m}} H\left(Q_{r i g h t}(\theta)\right)
G(Q,θ)=NmnleftH(Qleft(θ))+NmnrightH(Qright(θ))
选择合适的分割,最小化杂质度
θ
∗
=
argmin
θ
G
(
Q
,
θ
)
\theta^{*}=\operatorname{argmin}_{\theta} G(Q, \theta)
θ∗=argminθG(Q,θ)
递归去获得子集
Q
left
(
θ
∗
)
Q_{\text {left}}(\theta^*)
Qleft(θ∗)和
Q
right
(
θ
∗
)
Q_{\text {right}}(\theta^*)
Qright(θ∗)直到到达最大的深度,或者
N
m
<
m
i
n
samples
N_{m}<\mathrm{min}_{\text {samples}}
Nm<minsamples或者
N
m
=
1
N_{m}=1
Nm=1
1.1.1 分类标准
假设一个分类结果输出
0
,
1
,
…
,
K
−
1
0,1, \ldots, \mathrm{K}-1
0,1,…,K−1,节点
m
m
m,由一个带有
N
m
N_{m}
Nm个观测值的
R
m
R_{m}
Rm区域表示,并且
p
m
k
=
1
/
N
m
∑
x
i
∈
R
m
I
(
y
i
=
k
)
p_{m k}=1 / N_{m} \sum_{x_{i} \in R_{m}} I\left(y_{i}=k\right)
pmk=1/Nmxi∈Rm∑I(yi=k)
p
m
k
p_{m k}
pmk表示属于类别
k
k
k的样本在节点
m
m
m中的比例
一般杂质度的计算方式是Gini
H
(
X
m
)
=
∑
k
p
m
k
(
1
−
p
m
k
)
H\left(X_{m}\right)=\sum_{k} p_{m k}\left(1-p_{m k}\right)
H(Xm)=k∑pmk(1−pmk)
熵:
H
(
X
m
)
=
−
∑
k
p
m
k
log
(
p
m
k
)
H\left(X_{m}\right)=-\sum_{k} p_{m k} \log \left(p_{m k}\right)
H(Xm)=−k∑pmklog(pmk)
和错误分类:
H
(
X
m
)
=
1
−
max
(
p
m
k
)
H\left(X_{m}\right)=1-\max \left(p_{m k}\right)
H(Xm)=1−max(pmk)
1.1.2 回归标准
如果目标是一个连续的值,则节点
m
m
m,表示拥有
N
m
N_m
Nm个观察的区域
R
m
R_m
Rm,最优化分割位置的通用标准是均方误差(使用平均值最小化的L2误差)和平均绝对误差(使用中值最小化的L1误差)
均方误差:
y
‾
m
=
1
N
m
∑
i
∈
N
m
y
i
H
(
X
m
)
=
1
N
m
∑
i
∈
N
m
(
y
i
−
y
‾
m
)
2
\begin{array}{c}{\overline{y}_{m}=\frac{1}{N_{m}} \sum_{i \in N_{m}} y_{i}} \\ {H\left(X_{m}\right)=\frac{1}{N_{m}} \sum_{i \in N_{m}}\left(y_{i}-\overline{y}_{m}\right)^{2}}\end{array}
ym=Nm1∑i∈NmyiH(Xm)=Nm1∑i∈Nm(yi−ym)2
平均绝对误差:
y
‾
m
=
1
N
m
∑
i
∈
N
m
y
i
H
(
X
m
)
=
1
N
m
∑
i
∈
N
m
∣
y
i
−
y
‾
m
∣
\begin{array}{c}{\overline{y}_{m}=\frac{1}{N_{m}} \sum_{i \in N_{m}} y_{i}} \\ {H\left(X_{m}\right)=\frac{1}{N_{m}} \sum_{i \in N_{m}}\left|y_{i}-\overline{y}_{m}\right|}\end{array}
ym=Nm1∑i∈NmyiH(Xm)=Nm1∑i∈Nm∣yi−ym∣
其中
X
m
X_{m}
Xm表示节点
m
m
m中的训练数据
1.2 分类
DecisionTreeClassifier是一个能够对数据集进行多类分类的一个工具类。
输入1:数列X,装训练数据,[n_samples, n_features]
输入2:数列Y,装训练标签,[n_samples]
>>> from sklearn import tree
>>> X = [[0, 0], [1, 1]]
>>> Y = [0, 1]
>>> clf = tree.DecisionTreeClassifier()
>>> clf = clf.fit(X, Y)
拟合后,进行预测
>>> clf.predict([[2., 2.]])
array([1])
还可以预测每类的概率
>>> clf.predict_proba([[2., 2.]])
array([[0., 1.]])
DecisionTreeClassifier 能够二进制的(其中标记物是[-1,1])分类和多类(其中标记物是[0,…,K-1])的分类。
使用Iris数据集构建决策树
>>> from sklearn.datasets import load_iris
>>> from sklearn import tree
>>> iris = load_iris()
>>> clf = tree.DecisionTreeClassifier()
>>> clf = clf.fit(iris.data, iris.target)
经过训练后,我们可以使用export_graphviz 导出Graphviz格式的决策树。
graphviz 安装,在conda环境中:
conda install python-graphviz
python环境下安装
pypi with pip install graphviz
例子,图输出到iris.pdf
>>> import graphviz
>>> dot_data = tree.export_graphviz(clf, out_file=None)
>>> graph = graphviz.Source(dot_data)
>>> graph.render("iris")
1.3 回归
决策树也可以使用 DecisionTreeRegressor适用于回归问题
输入与分类方法类似,只是标签可以是float,而分类是integer
>>> 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]])
array([0.5])
1.4 多输出问题
多输出问题就是说需要预测多个输出,标签
Y
Y
Y是2D数列,[n_samples, n_outputs]。
当在输出端之间没有相关性,一个非常简单的方法来解决这类问题是建立n个独立的模型,即,一个用于每个输出,然后使用这些模型来独立地预测n个输出端中的每一个。然而,很有可能它是相同的输入相关,更好的方式是建立能够同时预测所有n个输出端的一个单一的模式。首先,训练时间短,因为只有一个单一估计模型。其次,将所得估计的泛化精度通常会增加。
对于决策树,这种策略可以很容易地被用来支持多输出的问题。这需要以下变化:
- 叶节点存储多输出而不是一个
- 使用分割标准计算所有N个输出的平均减少。
该模块通过实现DecisionTreeClassifier和 DecisionTreeRegressor提供了多路输出问题的支持。如果判决树输出数组Y:[n_samples, n_outputs],最终的结果:
输出n_output通过predict;
通过predict_proba输出n_output阵列的概率列表。
2 udacity mini-project
### your code goes here ###
from sklearn import tree
clf = tree.DecisionTreeClassifier(min_samples_split=40)
t0 = time()
#print len(features_train[0])
clf.fit(features_train,labels_train)
print "training time:", round(time()-t0,3),"s"
t0 = time()
pred =clf.predict(features_test)
print "predict time:", round(time()-t0,3),"s"
from sklearn.metrics import accuracy_score
accuracy = accuracy_score(labels_test,pred)
print accuracy