决策树
**决策树:**是一种树形结构,其中每个内部节点表示一个属性上的判断,每个分支代表一个判断结果的输出,最后每个叶节点代表一种分类结果,本质是一颗由多个判断节点组成的树。决策树算法的目的是为了产生一颗泛化能力强,即处理未见实例能力强的决策树。我们要找到信息增益最大的分支结点
一、 决策树分类原理
熵:
1、从信息的完整性上进行的描述:
当系统的有序状态一致时,数据越集中的地方熵值越小,数据越分散的地方熵值越大。
2、从信息的有序性上进行的描述:
当数据量一致时,系统越有序,熵值越低;系统越混乱或者分散,熵值越高。
"信息熵" (information entropy)是度量样本集合纯度最常用的一种指标,也就是熵值越小越好。
**信息增益:**以某特征划分数据集前后的熵的差值。熵可以表示样本集合的不确定性,熵越大,样本的不确定性就越大。因此可以使用划分前后集合熵的差值来衡量使用当前特征对于样本集合D划分效果的好坏。
一般而言,信息增益越大,则意味着使用属性 a 来进行划分所获得的"纯度提升"越大
信息增益 = entroy(前) - entroy(后)
案例
我们要解决一个问题:性别和活跃度两个特征,哪个对用户流失影响更大?
通过计算信息增益可以解决这个问题,统计上右表信息
其中Positive为正样本(已流失),Negative为负样本(未流失),下面的数值为不同划分下对应的人数。
可得到三个熵:
a.计算类别信息熵
整体熵:
b.计算性别属性的信息熵(a=“性别”)
c.计算性别的信息增益(a=“性别”)
b.计算活跃度属性的信息熵(a=“活跃度”)
c.计算活跃度的信息增益(a=“活跃度”)
活跃度的信息增益比性别的信息增益大,也就是说,活跃度对用户流失的影响比性别大。在做特征选择或者数据分析的时候,我们应该重点考察活跃度这个指标。
**信息增益率:**增益率是用前面的信息增益Gain(D, a)和属性a对应的"固有值"(intrinsic value) [Quinlan , 1993J的比值来共同定义的。
基尼值和基尼指数
CART 决策树 [Breiman et al., 1984] 使用"基尼指数" (Gini index)来选择划分属性.
基尼值Gini(D):从数据集D中随机抽取两个样本,其类别标记不一致的概率。故,Gini(D)值越小,数据集D的纯度越高。
数据集 D 的纯度可用基尼值来度量:
while(当前节点"不纯"):
‘’‘’ 1.遍历每个变量的每一种分割方式,找到最好的分割点
‘’‘’ 2.分割成两个节点N1和N2
end while
每个节点足够“纯”为止
二、 剪枝处理
**预剪枝:**提高泛化能力
**后剪枝:**解决过拟合问题
三、特征工程-特征提取
将任意数据(如文本或图像)转换为可用于机器学习的数字特征。
特征提取分类:
1.字典特征提取(特征离散化)
2.文本特征提取
3.图像特征提取(深度学习将介绍)
特征提取API
sklearn.feature_extraction
字典特征提取
sklearn.feature_extraction.DictVectorizer(sparse=True,…)
DictVectorizer.fit_transform(X)X:字典或者包含字典的迭代器返回值
返回sparse矩阵DictVectorizer.get_feature_names() 返回类别名称
文本特征提取
作用:对文本数据进行特征值化
sklearn.feature_extraction.text.CountVectorizer(stop_words=[])
返回词频矩阵
CountVectorizer.fit_transform(X)
X:文本或者包含文本字符串的可迭代对象
返回值:返回sparse矩阵CountVectorizer.get_feature_names() 返回值:单词列表
sklearn.feature_extraction.text.TfidfVectorizer
中文文本提取
jieba.cut()
返回词语组成的生成器
Tf-idf文本特征提取
用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。
四、 决策树算法api
class sklearn.tree.DecisionTreeClassifier(criterion=’gini’,max_depth=None,random_state=None)
criterion
特征选择标准
“gini"或者"entropy”,前者代表基尼系数,后者代表信息增益。一默认"gini",即CART算法。
min_samples_split
内部节点再划分所需最小样本数
这个值限制了子树继续划分的条件,如果某节点的样本数少于min_samples_split,则不会继续再尝试选择最优特征来进行划分。
默认是2.如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。我之前的一个项目例子,有大概10万样本,建立决策树时,我选择了min_samples_split=10。可以作为参考。
min_samples_leaf
叶子节点最少样本数
这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝。
默认是1,可以输入最少的样本数的整数,或者最少样本数占样本总数的百分比。如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。之前的10万样本项目使用min_samples_leaf的值为5,仅供参考。
max_depth 决策树最大深度
决策树的最大深度,默认可以不输入,如果不输入的话,决策树在建立子树的时候不会限制子树的深度。一般来说,数据少或者特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,推荐限制这个最大深度,具体的取值取决于数据的分布。常用的可以取值10-100之间
random_state 随机数种子
案例:泰坦尼克号乘客生存预测
我们提取到的数据集中的特征包括票的类别,是否存活,乘坐班次,年龄,登陆home.dest,房间,船和性别等。
数据:http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt
代码:
import pandas as pd
import numpy as np
from sklearn.feature_extraction import DictVectorizer
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, export_graphviz
#1.获取数据
# 1、获取数据
titan = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")
#2.数据基本处理
#2.1 确定特征值,目标值
x = titan[["pclass", "age", "sex"]]
y = titan["survived"]
#2.2 缺失值处理
# 缺失值需要处理,将特征当中有类别的这些特征进行字典特征抽取
x['age'].fillna(x['age'].mean(), inplace=True)
#2.3 数据集划分
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)
#3.特征工程(字典特征抽取)
#特征中出现类别符号,需要进行one-hot编码处理(DictVectorizer)
#x.to_dict(orient="records") 需要将数组特征转换成字典数据
# 对于x转换成字典数据x.to_dict(orient="records")
# [{"pclass": "1st", "age": 29.00, "sex": "female"}, {}]
transfer = DictVectorizer(sparse=False)
x_train = transfer.fit_transform(x_train.to_dict(orient="records"))
x_test = transfer.fit_transform(x_test.to_dict(orient="records"))
#4.决策树模型训练和模型评估
#决策树API当中,如果没有指定max_depth那么会根据信息熵的条件直到最终结束。这里我们#可以指定树的深度来进行限制树的大小
# 4.机器学习(决策树)
estimator = DecisionTreeClassifier(criterion="entropy", max_depth=5)
estimator.fit(x_train, y_train)
# 5.模型评估
estimator.score(x_test, y_test)
estimator.predict(x_test)
准确率:
0.790273556231003
array([0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0,
1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0,
0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1],
dtype=int64)
五、决策树可视化
保存树的结构到dot文件
sklearn.tree.export_graphviz() 该函数能够导出DOT格式
tree.export_graphviz(estimator,out_file='tree.dot’,feature_names=[‘’,’’])
export_graphviz(estimator, out_file="E:\\tree.dot", feature_names=['age', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', '女性', '男性'])
使用该网站http://webgraphviz.com/可显示决策树