文章目录
一、决策树
1.概念
决策树(Decision Tree)是在已知各种情况发生概率的基础上,通过构成决策树来求取净现值的期望值大于等于零的概率,评价项目风险,判断其可行性的决策分析方法,是直观运用概率分析的一种图解法。由于这种决策分支画成图形很像一棵树的枝干,故称决策树。在机器学习中,决策树是一个预测模型,他代表的是对象属性与对象值之间的一种映射关系。Entropy = 系统的凌乱程度,使用算法ID3, C4.5和C5.0生成树算法使用熵。这一度量是基于信息学理论中熵的概念。
决策树是一种树形结构,其中每个内部节点表示一个属性上的测试,每个分支代表一个测试输出,每个叶节点代表一种类别。
样本数据如下:
选择分隔符号和字符集
选择空格:
确定:
最后成功导入数据
————————————————
版权声明:本文为优快云博主「weixin_50909683」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/weixin_50909683/article/details/121016507
2. 信息熵(information entropy)
假定当前样本集合D中第k类样本所占的比例为pk(k=1,,2,...,
|y|),则D的信息熵定义为:Ent(D) = -∑k=1 pk·log2 pk约定
若p=0,则log2 p=0)显然,Ent(D)值越小,D的纯度越高。因为
0<=pk<= 1,故log2 pk<=0,Ent(D)>=0. 极限情况下,考虑D中
样本同属于同一类,则此时的Ent(D)值为0(取到最小值)。当D
中样本都分别属于不同类别时,Ent(D)取到最大值log2 |y|.
3. 信息增益(information gain)
假定离散属性a有V个可能的取值{a1,a2,...,aV}. 若使用a
对样本集D进行分类,则会产生V个分支结点,记Dv为第v个分
支结点包含的D中所有在属性a上取值为av的样本。不同分支结
点样本数不同,我们给予分支结点不同的权重:|Dv|/|D|, 该
权重赋予样本数较多的分支结点更大的影响、由此,用属性a对
样本集D进行划分所获得的信息增益定义为:Gain(D,a) = Ent(D)-∑v=1 |Dv|/|D|·Ent(Dv)
其中,Ent(D)是数据集D划分前的信息熵,∑v=1 |Dv|/|D|·Ent(Dv)可以表示为划分后的信息熵。“前-后”的结果表明了本次划分所获得的信息熵减少量,也就是纯度的提升度。显然,Gain(D,a) 越大,获得的纯度提升越大,此次划分的效果越好。
4. 增益率(gain ratio)
基于信息增益的最优属性划分原则——信息增益准则,对可取值
数据较多的属性有所偏好。C4.5算法使用增益率替代信息增益来
选择最优划分属性,增益率定义为:Gain_ratio(D,a) = Gain(D,a)/IV(a
其中 IV(a) = -∑v=1 |Dv|/|D|·log2 |Dv|/|D|
称为属性a的固有值。属性a的可能取值数目越多(即V越大),则IV(a)的值通常会越大。这在一定程度上消除了对可取值数据较多的属性的偏好。
事实上,增益率准则对可取值数目较少的属性有所偏好,C4.5算法并不是直接使用增益率准则,而是先从候选划分属性中找出信息增益高于平均水平的属性,再从中选择增益率最高的。
下面,我们就对以下表格中的西瓜样本构建决策树模型。
5、代码实现
1.导入模块部分
#导入模块
import pandas as pd
import numpy as np
from collections import Counter
from math import log2
用pandas模块的read_excel()函数读取数据文本;用numpy模块将dataframe转换为list(列表);用Counter来完成计数;用math模块的log2函数计算对数。后边代码中会有对应体现。
2.数据获取与处理函数
#数据获取与处理
def getData(filePath):
data = pd.read_excel(filePath)
return data
def dataDeal(data):
dataList = np.array(data).tolist()
dataSet = [element[1:] for element in dataList]
return dataSet
getData()通过pandas模块中的read_excel()函数读取样本数据。尝试过将数据文件保存为csv格式,但是对于中文的处理不是很好,所以选择了使用xls格式文件。
dataDeal()函数将dataframe转换为list,并且去掉了编号列。编号列并不是西瓜的属性,事实上,如果把它当做属性,会获得最大的信息增益。
这两个函数是完全可以合并为同一个函数的,但是因为我想分别使用data(dataframe结构,带属性标签)和dataSet(list)数据样本,所以分开写了两个函数。
3.获取属性名称
#获取属性名称
def getLabels(data):
labels = list(data.columns)[1:-1]
return labels
很简单,获取属性名称:纹理,色泽,根蒂,敲声,脐部,触感。
4.获取类别标记
#获取类别标记
def targetClass(dataSet):
classification = set([element[-1] for element in dataSet])
return classification
获取一个样本是否好瓜的标记(是与否)。
5.叶结点标记
#将分支结点标记为叶结点,选择样本数最多的类作为类标记
def majorityRule(dataSet):
mostKind = Counter([element[-1] for element in dataSet]).most_common(1)
majorityKind = mostKind[0][0]
return majorityKind
6.计算信息熵
#计算信息熵
def infoEntropy(dataSet):
classColumnCnt = Counter([element[-1] for element in dataSet])
Ent = 0
for symbol in classColumnCnt:
p_k = classColumnCnt[symbol]/len(dataSet)
Ent = Ent-p_k*log2(p_k)
return Ent
7.子数据集构建
#子数据集构建
def makeAttributeData(dataSet,value,iColumn):
attributeData = []
for element in dataSet:
if element[iColumn]==value:
row = element[:iColumn]
row.extend(element[iColumn+1:]