沛县微网站开发,东莞网站建设 胶粘包装材料,网页游戏平台哪个好,wordpress上传新建lp决策树分类算法 1. 什么是决策树#xff1f;2. DecisionTreeClassifier的使用#xff08;sklearn#xff09;2.1 算例介绍2.2 构建决策树并实现可视化 3. 决策树分裂指标3.1 信息熵#xff08;ID3#xff09;3.2 信息增益3.3 基尼指数#xff08;CART#xff09; 4. 代码… 决策树分类算法 1. 什么是决策树2. DecisionTreeClassifier的使用sklearn2.1 算例介绍2.2 构建决策树并实现可视化 3. 决策树分裂指标3.1 信息熵ID33.2 信息增益3.3 基尼指数CART 4. 代码实现选择最优划分属性5. 鸢尾花分类实战 1. 什么是决策树 决策树属于有监督机器学习的一种起源非常早符合直觉并且非常直观模仿人类做决策的过程早期人工智能模型中有很多应用现在更多的是使用基于决策树的一些集成学习的算法。这一章我们先把决策树算法理解透彻有利于后面学习集成学习。
1. 示例一
我们有如下数据
ID拥有房产是/否婚姻[单身已婚离婚]年收入单位千元无法偿还债务是/否1是单身125否2否已婚100否3否单身70否4是已婚120否5否离婚95是6否已婚60否7是离婚220否8否单身85是9否已婚75否10否单身90是
上表根据历史数据记录已有的用户是否可以偿还债务以及相关的信息。通过该数据构建的决策树如下 比如新来一个用户无房产单身年收入55K那么根据上面的决策树可以预测他无法偿还债务蓝色虚线路径。从上面的决策树还可以知道是否拥有房产可以很大程度上决定用户是否可以偿还债务对借贷业务具有指导意义。
2. 示例二
女孩母亲要给她介绍对象女孩问母亲该对象的具体情况年龄是多少母亲说24。长得帅吗挺帅的。收入高吗中等收入。是公务员吗母亲说是的。女孩决定去见见。由此也可以构建出一棵决策树 上面那棵树中属性为绿色的节点年龄、长相、收入、是否是公务员 一般使用X表示。跟属性对应的是目标值橘色节点一般使用y表示。构建这棵树时每个人标准不同树结构不同。那么用计算机该如何构建决策树呢划分的标准又是什么。 2. DecisionTreeClassifier的使用sklearn 2.1 算例介绍 接下来我们要用sklearn现成的方法解决区分一个用户是真人还是机器的问题。训练集数据如下
ID日志密度好友密度真实头像账号真伪0ssNN1slYY2lmYY3mmYY4lmYY5mlNY6msYN7lmYY8msYY9ssYN
其中s、m和l分别表示小、中和大。账号是否真实跟属性日志密度、好友密度、是否使用真实头像有关系。 2.2 构建决策树并实现可视化 1. 构建决策树
import numpy as np
import pandas as pd
from sklearn.tree import DecisionTreeClassifiery np.array(list(NYYYYYNYYN)) # 目标值
X pd.DataFrame({日志密度:list(sslmlmmlms),好友密度:list(slmmmlsmss),真实头像:list(NYYYYNYYYY)})# 整理数据将字符类型转化为整型
X[日志密度] X[日志密度].map({s:0, m:1, l:2})
X[好友密度] X[好友密度].map({s:0, m:1, l:2})
X[真实头像] X[真实头像].map({N:0, Y:1})# 建模和预测
model DecisionTreeClassifier() # 默认划分标准是基尼指数model.fit(X, y) # 训练模型
model.score(X, y) # 训练集评估2. 实现可视化
sklearn的tree模块中提供了丰富的可视化功能。
# 决策树可视化
from sklearn import tree
import matplotlib.pyplot as pltplt.rcParams[font.family] STKaiti # 修改字符显示
plt.figure(figsize(12, 12))
fn X.columns # 拿出属性名tree.plot_tree(model, filledTrue, feature_namesfn)大家可以看到上图形成的是一棵二叉树。今天我们所学习的二叉树默认引入二分法连续值处理机制。
3. 使用信息熵来生成决策树
model DecisionTreeClassifier(criterionentropy) # 指定划分标准为entropymodel.fit(X, y)
model.score(X, y)# 决策树可视化
from sklearn import tree
import matplotlib.pyplot as pltplt.rcParams[font.family] STKaiti
plt.figure(figsize(12, 12))
fn X.columnstree.plot_tree(model, filledTrue, feature_namesfn)还可以配合graphviz来实现可视化大家可以去看我的另一篇博客。 3. 决策树分裂指标 3.1 信息熵ID3 1. 概念
在物理学热力第二定律中描述的是封闭系统中的混乱程度。今天在机器学习的理念中描述的是一个样本集的纯粹程度。
2. 公式 H ( x ) − ∑ i 1 n p ( x ) l o g 2 p ( x ) H(x) -\sum\limits_{i 1}^n p(x)log_2p(x) H(x)−i1∑np(x)log2p(x) H ( x ) ∑ i 1 n p ( x ) l o g 2 1 p ( x ) H(x) \sum\limits_{i 1}^n p(x)log_2\frac{1}{p(x)} H(x)i1∑np(x)log2p(x)1
其中 p ( x ) p(x) p(x) 表示某类样本出现的概率。放在上面的例子中就是样本集中真假账号的占比。
3. 手动计算信息熵用到的数据还是2中的Xy
未分类的信息熵根节点信息熵
y np.array(list(NYYYYYNYYN))
X pd.DataFrame({日志密度:list(sslmlmmlms),好友密度:list(slmmmlsmss),真实头像:list(NYYYYNYYYY)})
X[真实用户] y # 把目标值这一列也添加进XX[日志密度] X[日志密度].map({s:0, m:1, l:2})
X[好友密度] X[好友密度].map({s:0, m:1, l:2})
X[真实头像] X[真实头像].map({N:0, Y:1})p1 (y N).mean() # N类型数据的占比
p2 (y Y).mean() # Y类型数据的占比
entropy p1 * np.log2(1/p1) p2 * np.log2(1/p2) # 0.8812908992306926
print(entropy)
输出
0.8812908992306926按照日志密度进行划分后得到的子样本信息熵带权加和 如果按照日志密度进行划分可选的二分划分点有两个[0.5, 1.5]因为日志密度的取值为[0, 1, 2]。这里的entropy不再是单纯的信息熵而是每个划分后子节点的信息熵带权加和。权重就是子节点样本数占根节点的比重。这里之所以计算的是子样本信息熵的带权加和而不是单独各个子样本的信息熵是为了之后计算信息增益做准备。
x X[日志密度].unique()
# 拿到的结果可能是乱序的我们排一下序
x.sort() # [0, 1, 2]for i in range(len(x) - 1):split x[i:i2].mean() # 遍历划分点cond X[日志密度] split # 分成两边每一边分别计算信息熵# 计算概率分布p cond.value_counts()/cond.size # 得到的p是Series类型数据索引是True, Flase值是比率indexs p.index # 拿到索引True, Falseentropy 0 # 信息熵for index in indexs:sub X[cond index][真实用户]# 子节点的概略分布p_sub sub.value_counts()/sub.size# 每个分支节点的信息熵带权加和权重是p[index]entropy (p_sub * np.log2(1/p_sub)).sum() * p[index]print(split, entropy)
输出
0.5 0.689659695223976
1.5 0.689659695223976上面我们用sklearn形成的决策树中根节点很明显是根据好友密度划分的为什么不能先根据日志密度或者其他属性划分这个最优划分属性又是如何确定的 3.2 信息增益 1. 概念及公式
信息增益是指通过某个属性划分后事件的不确定性下降的程度。写作 g ( X , y ) g(X,y) g(X,y)。它的计算方式为熵减去条件熵公式如下 g ( X , y ) H ( Y ) − H ( Y ∣ X ) g(X,y) H(Y) - H(Y|X) g(X,y)H(Y)−H(Y∣X)
表示的是知道了某个条件后原来事件不确定性降低的幅度。那这个值肯定越大越好。这个 H ( Y ) H(Y) H(Y) 指的就是根节点信息熵 H ( Y ∣ X ) H(Y|X) H(Y∣X) 指的就是子节点信息熵带权加和。
2. 对比不同属性的信息增益
使用日志密度划分的信息增益 之前已经算过了划分点为0.5或1.5得到的条件熵一样为0.689任选一个。根节点的信息熵为0.811。故信息增益为0.881 - 0.689 0.192。 使用好友密度划分的信息增益 最优的划分点是0.5此时条件熵为0.324最小。故信息增益为0.881 - 0.324 0.557。
x X[好友密度].unique()
# 拿到的结果可能是乱序的我们排一下序
x.sort() for i in range(len(x) - 1):split x[i:i2].mean() # 遍历划分点cond X[好友密度] split # 分成两边每一边分别计算信息熵# 计算概率分布p cond.value_counts()/cond.size # 得到的p是Series类型数据索引是True, Flase值是比率indexs p.index # 拿到索引True, Falseentropy 0 # 信息熵for index in indexs:sub X[cond index][真实用户]# 子节点的概略分布p_sub sub.value_counts()/sub.size# 每个分支节点的信息熵带权加和权重是p[index]entropy (p_sub * np.log2(1/p_sub)).sum() * p[index]print(split, entropy)
输出
0.5 0.32451124978365314
1.5 0.763547202339972使用真实头像划分的信息增益 只有一个划分点0.5条件熵为0.849故信息增益为0.881 - 0.849 0.032。
x X[真实头像].unique()
# 拿到的结果可能是乱序的我们排一下序
x.sort() for i in range(len(x) - 1):split x[i:i2].mean() # 遍历划分点cond X[真实头像] split # 分成两边每一边分别计算信息熵# 计算概率分布p cond.value_counts()/cond.size # 得到的p是Series类型数据索引是True, Flase值是比率indexs p.index # 拿到索引True, Falseentropy 0 # 信息熵for index in indexs:sub X[cond index][真实用户]# 子节点的概略分布p_sub sub.value_counts()/sub.size# 每个分支节点的信息熵带权加和权重是p[index]entropy (p_sub * np.log2(1/p_sub)).sum() * p[index]print(split, entropy)
输出
0.5 0.8490224995673064使用好友密度划分得到的信息增益是最大的故选择好友密度作为最优划分属性。 3.3 基尼指数CART 1. 概念
基尼系数是指国际上通用的、用以衡量一个国家或地区居民收入差距的常用指标。基尼系数最大为“1”最小等于“0”。基尼系数越接近 0 表明收入分配越是趋向平等。国际惯例把 0.2 以下视为收入绝对平均0.2-0.3 视为收入比较平均0.3-0.4 视为收入相对合理0.4-0.5 视为收入差距较大当基尼系数达到 0.5 以上时则表示收入悬殊。基尼系数的实际数值只能介于 01 之间基尼系数越小收入分配越平均基尼系数越大收入分配越不平均。国际上通常把 0.4 作为贫富差距的警戒线大于这一数值容易出现社会动荡。Gini 系数越小代表集合中的数据越纯所有我们可以计算分裂前的值在按照某个维度对数据集进行划分然后可以去计算多个节点的 Gini 系数。
2. 公式 g i n i ∑ i 1 n p i ( 1 − p i ) gini \sum\limits_{i 1}^np_i(1 - p_i) ginii1∑npi(1−pi)
在对数据进行分类是gini系数的变化越大说明划分越纯效果越好。 4. 代码实现选择最优划分属性 1. 准备数据
import numpy as np
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn import tree
import graphvizy np.array(list(NYYYYYNYYN))
X pd.DataFrame({日志密度:list(sslmlmmlms),好友密度:list(slmmmlsmss),真实头像:list(NYYYYNYYYY),真实用户:y})X[日志密度] X[日志密度].map({s:0, m:1, l:2})
X[好友密度] X[好友密度].map({s:0, m:1, l:2})
X[真实头像] X[真实头像].map({N:0, Y:1})2. 使用sklearn生成决策树
信息熵版本
model DecisionTreeClassifier(criterionentropy)
model.fit(X.iloc[:,:-1], y)dot_data tree.export_graphviz(model, filledTrue, roundedTrue, feature_namesX.columns[:-1])graphviz.Source(dot_data)基尼指数版本
model DecisionTreeClassifier()
model.fit(X.iloc[:,:-1], y)# dot 点
dot_data tree.export_graphviz(model, filledTrue, roundedTrue, feature_namesX.columns[:-1])graphviz.Source(dot_data)3. 用信息熵选择最优划分属性
cols [日志密度, 好友密度, 真实头像]lower_entropy 1 # 最小信息熵
best_split {} # 最佳划分条件for col in cols:x X[col].unique()x.sort()for i in range(len(x) - 1): # 获取最佳划分点split x[i:i2].mean()# 概率分布cond X[col] splitp cond.value_counts() / cond.sizeindexs p.indexentropy 0for index in indexs:sub X[cond index][真实用户]# 子节点概率分布p_sub sub.value_counts() / sub.sizeentropy (p_sub * np.log2(1/p_sub)).sum() * p[index]if entropy lower_entropy:lower_entropy entropybest_split.clear()best_split[col] splitprint(最佳划分条件是, best_split)
输出
最佳划分条件是 {好友密度: 0.5}4. 使用基尼指数选择最优划分属性
cols [日志密度, 好友密度, 真实头像]lower_gini 1 # 最小信息熵
best_split {} # 最佳划分条件for col in cols:x X[col].unique()x.sort()for i in range(len(x) - 1): # 获取最佳划分点split x[i:i2].mean()# 概率分布cond X[col] splitp cond.value_counts() / cond.sizeindexs p.indexgini 0for index in indexs:sub X[cond index][真实用户]# 子节点概率分布p_sub sub.value_counts() / sub.sizegini (p_sub * (1 - p_sub)).sum() * p[index]if gini lower_gini:lower_gini ginibest_split.clear()best_split[col] splitprint(最佳划分条件是, best_split)
输出
最佳划分条件是 {好友密度: 0.5}5. 鸢尾花分类实战 1. 决策树分类鸢尾花数据集
import numpy as np
from sklearn.tree import DecisionTreeClassifier
from sklearn import datasetsfrom sklearn.model_selection import train_test_splitiris datasets.load_iris()
X iris[data] # 属性值
y iris[target] # 目标值X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.2, random_state256)model DecisionTreeClassifier(criteriongini)
model.fit(X_train, y_train)# 测试数据得分
print(测试数据得分, model.score(X_test, y_test))print(算法预测的结果: , model.predict(X_test))
print(真实的结果是: , y_test)
输出
测试数据得分 0.9666666666666667
算法预测的结果: [0 2 2 0 2 1 0 1 1 1 2 2 2 0 0 1 2 1 0 2 1 0 1 1 2 0 0 1 0 0]
真实的结果是: [0 2 1 0 2 1 0 1 1 1 2 2 2 0 0 1 2 1 0 2 1 0 1 1 2 0 0 1 0 0]2. 可视化
import graphviz
from sklearn import treefeature_names iris[feature_names] # 特征名
dot_data tree.export_graphviz(model, filledTrue, roundedTrue, feature_namesfeature_names)
graph graphviz.Source(dot_data)graph.render(Account,formatpng)3. 剪枝
iris datasets.load_iris()X iris[data]
y iris[target]
fn iris[feature_names]
# 随机拆分
X_train,X_test,y_train,y_test train_test_split(X,y,random_state 256)# max_depth 调整树深度剪枝操作
# max_depth 默认深度最大延伸到将数据完全划分开为止。
# min_impurity_decrease节点划分最小不纯度如果某节点的不纯度(基尼系数信息增益均方差)小于这个阈值则该节点不再生成子节点
# max_depth决策树最大深度
# min_samples_split内部节点再划分所需最小样本数
# min_samples_leaf叶子节点最少样本数
# max_leaf_nodes最大叶子节点数
model DecisionTreeClassifier(criterionentropy,min_impurity_decrease0.2)
model.fit(X_train,y_train)
y_ model.predict(X_test)
print(真实类别是,y_test)
print(算法预测是,y_)
print(准确率是,model.score(X_test,y_test))
# 导出数据
dot_data tree.export_graphviz(model,feature_namesfn,class_namesiris[target_names],# 类别名filledTrue, # 填充颜色roundedTrue,)
graph graphviz.Source(dot_data)
graph.render(./13-iris-裁剪, formatpng)4. 选择合适的超参并可视化
import numpy as np
from sklearn.tree import DecisionTreeClassifier
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn import tree
import matplotlib.pyplot as pltX,y datasets.load_iris(return_X_yTrue)# 随机拆分
X_train,X_test,y_train,y_test train_test_split(X,y,random_state 256)
depth np.arange(1,16)
err []
for d in depth:model DecisionTreeClassifier(criterionentropy,max_depthd)model.fit(X_train,y_train)score model.score(X_test,y_test)err.append(1 - score)print(错误率为%0.3f%% % (100 * (1 - score)))
plt.rcParams[font.family] STKaiti
plt.plot(depth,err,ro-)
plt.xlabel(决策树深度,fontsize 18)
plt.ylabel(错误率,fontsize 18)
plt.title(筛选合适决策树深度)
plt.grid()
plt.savefig(./14-筛选超参数.png,dpi 200)输出
错误率为31.579%
错误率为2.632%
错误率为2.632%
错误率为2.632%
错误率为2.632%
错误率为2.632%
错误率为2.632%
错误率为2.632%
错误率为2.632%
错误率为2.632%
错误率为2.632%
错误率为2.632%
错误率为2.632%
错误率为2.632%
错误率为2.632%5. 决策树副产物
特征重要性
model.feature_importances_
输出
array([0. , 0.04621936, 0.89613255, 0.05764808])