【学习笔记】分类算法-决策树、随机森林

目录

  • 特征选择
  • 信息的度量和作用
  • 信息增益
    • 信息增益的计算
    • 常见决策树使用的算法
  • sklearn决策树API
    • 泰坦尼克号案例
  • 决策树的优缺点以及改进
  • 集成学习方法-随机森林
    • 学习算法
    • 集成学习API

决策树是一种基本的分类方法,当然也可以用于回归。我们一般只讨论用于分类的决策树。决策树模型呈树形结构。在分类问题中,表示基于特征对实例进行分类的过程,它可以认为是if-then规则的集合。在决策树的结构中,每一个实例都被一条路径或者一条规则所覆盖。通常决策树学习包括三个步骤:特征选择、决策树的生成和决策树的修剪。

特征选择

特征选择在于选取对训练数据具有分类能力的特征。这样可以提高决策树学习的效率,如果利用一个特征进行分类的结果与随机分类的结果没有很大差别,则称这个特征是没有分类能力的。经验上扔掉这样的特征对决策树学习的影响不大。通常特征选择的准则是信息增益,这是个数学概念。通过一个例子来了解特征选择的过程。

ID 年龄 有工作 有自己的房子 信贷情况 类别
1 青年 一般
2 青年
3 青年
4 青年 一般
5 青年 一般
6 中年 一般
7 中年
8 中年
9 中年 非常好
10 中年 非常好
11 老年 非常好
12 老年
13 老年
14 老年 非常好
15 老年 一般

我们希望通过所给的训练数据学习一个贷款申请的决策树,用以对文中的贷款申请进行分类,即当新的客户提出贷款申请时,根据申请人的特征利用决策树决定是否批准贷款申请。特征选择其实是决定用那个特征来划分特征空间。下图中分别是按照年龄,还有是否有工作来划分得到不同的子节点。

【学习笔记】分类算法-决策树、随机森林_第1张图片

【学习笔记】分类算法-决策树、随机森林_第2张图片

问题是究竟选择哪个特征更好些呢?那么直观上,如果一个特征具有更好的分类能力,是的各个自己在当前的条件下有最好的分类,那么就更应该选择这个特征。信息增益就能很好的表示这一直观的准则。这样得到的一棵决策树只用了两个特征就进行了判断:

【学习笔记】分类算法-决策树、随机森林_第3张图片

通过信息增益生成的决策树结构,更加明显、快速的划分类别。

信息的度量和作用

我们常说信息有用,那么它的作用如何客观、定量地体现出来呢?信息用途的背后是否有理论基础呢?这个问题一直没有很好的回答,直到1948年,香农在他的论文“通信的数学原理”中提到了“信息熵”的概念,才解决了信息的度量问题,并量化出信息的作用。

一条信息的信息量与其不确定性有着直接的关系,比如我们要搞清一件非常不确定的事,就需要大量的信息。相反如果对某件事了解较多,则不需要太多的信息就能把它搞清楚 。所以从这个角度看,可以认为,信息量就等于不确定的多少。那么如何量化信息量的度量呢?2022年举行世界杯,大家很关系谁是冠军。假如我错过了看比赛,赛后我问朋友 ,“谁是冠军”?他不愿意直接告诉我,让我每猜一次给他一块钱,他告诉我是否猜对了,那么我需要掏多少钱才能知道谁是冠军?我可以把球编上号,从1到32,然后提问:冠 军在1-16号吗?依次询问,只需要五次,就可以知道结果。所以谁是世界杯冠军这条消息只值五块钱。当然香农不是用钱,而是用“比特”这个概念来度量信息量。一个比特是 一位二进制数,在计算机中一个字节是8比特。

那么如果说有一天有64支球队进行决赛阶段的比赛,那么“谁是世界杯冠军”的信息量就是6比特,因为要多猜一次,有的同学就会发现,信息量的比特数和所有可能情况的对数函数log有关,(log32=5,log64=6)

另外一方面你也会发现实际上我们不需要猜五次就能才出冠军,因为像西班牙、巴西、德国、意大利这样的球队夺得冠军的可能性比南非、尼日利亚等球队大得多,因此第一次猜测时不需要把32支球队等分成两个组,而可以把少数几支最有可能的球队分成一组,把其他球队分成一组。然后才冠军球队是否在那几支热门队中。这样,也许三次就猜出结果。因此,当每支球队夺冠的可能性不等时,“谁是世界杯冠军”的信息量比5比特少。香农指出,它的准确信息量应该是:

