01 - 决策树

1. 概述

说实话,在我的理解范围内,现有算法基本可以被总结到如下三类中:

  • 基于知识规则的推理,由人类智慧的人工总结,例如一个普通人炒菜的决策过程;

  • 基于经典统计的描述,根据经典数据统计方法做对应决策,如对哪些学生做奖励先统计出top2%;

  • 基于广义统计的抽象,包括现有的机器学习、深度学习等系列算法,自动从数据中总结抽象决策。

任何一个数据驱动的系统都避免不了如上三类方法,例如一个完备的电商推荐系统既需要设计类似于保存购物车就推荐部分到首页的基于知识规则的推理,也需要统计到某群体用户的主体需求做基于经典统计的描述,最后必不可少得用上各种适于处理大数据的基于广义统计的机器学习算法。

好了,不扯淡了,下面开始重点围绕决策树算法本身,在《决策树总结|ID3 C4.5/C5.0 CHAID CART与QUEST》《决策树学习》这两篇文章中,作者对主流决策树算法都有较为详细的说明,此处不再过分详述,要点如下:

  • 决策树模型呈树形结构(节点[内部节点表示一个特征,叶子节点表示一个类别] + 有向边),可认为由算法总结的IF-THEN规则结合,其结果类似于人工知识规则,故而非常直观;
  • 决策树学习三大步骤:特征选择、决策生成、决策剪枝;
  • 根据各步骤所用方法不同可分为如下常见算法:CHAID(1980)、CART(1984)、ID3(1986)、C4.5(1993)/C5.0、QUEST(1997)、AD-Tree(1999)、Soft Decision Tree(2017)等,其中CART(Classification and Regression Tree)分类回归树既可用于分类又可用于回归,此外ID3(信息增益)→C4.5(信息增益比)→C5.0(商业优化版)一脉相承。

《决策树学习》一文中,作者提到:根据谷歌趋势和谷歌学术的数据,C4.5仍然是各种决策树学习算法中最受关注和相关论文数量最多的,因此我们可以将其看作是单决策树学习应用中最流行的算法。

2. C4.5

  • 【特征选择】即决定由哪个特征来划分特征空间,ID3使用信息增益,C4.5使用信息增益比;
  • 【决策生成】(略);
  • 【决策剪枝】如果说决策生成只是对(训练)样本数据集进行了很好的拟合,那么决策剪枝则通过优化损失函数减小了模型复杂度的同时提高了在(测试)总体数据集的泛化能力。

具体内容请参阅《统计学习方法》李航著

3. Iris数据集

# 加载iris数据:sklearn包自带
from sklearn.datasets import load_iris
iris = load_iris()

# 查看数据类型
print(type(iris.data), '\t', iris.data.dtype, '\t', iris.data.shape)
print(type(iris.target), '\t', iris.target.dtype, '\t\t', iris.target.shape)

# 利用Pandas查看统计描述
import pandas as pd
print('\n------------------------------------')
print('\n', pd.DataFrame(iris.data).describe())
print('\n类别集合:', set(iris.target))

4. 数据离散化

由于本算法需接受分类变量进行处理,因而需要将各特征值数据离散化,采用不同的离散方式往往对结果有着很大的影响,参考Python数据预处理 - 连续数据离散化(等宽、等频、聚类离散)常用的数据离散化方式有:

  • 等宽离散
  • 等频离散
  • 聚类离散

为方便阐述,此处仅采用等宽离散。

k = 5  # k份
iris.data = iris.data.astype('int')
for n in range(iris.data.shape[-1]):
    iris.data[:, 0] = pd.cut(iris.data[:, 0], k, labels=range(k))
print(iris.data)

通过如上代码可以看到Iris数据集共计150个实例,有4个属性,和3个类别。

5. 数据集的划分

import random
sum_of_data = len(iris.target)
idx = [i for i in range(sum_of_data)]  # 准备索引
random.shuffle(idx)  # 对idx执行shuffle
# 如下采用经典的二八划分原则
train_data = iris.data[idx[:int(sum_of_data*0.8)]]
train_target = iris.target[idx[:int(sum_of_data*0.8)]]
test_data = iris.data[idx[int(sum_of_data*0.8):]]
test_target = iris.target[idx[int(sum_of_data*0.8):]]
# 可以查看一下测试集的前十个数据:前四列是特征,最后一列是类别
print(np.hstack((test_data, np.expand_dims(test_target, axis=1)))[:10])
import os
if not os.path.exists("data"):
    os.makedirs("data")
# 也可以分别保存训练集和测试集到CSV文件中
train_set = pd.DataFrame(np.hstack((train_data, np.expand_dims(train_target, axis=1))))
test_set = pd.DataFrame(np.hstack((test_data, np.expand_dims(test_target, axis=1))))
train_set.to_csv("data/iris_train.csv", index=False, header=None, sep=',')
test_set.to_csv("data/iris_test.csv", index=False, header=None, sep=',')

6. sklearn构建决策树完整流程演示

参考sklearn中文文档

from sklearn.datasets import load_iris
from sklearn import tree
iris = load_iris()
clf = tree.DecisionTreeClassifier()  # "clf" means "classifier"
clf = clf.fit(iris.data, iris.target)  # 使用iris源数据
# clf = clf.fit(train_data, train_target)  # 使用预处理过的数据
print("预测:", clf.predict(test_data))
print("真实:", test_target)

猜你喜欢

转载自blog.csdn.net/atlantistin/article/details/84785934