ng-决策树

特征选择算法

我们希望选择具有良好分类能力的特征,为此我们引入信息增益来衡量不纯度

X是取有限个值的随机变量,则概率分布为 P(X = xi) = pi,  i = 1, 2, ⋯, n 定义随机变量X的熵为 $$H(X)=-\sum_{i=1}^np_i\log p_i$$ log以2为底时,熵的单位是比特,以e为底时,熵的单位是纳特。
若随机变量只取两个值(伯努利分布),熵可以写为关于p的函数 H(p) = −plog p − (1 − p)log (1 − p) 1720786491668.png

Information gain信息增益

一般的,定义 (信息增益) 特征A对训练数据集D的信息增益g(D, A),定义为集 合D的经验熵H(D)与特征A给定条件下D的经验条件熵H(D|A)之差,即 g(D, A) = H(D) − H(D|A)

  • 在决策树的二叉树场景下,上式可写为  = H(p1root)  − (wleftH(p1left) + wrightH(p1right))

我们总是选择信息增益更大的决策A用于树的生成。

数学描述

设训练数据集为D,|D|表示其样本容量,即样本个数。设有K个类Ck, k= 1, 2, ⋯, K,|Ck|为属于类Ck的样本个数,∑|Ck| = |D|。设特征An个不同的 k = 1 取值{a1, a2, ⋯, an},根据特征A的取值将D 划 分 为 n个子集D1, D2, ⋯, Dn, |Di|Di的样本个数,$\sum_i^n|D_i|=|D|$。记子集Di中属于类Ck的样本的集合为Dik,即 i = 1 Dik = Di ∩ Ck, |Dik|Dik 的样本个数。于是信息增益的算法如下。

(1)计算数据集D的经验熵H(D),这代表原始数据集的混乱程度(直接按照将要预测特征求熵) $$H(D)=-\sum_{k=1}^K\frac{|C_k|}{|D|}\log_2\frac{|C_k|}{|D|}$$ (2)计算特征A对数据集D的经验条件熵H(D|A) $$H(D|A)=\sum_{i=1}^n\frac{|D_i|}{|D|}H(D_i)=-\sum_{i=1}^n\frac{|D_i|}{|D|}\sum_{k=1}^K\frac{|D_{ik}|}{|D_i|}\log_2\frac{|D_{ik}|}{|D_i|}$$ (3)计算信息增益 g(D, A) = H(D) − H(D|A)

  • 引入信息增益比 $$g_R(D,A)=\frac{g(D,A)}{H_A(D)}$$ 其中,$H_A(D)=-\sum_{i=1}^n\frac{|D_i|}{|D|}\log_2\frac{|D_i|}{|D|},n$是特征A取值的个数。 这是为因为在决策过程中,算法直接使用信息增益,会导致进行决策倾向于选择分类特征较多的节点,为此引入信息增益比来规避这一问题。

ID3算法->C4.5算法

用于生成树

剪枝算法

决策树的剪枝往往通过极小化决策树整体的损失函数(loss function)或代价函数(cost function)来实现。设树T的叶结点个数为|T|,t是树T的叶结点,该叶结点有Nt个样本点,其中k类的样本点有Ntk个,k = 1, 2, ⋯, K,Ht(T)为叶结点t 上的经验熵,α ≥ 0为参数,则决策树学习的损失函数可以定义为

$$C_\alpha(T)=\sum_{t=1}^{|T|}N_tH_t(T)+\alpha|T|$$ 其中经验熵为 $$H_t(T)=-\sum_k\frac{N_{tk}}{N_t}\log\frac{N_{tk}}{N_t}$$ 在损失函数中,将式(5.11)右端的第 1 项记作 $$C(T)=\sum_{t=1}^{|T|}N_tH_t(T)=-\sum_{t=1}^{|T|}\sum_{k=1}^KN_{tk}\log\frac{N_{tk}}{N_t}$$ ### 这时有 Cα(T) = C(T) + α|T|

α的大小决定了我们对树的复杂程度的控制。我们为了防止过拟合,需要在C(T)和 T之间取舍。
剪枝算法的基本思路就是,从叶节点自下而上的剪枝,如果剪枝后的惩罚函数变小了,则返回剪枝之后的树继续进行剪枝。

CART算法

回归树算法