H = -(p1logp1 + p2logp2 + ... + p32log32)

其中,p1...p32为这三支球队夺冠的概率。H的专业术语称之为信息熵,单位为比特,当这32支球队夺冠的几率相同时,对应的信息熵等于5比特,这个可以通过计算得出。有一个特性就是,5比特是公式的最大值。那么信息熵(经验熵)的具体定义可以为如下:

信息增益

自古以来,信息和消除不确定性是相联系的。所以决策树的过程其实是在寻找某一个特征对整个分类结果的不确定减少的过程。那么这样就有一个概念叫做信息增益(information gain)。

那么信息增益表示得知特征X的信息而使得类Y的信息的不确定性减少的程度,所以我们对于选择特征进行分类的时候,当然选择信息增益较大的特征,这样具有较强的分类能力。特征A对训练数据集D的信息增益g(D,A),定义为集合D的经验熵H(D)与特征A给定条件下D的经验条件熵H(D|A)之差,即公式为:

根据信息增益的准则的特征选择方法是:对于训练数据集D,计算其每个特征的信息增益,并比较它们的阿笑,选择信息增益最大的特征。

信息增益的计算

所以首先对于经验熵来说,计算如下:

【学习笔记】分类算法-决策树、随机森林_第4张图片

那么条件熵计算如下:

【学习笔记】分类算法-决策树、随机森林_第5张图片

既然我们有了这两个公式,我们可以根据前面的是否通过贷款申请的例子来通过计算得出我们的决策特征顺序。那么我们首先计算总的经验熵为:

H(D) = -(9/15 * log(9/15) + 6/15 * log(6/15)) = 0.9709505944546686

然后计算出年龄的信息增益为:

H(D|年龄) = H(D) - H(D'|年龄) = 0.9709505944546686 - [1/3H(青年) + 1/3H(中年) + 1/3H(老年)]

H(青年) = -(3/5 * log(3/5) + 2/5 * log(2/5))

H(青年) = -(3/5 * log(3/5) + 2/5 * log(2/5))

H(老年) = -(4/5 * log(4/5) + 1/5 * log(1/5))

常见决策树使用的算法

  • ID3:信息增益 最大的准则

  • C4.5:信息增益比 最大的准则

  • CART:
    回归树: 平方误差 最小
    分类树: 基尼系数 最小的准则 在sklearn中可以选择划分的原则

sklearn决策树API

sklearn.tree.DecisionTreeClassifier(criterion=’gini’, max_depth=None,random_state=None):决策树分类器

参数:

  • criterion:默认是’gini’系数,也可以选择信息增益的熵’entropy’
  • max_depth:树的深度大小
  • random_state:随机数种子

方法:

  • decision_path:返回决策树的路径

泰坦尼克号案例

在泰坦尼克号和titanic2数据帧描述泰坦尼克号上的个别乘客的生存状态。在泰坦尼克号的数据帧不包含从剧组信息,但它确实包含了乘客的一半的实际年龄。关于泰坦尼克号旅客的数据的主要来源是百科全书Titanica。这里使用的数据集是由各种研究人员开始的。其中包括许多研究人员创建的旅客名单,由Michael A. Findlay编辑。

我们提取的数据集中的特征是票的类别,存活,乘坐班,年龄,登陆,home.dest,房间,票,船和性别。乘坐班是指乘客班(1,2,3),是社会经济阶层的代表。

import pandas as pd
from sklearn.feature_extraction import DictVectorizer
from sklearn.tree import DecisionTreeClassifier, export_graphviz

# 获取数据
titannic = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")
# print(titannic.info())

# 选取一些特征
x = titannic[["pclass", "age", "sex"]]
y = titannic["survived"]

# 处理缺失值
x["age"].fillna(x["age"].mean(), inplace=True)

# 数据集分隔
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)
# 字典特征抽取
dv = DictVectorizer(sparse=False)
# print(x_train.to_dict(orient="record"))
x_train = dv.fit_transform(x_train.to_dict(orient="records"))
# print(dv.get_feature_names())
x_test = dv.transform(x_test.to_dict(orient="records"))

