决策树
信息熵
公式: H ( X ) = − ∑ x ∈ X P ( x ) l o g P ( x ) H(X)=-\sum_{x\in X}P(x)logP(x) H(X)=−∑x∈XP(x)logP(x),H(X)称为X的信息熵,反映了X的信息量。
信息增益:g(D,A) = H(D)-H(D|A)为得知特征A下使得D的信息不确定性减少的程度。
信息增益的计算
H
(
D
)
=
−
∑
k
=
1
K
∣
C
k
∣
∣
D
∣
l
o
g
∣
C
k
∣
∣
D
∣
H(D)=-\sum_{k=1}^{K}\frac{|C_k|}{|D|}log\frac{|C_k|}{|D|}
H(D)=−∑k=1K∣D∣∣Ck∣log∣D∣∣Ck∣
H
(
D
∣
A
)
=
∑
i
=
1
n
∣
D
i
∣
∣
D
∣
H
(
D
i
)
H(D|A)=\sum_{i=1}^{n}\frac{|D_i|}{|D|}H(D_i)
H(D∣A)=∑i=1n∣D∣∣Di∣H(Di) = H(D,A) - H(A)
信息增益:g(D,A) = H(D) - H(D|A)
其中
C
k
C_k
Ck表示属于某个类别的样本数
决策树
- 常见决策树使用的算法
- ID3:信息增益,最大的准则
- C4.5:信息增益比最大的准则
- CART
- 回归树:平方误差,最小的准则
- 分类数:基尼系数,最小的准则,在sklearn中可以选择划分的原则
sklearn决策树API:sklearn.tree
- sklearn.tree.DecisionTreeClassifier(criterion = ‘gini’, max_depth = None, random_state = None)
- 决策树分类器
- criterion:默认是’gini’系数,也可以选择信息增益的熵’entropy’
- max_depth:树的深度大小
- random_state:随机数种子
- method:
- decision_path:返回决策树的路径
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
from sklearn.tree import DecisionTreeClassifier, export_graphviz
# 导入数据
titan = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")
# 处理数据,找出特征值和目标值
x = titan[['pclass', 'age', 'sex']]
y = titan['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)
# 特征工程
dict = DictVectorizer(sparse=False)
# 要先将数据转换成字典格式再进行字典特征抽取,转换成One-hot编码
x_train = dict.fit_transform(x_train.to_dict(orient="records"))
x_test = dict.transform(x_test.to_dict(orient="records"))
# 用决策树进行预测
dec = DecisionTreeClassifier()
dec.fit(x_train, y_train)
print("预测的准确率:", dec.score(x_test, y_test))
决策树的结构、本地保存
- sklearn.tree.export_graphviz() 该函数能够导出DOT格式
- tree.export_graphviz(estimator,out_file='tree.dot’,feature_names=[‘’,’’])
- 工具:(能够将dot文件转换为pdf、png)
- 安装graphviz
- ubuntu:sudo apt-get install graphviz ,Mac:brew install graphviz
- 运行命令
- $ dot -Tpng tree.dot -o tree.png
# 导出决策树的结构
export_graphviz(dec, out_file="./tree.dot", feature_names=['年龄', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', '女性', '男性'])
决策树的优缺点以及改进
- 优点:
- 简单的理解和解释,树木可视化。
- 需要很少的数据准备,其他技术通常需要数据归一化。
- 缺点:
- 决策树学习者可以创建不能很好地推广数据的过于复杂的树,这被称为过拟合。
- 决策树可能不稳定,因为数据的小变化可能会导致完全不同的树被生成。
- 改进:
- 减枝cart算法
- 随机森林
决策树的评价
- 假定样本的总类别为K个
- 对于决策树的某叶结点,假定该叶结点含有样本数目为n,其中第k类的样本点数目为
n
k
,
k
=
1
,
2
,
.
.
.
,
K
n_k,\ k=1,2,...,K
nk, k=1,2,...,K.
- 若某类样本 n j = n n_j=n nj=n而 n 1 , . . . , n j − 1 , n j + 1 , . . . , n K = 0 n_1,...,n_{j-1},n_{j+1},...,n_K=0 n1,...,nj−1,nj+1,...,nK=0,称该结点为纯结点;
- 若各类样本数目 n 1 = n 2 = . . . = n k = n / K n_1=n_2=...=n_k=n/K n1=n2=...=nk=n/K,称该样本为均结点。
- 纯结点的熵为0,最小
- 均结点的熵为lnK,最大
- 对所有叶结点的熵求和,该值越小说明对样本的分类越精确。
- 各叶结点包含的样本数目不同,可使用样本数加权求熵和
- 评价函数:
C
(
T
)
=
∑
t
∈
l
e
a
f
N
t
⋅
H
(
t
)
C(T)=\sum_{t\in leaf}N_t\cdot H(t)
C(T)=∑t∈leafNt⋅H(t)
- 由于该评价函数越小越好,所以,可以称为“损失函数”。
剪枝
- 总体思路:
- 由完全树 T 0 T_0 T0开始,剪枝部分结点得到 T 1 T_1 T1,再次剪枝部分结点得到 T 2 T_2 T2,…,直到仅剩树根的树 T k T_k Tk;
- 在验证数据集上对这k个树分别评价,选择损失函数最小的树 T α T_{\alpha} Tα
- 剪枝系数的缺点
- 根据原损失函数 C ( T ) = ∑ t ∈ l e a f N t H ( t ) C(T)=\sum_{t\in leaf}N_tH(t) C(T)=∑t∈leafNtH(t)
- 叶结点越多,决策树越复杂,损失越大,修正:
- 当 α = 0 \alpha=0 α=0时,未剪枝的决策树损失最小; C α = C ( T ) + α ∣ T l e a f ∣ C_{\alpha}=C(T)+\alpha |T_{leaf}| Cα=C(T)+α∣Tleaf∣
- 当 α = ∞ \alpha = \infty α=∞时,单根结点的决策树损失最小。
- 假定当前对以r为根的子树剪枝:
- 剪枝后,只保留r本身而删掉所有的叶子
- 考察以r为根的子树:
- 剪枝后的损失函数 C α ( r ) = C ( r ) + α C_{\alpha}(r)=C(r)+\alpha Cα(r)=C(r)+α
- 剪枝前的算是函数 C α ( R ) = C ( R ) + α ∣ R l e a f ∣ C_{\alpha}(R)=C(R)+\alpha |R_{leaf}| Cα(R)=C(R)+α∣Rleaf∣
- 令二者相等,求得: α = ( C ( r ) − C ( R ) ) / ( < R l e a f > − 1 ) \alpha=(C(r)-C(R))/(<R_{leaf}>-1) α=(C(r)−C(R))/(<Rleaf>−1)
- α \alpha α称为结点r的剪枝系数。
随机森林
集成学习方法:通过建立几个模型组合的来解决单一预测问题。它的工作原理是生成多个分类器/模型,各自独立地学习和作出预测。这些预测最后结合成单预测,因此优于任何一个单分类的做出预测
随机森林:在机器学习中,随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定。
- 根据下列算法而建造每棵树:
- 用N来表示训练用例(样本)的个数,M表示特征数目。
- 输入特征数目m,用于确定决策树上一个节点的决策结果;其中m应远小于M。
- 从N个训练用例(样本)中以有放回抽样的方式,取样N次,形成一个训练集(即bootstrap取样),并用未抽到的用例(样本)作预测,评估其误差。
集成学习API:sklearn.ensemble
- sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion=’gini’,
max_depth=None, bootstrap=True, random_state=None)- 随机森林分类器
- n_estimators:integer,optional(default = 10)森林里的树木数量
一般取120,200,300,500,800,1200 - criteria:string,可选(default = ‘gini’)分割特征的测量方法
- max_depth:integer或None,可选(默认= 无)树的最大深度
一般取5,8,15,25,30 - max_feature=“auto”,每个决策树的最大特征数量
- If “auto”, then ‘max_feature=sqrt(n_features)’
- If “sqrt”, then ‘max_feature=sqrt(n_features)’
- If “log2”, then ‘max_feature=log2(n_features)’
- If None, then ‘max_feature=n_features’
- bootstrap:boolean,optional(default = True)是否在构建树时使用放回抽样
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
from sklearn.ensemble import RandomForestClassifier
# 随机森林进行预测 (超参数调优)
rf = RandomForestClassifier()
param = {"n_estimators": [120, 200, 300, 500, 800, 1200], "max_depth": [5, 8, 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_)
随机森林的优点:
- 在当前所有算法中,具有极好的准确率
- 能够有效的运行在大数据集上
- 能够处理具有高维特征的输入样本,而且不需要降维
- 能够评估各个特征在分类问题上的重要性
- 对于缺省值问题也能够获得很好的结果