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

−149​log2​149​−145​log2​145​=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∑K​pk​(1−pk​)=1−k=1∑K​pk2​ (和熵的衡量标准类似,计算方式不相同)

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

如果文中有任何错误,请在评论区指正。

都看到这了,点个赞再走吧

相关阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。