本质上实在构建一个及其细分的分段函数用于回归算法,每次分段遵循最小的残差平方和进行。
采用启发式的方法,选择第j个变量x(j) 和它取的值s,作为切分变量(splitting variable)和切分点(splitting point),并定义两个区域(事实上遍历j的思路有很多): R1(j, s) = {x|x(j) ≤ s}  和  R2(j, s) = {x|x(j) > s} 然后寻找最优切分变量j和最优切分点s。具体地,求解 minj, s[minc1xi ∈ R1(j, s)(yi − c1)2 + minc2xi ∈ R2(j, s)(yi − c2)2] 算法如下:
(1)选择最优切分变量j与切分点s,求解 minj, s[minc1xi ∈ R1(j, s)(yi − c1)2 + minc2xi ∈ R2(j, s)(yi − c2)2] 遍历变量j,对固定的切分变量j扫描切分点s,选择使上式达到最小值的对
(2)用选定的对(j, s)划分区域并决定相应的输出值: R1(j, s) = {x|x(j) ≤ s},  R2(j, s) = {x|x(j) > s} $$\hat{c}_m=\frac1{N_m}\sum_{x_i\in R_m(j,s)}y_i,\quad x\in R_m,\quad m=1,2$$ (3)继续对两个子区域调用步骤 (1),(2),直至满足停止条件。(4)将输入空间划分为M个区域R1, R2, ⋯, RM,生成决策树: $$f(x)=\sum_{m=1}^M\hat{c}_mI(x\in R_m)$$

分类树算法

使用基尼指数作为划分标准,其实和上文的熵趋势上一样。
基尼指数
$$\mathrm{Gini}(p)=\sum_{k=1}^Kp_k(1-p_k)=1-\sum_{k=1}^Kp_k^2$$ 对于给定的样本,基尼指数为 $$\mathrm{Gini}(D)=1-\sum_{k=1}^K\left(\frac{|C_k|}{|D|}\right)^2$$

1720793162035.png

one-hot编码

也可以用到神经网络,逻辑回归等领域, alt text alt text

决策树可以处理连续值特征,方法是在每个节点上考虑不同的阈值进行划分,计算信息增益,选择能提供最大信息增益的阈值进行分割。这样可以递归地构建决策树的其余部分。此外,决策树算法还可以扩展到回归问题,预测数字输出。

实战:预测天气

代码分两个模块 - 数据分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
##  基础函数库
import numpy as np
import pandas as pd
## 绘图函数库
import matplotlib.pyplot as plt
import seaborn as sns
data = pd.read_csv('../data/weather.csv')
# data.info()
data = data.fillna(-1)

#k考察数据整体
def overview():
global data
data.info()
data.describe()

numerical_features = [x for x in data.columns if data[x].dtype == np.float64]
category_features = [x for x in data.columns if data[x].dtype != np.float64 and x != 'RainTomorrow']
# 画箱线图函数
def boxlinegraph():
global numerical_features
global category_features
for col in data[numerical_features].columns:
if col != 'RainTomorrow':
sns.boxplot(x='RainTomorrow', y=col, saturation=0.5, palette='pastel', data=data)
plt.title(col)
plt.show()

## 把所有的相同类别的特征编码为同一个值
def get_mapfunction(x):
mapp = dict(zip(x.unique().tolist(),
range(len(x.unique().tolist())))) # 将这些独特的值与一个范围(从0开始,长度为独特值的数量)配对,创建一个元组列表。每个独特值对应一个唯一的整数。
def mapfunction(y):
if y in mapp:
return mapp[y]
else:
return -1
return mapfunction
for i in category_features:
data[i] = data[i].apply(get_mapfunction(data[i]))


boxlinegraph()

- 决策树预测
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from xgboost.sklearn import XGBClassifier
import matplotlib.pyplot as plt
import seaborn as sns
data = pd.read_csv('../data/weather.csv')
# data.info()
data = data.fillna(-1)

numerical_features = [x for x in data.columns if data[x].dtype == np.float64]
category_features = [x for x in data.columns if data[x].dtype != np.float64 ]
def get_mapfunction(x):
mapp = dict(zip(x.unique().tolist(),
range(len(x.unique().tolist())))) # 将这些独特的值与一个范围(从0开始,长度为独特值的数量)配对,创建一个元组列表。每个独特值对应一个唯一的整数。
def mapfunction(y):
if y in mapp:
return mapp[y]
else:
return -1
return mapfunction
for i in category_features:
data[i] = data[i].apply(get_mapfunction(data[i]))

## 选择其类别为0和1的样本 (不包括类别为2的样本)
data_target_part = data['RainTomorrow']
data_features_part = data[[x for x in data.columns if x != 'RainTomorrow']]
## 测试集大小为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)
## 定义 XGBoost模型
clf = XGBClassifier()
# 在训练集上训练XGBoost模型
clf.fit(x_train, y_train)
## 在训练集和测试集上分布利用训练好的模型进行预测
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()



ng-决策树
http://example.com/2024/03/10/机器学习/ng机器学习/
作者
bradin
发布于
2024年3月10日
许可协议