决策树
决策树思想的来源非常朴素,程序设计中的条件分支结构就是if-then结构,最早的决策树就是利用这类结构分割数据的一种分类学习方法
信息论基础
信息熵
依据 Boltzmann’s H-theorem,香农把随机变量
X
X
X 的熵值
H
Η
H(希腊字母Eta)定义如下,其值域为
x
1
,
.
.
.
,
x
n
{x_1, ..., x_n}
x1,...,xn:
H
(
X
)
=
∑
i
P
(
x
i
)
I
(
x
i
)
=
−
∑
i
P
(
x
i
)
log
b
P
(
x
i
)
,
\mathrm{H} (X)=\sum _{{i}}{{\mathrm {P}}(x_{i})\,{\mathrm {I}}(x_{i})}=-\sum _{{i}}{{\mathrm {P}}(x_{i})\log _{b}{\mathrm {P}}(x_{i})},
H(X)=i∑P(xi)I(xi)=−i∑P(xi)logbP(xi),
- 信息和消除不确定性是相联系的,即信息熵越大,不确定性越大
- H H H 的专业术语称之为信息熵,单位为比特。
案例:每猜一次给一块钱,告诉我是否猜对了,那么我需要掏多少钱才能知道谁是冠军?
我可以把球编上号,从1到32,然后提问:冠 军在1-16号吗?依次询问,只需要五次,
就可以知道结果。
该案例中信息熵为:
− ( 1 32 l o g ( 1 32 ) + 1 32 l o g ( 1 32 ) + . . . ) = 5 -(\frac{1}{32}log(\frac{1}{32}) + \frac{1}{32}log(\frac{1}{32}) + ...) = 5 −(321log(321)+321log(321)+...)=5
信息增益
信息增益表示得知特征 A A A 的信息而使得类 Y Y Y 的信息的不确定性减少的程度。
g ( D , A ) g(D,A) g(D,A): 特征 A A A 对训练数据集 D D D 的信息增益为:
g ( D , A ) = H ( D ) − H ( D ∣ A ) g(D,A) = H(D) - H(D|A) g(D,A)=H(D)−H(D∣A)
其中:
- g ( D , A ) g(D,A) g(D,A): 特征 A A A 对训练数据集 D D D 的信息增益,
- H ( D ) H(D) H(D)(初始信息熵): 集合 D D D 的信息熵
- H ( D ∣ A ) H(D|A) H(D∣A)(条件熵): 特征 A A A 给定条件下 D D D 的信息条件熵
https://zh.wikipedia.org/wiki/%E7%9B%B8%E5%AF%B9%E7%86%B5
H ( D i ) = − ∑ k = 1 K ∣ C k ∣ ∣ D i ∣ l o g ∣ C k ∣ ∣ D i ∣ H ( D ∣ A ) = ∑ i = 1 n ∣ D i ∣ ∣ D ∣ H(D_i) = - \displaystyle\sum_{k=1}^{K} \frac{|C_k|}{|D_i|}log\frac{|C_k|}{|D_i|} \\ H(D|A) = \displaystyle\sum_{i=1}^{n}\frac{|D_i|}{|D|} H(Di)=−k=1∑K∣Di∣∣Ck∣log∣Di∣∣Ck∣H(D∣A)=i=1∑n∣D∣∣Di∣
其中: K K K 为样本类别总量, C k C_k Ck 为类别 k k k 的样本数量。
常见决策树使用的算法
- ID3: 信息增益 最大的准则
- C4.5: 信息增益比 最大的准则
- CART
- 回归树: 平方误差 最小
- 分类树: 基尼系数 ,划分更加仔细 最小的准则 在sklearn中可以选择划分的默认原则
案例
https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html
import pandas as pd
from sklearn.feature_extraction import DictVectorizer
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, export_graphviz
# 泰坦尼克号乘客生存分析
# 一、pd读取数据
titanic = pd.read_csv("https://hbiostat.org/data/repo/titanic.txt")
# 二、处理数据
# 1.取出特征值与目标值
x = titanic[['pclass', 'age', 'sex']]
y = titanic['survived']
# 2.处理缺失值
x['age'].fillna(x['age'].mean(), inplace=True)
# 3.分割数据集到训练集与测试集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)
# 三、进行特征工程
# 1.特征抽取
# 将有类别特征的数据转换成字典数据,x_train.to_dict(orient = 'records')
# 然后再把字典中一些类别数据,分别转换成特征(one-hot编码)
dict = DictVectorizer(sparse=False)
x_train = dict.fit_transform(x_train.to_dict(orient='records'))
# transform按照原先标准转换
x_test = dict.transform(x_test.to_dict(orient='records'))
# 返回类别数据
print(dict.get_feature_names())
print(x_train)
# 四、决策树估计器流程
dec = DecisionTreeClassifier()
dec.fit(x_train, y_train)
# 得到预测结果
print('预测结果为:\n', dec.predict(x_test))
# 预测准确率
print('预测准确率为:\n', dec.score(x_test, y_test))
# 导出决策树的结构
export_graphviz(dec, out_file='./tree.dot', feature_names=['年龄', '一等', '二等', '三等', '女', '男'])
dot -Tpdf tree.dot > tree.pdf
决策树的优点与缺点
注:企业重要决策,由于决策树很好得分析能力,在决策过程应用较多
优点:
- 简单的理解和解释,树木可视化。
- 需要很少的数据准备,其他技术通常需要数据归一化,
缺点:
- 决策树学习者可以创建不能很好地推广数据的过于复杂的树,这被称为过拟合。
- 决策树可能不稳定,因为数据的小变化可能会导致完全不同的树被生成
随机森林
定义:在机器学习中,随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定。
集成学习方法
集成学习通过建立几个模型组合的来解决单一预测问题。它的工作原理是生成多个分类器/模型,
各自独立地学习和作出预测。这些预测最后结合成单预测,因此优于任何一个单分类的做出预测。
算法原理介绍
根据下列算法而建造每棵树:
用N来表示训练用例(样本)的个数,M表示特征数目。
- 从N个训练用例(样本)中以有放回抽样的方式每次取一个,取样N次,形成一个训练集(即bootstrap取样:随机有放回的抽样),并用未抽到的用例(样本)作预测,评估其误差。
- 输入特征数目m,用于确定决策树上一个节点的决策结果;其中m应远小于M。
为什么要随机抽样训练集?
- 如果不进行随机抽样,每棵树的训练集都一样,那么最终训练出的树分类结果也是完全一样的
为什么要有放回地抽样?
- 如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都是没有交集的,这样每棵树都是“有偏的”,都是绝对“片面的”(当然这样说可能不对),也就是说每棵树训练出来都是有很大的差异的;而随机森林最后分类取决于多棵树(弱分类器)的投票表决。
案例
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_extraction import DictVectorizer
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import train_test_split
# 一.读取数据
titanic = pd.read_csv("https://hbiostat.org/data/repo/titanic.txt")
# 二、处理数据
# 1.提取特征值与目标值
x = titanic[['pclass', 'age', 'sex']]
y = titanic['survived']
# 2.处理age中的缺失值
x['age'].fillna(x['age'].mean(), inplace=True)
# 3.分割数据集 训练集与测试集、
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)
# 三、进行特征工程
# 特征抽取
# 将特征值的类别特征数据转换成字典数据
# 再将类别数据转换成one-hot编码
dict = DictVectorizer(sparse=False)
x_train = dict.fit_transform(x_train.to_dict(orient='records'))
x_test = dict.transform(x_test.to_dict(orient='records'))
# 返回类别数据
print(dict.get_feature_names())
print(x_train)
# 四、随机森林-模型的选择与调优
# 1.构造实例
rf = RandomForestClassifier()
# 2.交叉验证与网格搜索
# n_estimators:决策树的数量
# max_depth:每棵树的深度限制
param = {'n_estimators': [100, 200, 300, 500, 800, 1200], 'max_depth': [5, 8, 15, 25, 30]}
gc = GridSearchCV(rf, param_grid=param, cv=5)
gc.fit(x_train, y_train)
# 准确率
print('准确率是:\n', gc.score(x_test, y_test))
# 在交叉验证中最好的结果
print('交叉验证中最好的结果是:\n', gc.best_score_)
# 最好的参数模型
print('最好的参数模型:\n', gc.best_estimator_)
# 查看选择的参数模型
print('查看选择的参数模型:\n', gc.best_params_)
随机森林的优点与缺点
随机森林的优点:
- 在当前所有算法中,具有极好的准确率
- 能够有效地运行在大数据集上
- 能够处理具有高维特征的输入样本,而且不需要降维
- 能够评估各个特征在分类问题上的重要性
- 对于缺省值问题也能够获得很好得结果