# 决策树进行预测
dec = DecisionTreeClassifier()
dec.fit(x_train, y_train)

print("预测的准确率:", dec.score(x_test, y_test))
# 导出决策树
export_graphviz(dec, out_file="titannic_tree.dot", feature_names=dv.get_feature_names())

输出结果:

预测的准确率: 0.8206686930091185

sklearn.tree.export_graphviz() 该函数能够导出DOT格式tree.export_graphviz(estimator,out_file='tree.dot’,feature_names=[‘’,’’])

使用graphviz将dot文件转换成png图片。

在ubuntu的安装命令:

sudo apt-get install graphviz

运行命令转成png:

dot -Tpng titannic_tree.dot -o titannic_tree.png

决策树的优缺点以及改进

优点:

  • 简单的理解和解释,树木可视化。

  • 需要很少的数据准备。其他技术通常需要数据归一化,需要创建虚拟变量,并删除空值。但请注意,此模块不支持缺少值。
  • 使用树的成本(即,预测数据)在用于训练树的数据点的数量上是对数的。

缺点:

  • 决策树学习者可以创建不能很好地推广数据的过于复杂的树。这被称为过拟合。修剪(目前不支持)的机制,设置叶节点所需的最小采样数或设置树的最大深度是避免此问题的必要条件。
  • 决策树可能不稳定,因为数据的小变化可能会导致完全不同的树被生成。通过使用合奏中的决策树来减轻这个问题。

改进:

  • 减枝cart算法
  • 随机森林

集成学习方法-随机森林

集成学习通过建立几个模型组合的来解决单一预测问题。它的工作原理是生成多个分类器/模型,各自独立地学习和作出预测。这些预测最后结合成单预测,因此优于任何一个单分类的做出预测。

什么是随机森林?

在机器学习中,随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定。

学习算法

根据下列算法而建造每棵树:

  • 用N来表示训练用例(样本)的个数,M表示特征数目。
  • 输入特征数目m,用于确定决策树上一个节点的决策结果;其中m应远小于M。
  • 从N个训练用例(样本)中以有放回抽样的方式,取样N次,形成一个训练集(即bootstrap取样),并用未抽到的用例(样本)作预测,评估其误差。
  • 对于每一个节点,随机选择m个特征,决策树上每个节点的决定都是基于这些特征确定的。根据这m个特征,计算其最佳的分裂方式。

为什么要随机抽样训练集?

如果不进行随机抽样,每棵树的训练集都一样,那么最终训练出的树分类结果也是完全一样的。

为什么要有放回地抽样?

如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都是没有交集的,这样每棵树都是“有偏的”,都是绝对“片面的”(当然这样说可能不对),也就是说每棵树训练出来都是有很大的差异的;而随机森林最后分类取决于多棵树(弱分类器)的投票表决。

集成学习API

class sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion=’gini’,
max_depth=None, bootstrap=True, random_state=None):随机森林分类器

参数:

  • n_estimators:integer,optional(default = 10) 森林里的树木数量
  • criteria:string,可选(default =“gini”)分割特征的测量方法
  • max_depth:integer或None,可选(默认=无)树的最大深度
  • bootstrap:boolean,optional(default = True)是否在构建树时使用放回抽样

改造之前泰坦尼克号的案例

from sklearn.ensemble import RandomForestClassifier
...
# 随机森林进行预测
rf = RandomForestClassifier()

# 网格搜索与交叉认证
param = {"n_estimators": [120, 200, 300, 400, 500, 800, 1200], "max_depth": [3, 5, 15, 25, 30]}
gc = GridSearchCV(rf, param_grid=param, cv=2)
gc.fit(x_train, y_train)

print("准确率为:", gc.score(x_test, y_test))
print("最佳的模型参数:", gc.best_params_)

输出结果:

准确率为: 0.8297872340425532
最佳的模型参数: {'max_depth': 5, 'n_estimators': 120}

随机森林的优点:

  • 在当前所有算法中,具有极好的准确率
  • 能够有效地运行在大数据集上
  • 能够处理具有高维特征的输入样本,而且不需要降维
  • 能够评估各个特征在分类问题上的重要性
  • 对于缺省值问题也能够获得很好得结果

你可能感兴趣的:(【学习笔记】分类算法-决策树、随机森林)