python实现ID3算法实现全过程
原理:基于信息熵来选择最佳的测试属性。注意理解熵的概念,还有信息增益的概念。这样更能理解决策树的生成。
信息熵的概念及其公式实现:
总信息熵
I(s1,s2,s3…sn) = -∑P(xi)log(2,P(xi)) (i=1,2,…n) ------------------------------式1
设A属性有不同的的k个值{a1,a2,a3,a4…}A属性样本的信息熵值:
E(A)=∑s1,s2,s3,s4,…/s* I(s1,s2,s3…sn) ---------------------------------------式2
信息增益:
Gain(A) = I -E(A) ----------------------------------------------------------------------式3
单看公式相信大家难以理解。
我们用实例来解释可能比较容易接受。
大家应该都有接触过王者荣耀,那么对你来说什么情况很容易导致你输呢?
是因为存在鲁班吗,还是瑶,亦或者是韩信,还是打野从来拿不到buff,队友经常吵架,还是有其它奇奇怪怪的原因呢,我们来用决策树来随便玩玩,查看以下哪些年我们被坑输的结果,预测我们今后比赛的结果。
首先根据我们的情况啦,选择几个属性玩玩。(当然你也可以把很多属性加进去,这里我们做个示例就不搞那么多了。)我这里选的是,以下5个属性:
1.是否有鲁班
2.是否有瑶
3.是否有韩信
4.打野是否经常拿不到buff
5.队友是否吵架
结果:
输or赢
把我的对局情况做出了以下表格:(共36场对局)
具体情况如上所示哈。num代表序列号。
先把数据量化,"有"和"赢"当成1
"否"和"输"当成-1
便于我们计算信息熵。
emm,先展示以下我们的原理计算环节:
步骤一、求总信息熵
根据式1,计算总的信息熵。可以看到总记录为36条,而结果为"赢"得部分有15条,而结果为"输"的有21条
所以得到公式:I(总信息熵)=
步骤二、求各个属性的信息熵
计算每个测试属性的信息熵,例如:"是否存在鲁班"这一属性:
我们看到,"存在鲁班"的情况有15条,"不存在鲁班"的情况有21条
1)
那么"存在鲁班"时"赢"的占5条,"输"的占10条
I(有鲁班)=I(5,10)=
同理可得:
2)
I(无鲁班)=I(10,11)
公式类似上面
所以测试属性的信息熵为:
3)
E(是否存在鲁班) = P(存在鲁班) * I(有鲁班)+P(不存在鲁班) * I(无鲁班)
4)
同理,我们可以计算出其他测试属性的信息熵:
E(是否存在瑶) =
E(是否存在韩信) =
E(打野是否经常拿不到buff) =
E(队友是否吵架) =
步骤三、求每个属性的信息增益
根据式3
Gain(测试属性)=I(总信息熵) — E(测试属性信息熵)
即拿鲁班来举例:
Gain(是否存在鲁班) = I(总信息熵) — E(是否存在鲁班)
其他的同理
步骤四、找出节点和分支重复前面步骤
根据步骤3中我们得到了每个测试属性的信息增益,我们把最大的拿出来作为第一个节点,然后以这个节点属性的属性值"是""否"作为两个分支。
然后重复上面的3个步骤继续对该根节点的其他分支进行划分,针对每个分支节点继续进行信息增益的计算,反复循环,知道没有新的节点分支,最后就可以构成一棵决策树了。
在代码中,我们可以省略很多计算的过程,但是这个原理我们最好还是要掌握一下。
代码的实现:
import pandas as pd
"""王者荣耀情况影响战局的最佳属性"""
"""实现ID3算法"""
file_excel = ("./ID3.xlsx") #pandas导入数据啦
data = pd.read_excel(file_excel, index_col='num')
#是,赢转换为数据(量化)
#用1表示是和赢,-1表示否和输
data[data == '有'] = 1
data[data == '赢'] = 1
data[data != 1] = -1
x = data.iloc[:,: 5].values.astype(int) #前面的数据那几列(属性列)
y = data.iloc[:, 5].values.astype(int) #输赢那一列
from sklearn.tree import DecisionTreeClassifier as DTC #导入库
dtc = DTC(criterion='entropy') #建立决策树模型,基于信息熵
dtc.fit(x, y) #训练
from sklearn.tree import export_graphviz #导入可视化决策树的库
#x = pd.DataFrame(x)
with open("./output/tree.dot", 'w', encoding='utf-8') as f:
f = export_graphviz(dtc, feature_names=['if exist luban', 'if exist yao', 'if exist hanxin', 'if no buff for daye',
'if exist quarrel'], out_file=f) #保存决策树呀,./output/tree.dot。这是我保存的路径,可以自己修改哦
代码的实现并不难,基本都是用库方法,我们只需要导入数据,然后做基本的数据变换就好了。
从代码中可以看到我们已经生成了一个tree.dot文件。如果你打开这个dot文件,你会发现你看到的是一行一行的数据,难以观看,所以我们要想办法把它变成一颗树。
接下来就是关键啦,我们要怎么看到好看的决策树呢?
二、决策树可视化
我们的文件夹里生成了tree.dot文件我们要把它变成图片或者pdf还有变成树状。请执行以下步骤:
2.1下载安装graphviz可视化工具
官网下载超级慢,请在csdn直接搜索这个工具,然后下载,安装。没有技术含量,不作演示。要记住自己的安装路径
2.2graphviz添加环境变量
把安装路径的graphivz\bin添加到环境变量就可以了,不会添加环境变量的可以参照我的文章里面python安装那一篇去添加环境变量。
2.3验证安装完成
打开win+r输入cmd打开命令行工具,查看版本,输入:
dot -V
如果输出了版本号,即安装完成。
没有的应该是环境变量出了问题。
2.4把dot文件转成png或pdf
打开命令行工具然后跳转到tree.dot文件所在位置输入以下命令;
dot -Tpdf tree.dot -o tree.pdf
完成
结果展示:
这告诉我们打王者不要吵架不然输的可能性很大,看你队伍满足以上多少条,可以预测你这局的输赢哦。分支箭头往左为True,往右为False。
最下面一排的中entropy代表信息熵,value代表取值。如value=[1,0],代表赢1局,输0局的意思。
samples代表实例。这个决策树主要用作分类,或者预测,规则提取等。
我们可以根据决策的分类很容易看到,"队友是否吵架"这个是最佳属性。
喜欢的朋友留下你的赞哦!!