- 老师强调:作为计算机工程师,传统的算法和数据结构是最基础的内容,要掌握。
一、节点数据集的划分
1)决策树算法的思想
- 解决分类问题时,决策树算法的任务是构造决策树模型,对未知的样本进行分类;
- 决策树算法利用了信息熵和决策树思维:
- 信息熵越小的数据集,样本的确定性越高,当数据集的信息熵为 0 时,该数据集中只有一种类型的样本;
- 训练数据集中有很多类型的样本,通过对数据集信息熵的判断,逐层划分数据集,最终将每一类样本单独划分出来;
- 划分数据集的方式有很多种,只有当按样本类别划分数据集时(也就是两部分数据集中不会同时存在相同类型的样本),划分后的两部分数据集的整体的信息熵最小;反相推断,当两部分数据集的整体的信息熵最小时,则两部分数据集中不会同时存在相同类型的样本;
2)划分步骤
- 划分点:某一特征的某一个数值;(根据该特征值对数据集样本进行划分)
- 数据集中样本的排序:根据特征的数值大小进行排序;
- (一般不直接打乱原始数据集中样本的排列顺序,而是使用 np.argsorted( 特征向量 ),返回特征向量中元素排序后对应的 index)
- 选取划分点:要没有遗漏的迭代所有情况的划分点对应的划分情况;
- 将特征值排序后,从 0 号开始,选取相邻的但不相等的两个特征值的平均数作为一个划分点;按此方式迭代找出一组特质向量中的所有划分点;
4)划分结果
- 两种数据集:X_left、X_right 机器对应的 y;
- 特征类型,及其最优的划分点的特征值;
5)代码实现划分过程
-
划分根节点的数据集
import numpy as np import matplotlib.pyplot as plt from sklearn import datasets iris = datasets.load_iris() X = iris.data[:, 2:] y = iris.target
-
划分函数:返回数据集 X1、X2、y1、y2
def split(X, y, d, value): index_a = (X[:, d] <= value) index_b = (X[:, d] > value) return X[index_a], X[index_b], y[index_a], y[index_b]
- d:特征;
- value:特征值;
-
信息熵计算函数
from collections import Counter from math import log def entropy(y): counter = Counter(y) res = 0.0 for num in counter.values(): p = num / len(y) res += -p * log(p) return res
- counter = Counter(y):将向量 y 做成一个字典;
- counter 的 key:y 中各种数据;
- counter 的value:key 对应的数据在 y 中的个数;
- Counter(list/tuple/str/array等序列):以字典的形式返回 序列中所有元素及其数量;(可以起到去重的作用)
-
寻找最优的特征 d 及其对应的特征值 value、最小信息熵 entropy
def try_split(X, y): best_entropy = float('inf') best_d, best_v = -1, -1 for d in range(X.shape[1]): sorted_index = np.argsort(X[:,d]) for i in range(1, len(X)): if X[sorted_index[i-1], d] != X[sorted_index[i], d]: v = (X[sorted_index[i-1], d] + X[sorted_index[i], d]) / 2 x_l, x_r, y_l, y_r = split(X, y, d, v) e = entropy(y_l) + entropy(y_r) if e < best_entropy: best_entropy, best_d, best_v = e, d, v return best_entropy, best_d, best_v
- float('inf'):'inf'表示正无穷的值;
- np.argsort(X[:, d]):返回数据集 X 在第 d 列的排序的 index,并没有打乱数据集 X 的样本排列顺序;
-
第一次划分
best_entropy, best_d, best_v = try_split(X, y) x1_l, x1_r, y1_l, y1_r = split(X, y, best_d, best_v)
-
第二次划分数据集
- 判断数据集的信息熵是否为 0,如果等于 0,说明该数据集中只有一种类型的样本,不需要再进行划分;反之则需要再次进行划分;
- 划分方法与第一次划分的过程一样;