一 决策树简介
1.1 定义
是一种树形结构,本质是一颗由多个判断节点组成的树
1.2 信息熵
(1)定义
- 从信息的完整性上进行的描述:
当系统的有序状态一致时,数据越集中的地方熵值越小,数据越分散的地方熵值越大。 - 从信息的有序性上进行的描述:
当数据量一致时,系统越有序,熵值越低;系统越混乱或者分散,熵值越高。
(2)信息熵公式
Ent(D):
二 决策树划分依据
2.1 信息增益
使用划分前后集合熵的差值来衡量使用当前特征对于样本集合D划分效果的好坏。
公式:
Dv表示a属性中第v个分支节点包含的样本数(<性别>属性中<男性>分支中包含的样本数)
Ckv表示a属性中第v个分支节点包含的样本数中,第k个类别下包含的样本数(<男性>分支下<成绩好坏>类别分别包含的样本数)
ID3 决策树学习算法是以信息增益为准则来选择划分属性
2.2 信息增益率
C4.5 决策树算法 是使用"增益率" 来选择最优划分属性
公式:
IV(a)也叫属性分裂信息度量
算法流程:
while(当前节点"不纯"):
1.计算当前节点的类别熵(以类别取值计算)
2.计算当前阶段的属性熵(按照属性取值吓得类别取值计算)
3.计算信息增益
4.计算各个属性的分裂信息度量
5.计算各个属性的信息增益率
end while
当前阶段设置为叶子节点
2.3 基尼值和基尼指数
CART 决策树使用"基尼指数" (Gini index)来选择划分属性
基尼值Gini(D):从数据集D中随机抽取两个样本,其类别标记不一致的概率,Gini(D)值越小,数据集D的纯度越高
公式:
基尼指数Gini_index(D):
三 cart剪枝
剪枝 (pruning)是决策树学习算法对付"过拟合"的主要手段
3.1 预剪枝
预剪枝是指在决策树生成过程中,对每个结点在划分前先进行估计,若当前结点的划分不能带来决策树泛化性能提升,则停止划分并将当前结点标记为叶结点
3.2 后剪枝
后剪枝则是先从训练集生成一棵完整的决策树,然后自底向上地对非叶结点进行考察,若将该结点对应的子树替换为叶结点能带来决策树泛化性能提升,则将该子树替换为叶结点
3.3 两种剪枝方法对比
- 后剪枝保留了更多的分支
- 后剪枝欠拟合风险很小,泛化性能往往优于预剪枝
- 后剪枝在生成完全决策树之后进行的,其训练时间开销大,内存要求高
四 决策树API
4.1 决策树API
sklearn.tree.DecisionTreeClassifier(criterion=’gini’, max_depth=None,random_state=None)
criterion:“gini”(基尼指数)或者"entropy"(信息增益),默认"gini"
min_samples_split:内部节点再划分所需最小样本数。默认是2,如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。比如大概10万样本,min_samples_split=10,可以作为参考。
min_samples_leaf:叶子节点最少样本数,默认是1,如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。10万样本使用min_samples_leaf=5,仅供参考
max_depth:决策树最大深度,一般来说,数据少或者特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,推荐限制这个最大深度,具体的取值取决于数据的分布。常用的可以取值10-100之间
from sklearn.tree import DecisionTreeClassifier
# 4.机器学习(决策树)
estimator = DecisionTreeClassifier(criterion="entropy", max_depth=5)
estimator.fit(x_train, y_train)
4.2 可视化决策树
tree.export_graphviz(estimator,out_file='tree.dot’,feature_names=[‘’,’’])
保存的文件格式为dot
# 注意:feature_names中每一个类别都需要指定
export_graphviz(estimator, out_file="./tree.dot", feature_names=['age', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', '女性', '男性'])
在该网站上可以绘制决策树:决策树可视化
五 特征工程—特征提取
特征提取分类:
(1)字典特征提取(特征离散化)
(2)文本特征提取
(3)图像特征提取
5.1 字典特征提取
sklearn.feature_extraction.DictVectorizer(sparse=True,…)
方法:
特征转化:DictVectorizer.fit_transform(X),返回sparse矩阵
返回类别名称:DictVectorizer.get_feature_names()
from sklearn.feature_extraction import DictVectorizer
# 将数据转换成字典格式
# x.to_dict(orient="records") 需要将数组特征转换成字典数据
data.to_dict(orient="records")
# 1、实例化一个转换器类
transfer = DictVectorizer(sparse=False)
# 2、调用fit_transform
data = transfer.fit_transform(data)
print(data)
# 打印特征名字
transfer.get_feature_names()
什么是sparse矩阵??
当sparse= False:输出”one-hot“编码形式
当sparse= True:输出有内容位置,能提高效率,节省内存。如(0,3)100表示在第0行第3列有内容100。
5.2 文本特征提取
(1)英文
sklearn.feature_extraction.text.CountVectorizer(stop_words=[ ])
参数:
stop_words:停用词,一些语气词,虚词等无含义的词不需要进行统计,可放入停用词中
方法:
CountVectorizer.fit_transform(X)
CountVectorizer.get_feature_names()
注意:
(1)单个字母和标点符号不进行统计
(2)没有sparse参数,用toarray()可转换成”one-hot“编码形式
(3)返回结果中的数字代表该词出现的频率
from sklearn.feature_extraction.text import CountVectorizer
# 1、实例化一个转换器类
transfer = CountVectorizer()
# 2、调用fit_transform
data = transfer.fit_transform(data)
print(data.toarray())
transfer.get_feature_names()
(2)中文
jieba分词处理:
jieba.cut()
返回词语组成的生成器
from sklearn.feature_extraction.text import TfidfVectorizer
import jieba
text = " ".join(list(jieba.cut(text)))
text_list = []
for sent in data:
text_list.append(cut_word(sent))
print(text_list)
# 1、实例化一个转换器类
transfer = CountVectorizer()
# 2、调用fit_transform
data = transfer.fit_transform(text_list)
print(data.toarray())
transfer.get_feature_names()
(3)Tf-idf文本特征提取
如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语能很好的区分该篇文章
词频(term frequency,tf):某一个给定的词语在该文件中出现的频率
逆向文档频率(inverse document frequency,idf):一个词语普遍重要性的度量。可以由总文件数目除以包含该词语之文件的数目,再将得到的商取以10为底的对数得到
from sklearn.feature_extraction.text import TfidfVectorizer
# 1、实例化一个转换器类
transfer = TfidfVectorizer(stop_words=['一种', '不会', '不要'])
# 2、调用fit_transform
data = transfer.fit_transform(text_list)