1、决策树模型
1.1 什么是树
顾名思义和现实中的树类似,一般可以这样表示
一般由三个部分组成
根节点,如上图的1分支节点,如上图 2,4叶子节点,如上图 5,6,3,7,8
树是数据结构里的一个知识点,这里不过多赘述,更多内容请自行搜索。
1.2 决策树
从根节点开始一步一步走到叶子节点(根据决策选择走哪一个分叉)
所有数据最终都会落到叶子节点,所有分支节点上都是决策逻辑,例如下图的 age < 15,is male?
下图的例子可以看作筛选家人中爱玩游戏的人
决策树既可以做分类也可以做回归
1.3、决策树的组成
根节点:第一个选择点分支节点:中间过程,决策的逻辑叶子节点:最终的决策结果
2、决策树的训练与测试
训练阶段:从给定的训练集构造出来一棵树(从跟节点开始选择特征,如何进行特征切分)测试阶段:根据构造出来的树模型从上到下去走一遍就好了
一旦构造好了决策树,那么分类或者预测任务就很简单了,只需要走一遍就可以了,那么难点就在于如何构造出来一颗树,这就没那么容易了,需要考虑的问题还有很多的!
3、如何切分特征
也可以叫做如何选择节点,根节点的选择用哪个特征?如何切分数据呢?分支节点要用什么特征?
我们的目标应该是根节点就像老大一样能够更好吧的切分数据(分类的效果更好),根节点下面的节点自然就是老二。
目标:通过一种衡量标准,来计算通过不同特征进行分支选择后的分类情况,找出来最好的那个当成根节点,以此类推。
4、衡量标准----熵
4.1 含义
熵是表示随机变量不确定性的度量。
说人话就是一个系统的混乱程度,比如超市会卖各种各样的东西,所以就比较混乱,专卖店里只卖一个牌子的东西自然比较稳定
4.2 公式
H
(
X
)
=
−
∑
p
i
∗
l
o
g
p
i
,
i
=
1
,
2
,
3
,
.
.
.
,
n
H(X) = - \sum p_i * log p_i , i = 1,2,3,...,n
H(X)=−∑pi∗logpi,i=1,2,3,...,n
4.3 例子
现在有两个集合
A
集合【
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
2
,
2
】
A集合【1,1,1,1,1,1,1,1,2,2】
A集合【1,1,1,1,1,1,1,1,2,2】
B
集合【
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
1
】
B集合【1,2,3,4,5,6,7,8,9,1】
B集合【1,2,3,4,5,6,7,8,9,1】
显然
A
A
A集合的熵值要低,因为
A
A
A里面只有两种类别,相对稳定一些而
B
B
B中类别太多了,熵值就会大很多。
在分类任务中我们希望通过节点分支后数据类别的熵值越小越好,熵值小,也就是分的越开,越符合我们的要求。
4.4 信息增益
如何决策一个节点的选择呢?这里使用的是信息增益。
信息增益:表示特征X使得类Y的不确定性减少的程度。也就是说在某个条件下,不确定性减少的程度。
5、决策树构造实例
说了那么多概念,接下来通过一个例子深入了解决策树
数据是
14
14
14天打球的情况,特征是
4
4
4种环境的变化
根据
4
4
4种特征,我们有如下划分
那么我们可以根据信息增益来确定谁当根节点
在历史数据中(
14
14
14天)有
9
9
9天打球,
5
5
5天不打球,所以此时的熵应为:
−
9
14
l
o
g
2
9
14
−
5
14
l
o
g
2
5
14
=
0.940
- \frac{9}{14} log_2 \frac{9}{14} - \frac{5}{14} log_2 \frac{5}{14} = 0.940
−149log2149−145log2145=0.940
基于天气划分的信息增益如下计算
o
u
t
l
o
o
k
=
s
u
n
n
y
outlook = sunny
outlook=sunny 时,熵值为
0.971
0.971
0.971
o
u
t
l
o
o
k
=
o
v
e
r
c
a
s
t
outlook = overcast
outlook=overcast 时,熵值为
0
0
0
o
u
t
l
o
o
k
=
r
a
i
n
y
outlook = rainy
outlook=rainy 时,熵值为
0.971
0.971
0.971
根据数据统计,
o
u
t
l
o
o
k
outlook
outlook取值分别为
s
u
n
n
y
,
o
v
e
r
c
a
s
t
,
r
a
i
n
y
sunny,overcast,rainy
sunny,overcast,rainy的概率分别为:
5
14
\frac{5}{14}
145,
4
14
\frac{4}{14}
144,
5
14
\frac{5}{14}
145
熵值计算:
5
14
∗
0.971
+
4
14
∗
0
+
5
14
∗
0.971
=
0.693
\frac{5}{14} * 0.971 + \frac{4}{14} * 0 + \frac{5}{14} * 0.971 = 0.693
145∗0.971+144∗0+145∗0.971=0.693
信息增益:系统的熵值从原始的
0.940
0.940
0.940下降到了
0.693
0.693
0.693,增益为
0.247
0.247
0.247
同样的方式可以计算出其他特征的信息增益,那么我们选择最大的那个就可以啦
g
a
i
n
(
t
e
m
p
e
r
a
t
u
r
e
)
=
0.029
gain(temperature)=0.029
gain(temperature)=0.029
g
a
i
n
(
h
u
m
i
d
i
t
y
)
=
0.152
gain(humidity)=0.152
gain(humidity)=0.152
g
a
i
n
(
w
i
n
d
y
)
=
0.048
gain(windy)=0.048
gain(windy)=0.048
6、决策树算法 – 衡量标准
I
D
3
ID3
ID3 :信息增益,即上面介绍的(不适合解决非常稀疏的特征,例如id序号)
C
4.5
C4.5
C4.5 : 信息增益率(解决
I
D
3
ID3
ID3问题,考虑自身熵)
C
A
R
T
CART
CART :使用
G
I
N
I
GINI
GINI系数来当作衡量标准
G
I
N
I
系数
GINI系数
GINI系数 :
G
i
n
i
(
p
)
=
∑
k
=
1
K
p
k
(
1
−
p
k
)
=
1
−
∑
k
=
1
K
p
k
2
Gini(p) = \sum\limits_{k = 1}^{K} p_k (1 - p_k) = 1 - \sum\limits_{k = 1}^{K} p_k^2
Gini(p)=k=1∑Kpk(1−pk)=1−k=1∑Kpk2 (和熵的衡量标准类似,计算方式不相同)
7、决策树剪枝策略
7.1 为什么要剪枝:
决策树过拟合风险很大,理论上可以完全分得开数据
如果树足够庞大,每个叶子节点不就一个数据了嘛,即使准确率很高,但这样做是没有意义的
7.2 剪枝策略
剪枝策略:预剪枝,后剪枝
预剪枝:边建立决策树边进行剪枝的操作(更实用) 限制深度,叶子节点个数叶子节点样本数,信息增益量等 后剪枝:当建立完决策树后来进行剪枝操作 通过一定的衡量标准
C
α
(
T
)
=
C
(
T
)
+
α
⋅
∣
T
l
e
a
f
∣
C_\alpha(T) = C(T) + \alpha \cdot |T_{leaf}|
Cα(T)=C(T)+α⋅∣Tleaf∣ (叶子节点越多,损失越大)
8、
s
k
l
e
a
r
n
sklearn
sklearn决策树使用实例
关于
s
k
l
e
a
r
n
sklearn
sklearn的使用请参考
s
k
l
e
a
r
n
sklearn
sklearn的官网
# import package
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn import linear_model, neighbors, tree, svm, ensemble
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import mean_squared_error, mean_absolute_error, confusion_matrix, classification_report
1、
C
l
a
s
s
i
f
i
c
a
t
i
o
n
Classification
Classification任务
bank = pd.read_csv('bank.csv')
print(bank.head())
# 将非数值行特征转换为数值
bank_cat = bank.select_dtypes(['object']).copy()
for col in bank_cat:
print(col, ':')
codes, uniques = pd.factorize(bank_cat[col], sort=True)
bank[col]=codes
# 获取模型输入
y = bank['deposit']
X = bank.drop(['deposit'], axis=1)
# 分割数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1)
# 数据标准化
mean = X_train.mean()
std = X_train.std()
X_train = (X_train - mean) / std
X_test = (X_test - mean) / std
print("===X_train===")
print(X_train)
print("===y_train===")
print(y_train)
dt_clf = tree.DecisionTreeClassifier(max_depth = 4)
dt_clf.fit(X_train, y_train)
print('train_acc:', dt_clf.score(X_train, y_train),
'\n test_acc:', dt_clf.score(X_test, y_test))
train_acc: 0.7960577892261171 test_acc: 0.7828034034930587
#使用GridSearchCV自动调参
from sklearn.model_selection import GridSearchCV
dt_clf = tree.DecisionTreeClassifier()
param_grid = { "criterion" : ["gini", "entropy"],
"min_samples_leaf" : [1, 5, 10],
"min_samples_split" : [6,8,10, 12,14, 16,18, 20,22, 24],
'max_depth' : [3,4,5,6,7,8,9,10,11,12]
}
gs_clf = GridSearchCV(dt_clf, param_grid=param_grid, scoring='accuracy', cv= 5, n_jobs=-1)
# cv: 交叉验证分几份
# n_jobs: 并行运行的处理器核心, -1 是使用所有
gs_clf.fit(X_train, y_train)
print(gs_clf.best_score_)
print(gs_clf.best_params_)
print(gs_clf.best_estimator_)
0.8232731390428512 {‘criterion’: ‘entropy’, ‘max_depth’: 12, ‘min_samples_leaf’: 10, ‘min_samples_split’: 24} DecisionTreeClassifier(criterion=‘entropy’, max_depth=12, min_samples_leaf=10, min_samples_split=24)
dt_clf = gs_clf.best_estimator_
dt_clf.fit(X_train, y_train)
print('train_acc:', dt_clf.score(X_train, y_train),
'\n test_acc:', dt_clf.score(X_test, y_test))
train_acc: 0.8759099563220966 test_acc: 0.825794894760412
2.
R
e
g
r
e
s
s
i
o
n
Regression
Regression任务
supermarket = pd.read_csv('supermarket.csv')
print(supermarket.head())
supermarket_cat = supermarket.select_dtypes(['object']).copy()
for col in supermarket_cat:
print(col, ':')
codes, uniques = pd.factorize(supermarket_cat[col], sort=True)
supermarket[col]=codes
print(uniques)
print(supermarket.head())
y = supermarket['Item_Outlet_Sales']
X = supermarket.drop(['Item_Outlet_Sales'], axis=1)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=2)
mean = X_train.mean()
std = X_train.std()
X_train = (X_train - mean) / std
X_test = (X_test - mean) / std
print("===X_train===")
print(X_train)
print("===y_train===")
print(y_train)
dt_reg = tree.DecisionTreeRegressor(criterion = 'mse', max_depth=3)
dt_reg.fit(X_train, y_train)
print('train_mae:', mean_absolute_error(dt_reg.predict(X_train), y_train),
'\n test_mae:', mean_absolute_error(dt_reg.predict(X_test), y_test))
train_mae: 764.9480125757958 test_mae: 768.3178987658453
#调参
param_grid = {"criterion" : ["mse", "friedman_mse"],
'max_depth' : [2,3,4,5,6,7,8,9,10,11,12,13],
'min_samples_leaf' : [1,3,5,7,10],
'min_samples_split' : [2,4,6,10, 12, 16, 20, 24]
}
gs_reg = GridSearchCV(dt_reg, param_grid=param_grid, scoring='neg_mean_squared_error', cv= 5, n_jobs=-1)
gs_reg.fit(X_train, y_train)
print(gs_reg.best_score_)
print(gs_reg.best_params_)
print(gs_reg.best_estimator_)
-961807.5687332209 {‘criterion’: ‘mse’, ‘max_depth’: 5, ‘min_samples_leaf’: 5, ‘min_samples_split’: 16} DecisionTreeRegressor(criterion=‘mse’, max_depth=5, min_samples_leaf=5, min_samples_split=16)
dt_reg = gs_reg.best_estimator_
dt_reg.fit(X_train, y_train)
print('train_mae:', mean_absolute_error(dt_reg.predict(X_train), y_train),
'\n test_mae:', mean_absolute_error(dt_reg.predict(X_test), y_test))
train_mae: 701.3943587725482 test_mae: 692.7756288130439
dt_reg.score(X_test, y_test)
0.5767475439986196
如果文中有任何错误,请在评论区指正。
都看到这了,点个赞再走吧
相关阅读
发表评论