决策树学习

目录

一、介绍

二、决策树的基本概念

1、决策树

2、主要组成:

三、决策树的构造算法

1、 ID3(Iterative Dichotomiser 3)。

2、 C4.5。

3、基尼指数(CART)。

四、代码实现

五、决策树的优缺点

1、ID3决策树的优点: 

2、ID3决策树的缺点:


一、介绍

机器学习是人工智能的一个分支,它使计算机系统能够从数据中学习并做出决策或预测,而不是依赖于严格的编程指令。机器学习算法可以从数据中识别模式和关系,并用这些信息来做出预测或执行任务。决策树是一种常用的机器学习算法,它是一种监督学习算法,可以用于分类和回归任务。决策树模型表示一系列的决策规则,这些规则将输入特征映射到输出标签。

二、决策树的基本概念

1、决策树

决策树是一种树形结构,其中每个内部节点代表一个特征,每个分支代表一个特征值的选择,每个叶节点代表一个输出标签。从根节点开始,决策树通过一系列的决策来分割数据集,直到达到叶节点,从而做出预测。

2、主要组成:

根节点:决策树的起始点,包含整个数据集。
内部节点:代表一个特征,节点包含一个判断条件,用于分割数据集。
分支:连接内部节点和子节点,代表特征的某个值。
叶节:也称为终端节点,每个叶节点都有一个类标签,用于做出预测。

三、决策树的构造算法

1、 ID3(Iterative Dichotomiser 3)。


ID3算法采用信息增益(Information Gain)作为特征选择的标准。信息增益是基于信息论的概念,表示使用特征A对样本集合进行划分所获得的信息增益。信息增益越大,表示特征A对分类的能力越强。

信息增益的计算基于信息熵(Entropy)的概念,信息熵定义为信息的期望值,信息熵越大,则表明数据集的混乱程度越大。

数据集D的信息熵用如下公式表示:

在给定特征 ( A ) 的条件下,数据集 ( D ) 的信息熵为:

信息增益公式为:

2、 C4.5。

C4.5算法是ID3算法的改进版本,它在信息增益的基础上引入了信息增益比(Gain Ratio)来解决ID3算法对取值较多特征的偏向性问题。

下面是C4.5算法中使用的公式,前面的公式和ID3一样,最后多加了两个公式

分裂信息(Split Information):

信息增益比(Gain Ratio):

3、基尼指数(CART)。

决策树中的基尼指数是用来衡量节点的纯度或不纯度的指标之一。在构建决策树时,基尼指数通常用于选择最佳的划分特征,以便将数据集划分为纯度更高的子集。

基尼指数计算公式:

基尼指数的取值范围在0到1之间,数值越低表示节点的纯度越高,即样本的类别分布越趋于一致;而数值越高则表示节点的不纯度越高,即样本的类别分布越杂乱。

在构建决策树时,基尼指数通常与信息增益或信息增益比等指标一起使用,以帮助选择最佳的划分特征。通过选择基尼指数最小的划分点,可以使得子节点的纯度更高,从而提高了决策树的分类性能。

四、代码实现

#数据加载
def loadData( ):
    data = pd.read_csv("titanic.csv")
    data["Age"] = data["Age"].fillna(data["Age"].mean())  #针对Age字段,采用均值进行填充
    data = data.dropna()
    data.isna().sum()
    dataset = data.values.tolist()
 
    #四个属性
    labels=['Pclass','Age','Sex','Survived']
    return dataset,labels
#计算给定数据的香农熵
def calShannonEnt(dataset):
    numEntries = len(dataset)   #获得数据集函数
    labelCounts={}  #用于保存每个标签出现的次数
    for data in dataset:    
        #提取标签信息
        classlabel = data[-1]
        if(classlabel not in labelCounts.keys()):   #如果标签未放入统计次数的字典,则添加进去
            labelCounts[classlabel]=0
        labelCounts[classlabel]+=1  #标签计数
    shannonEnt=0.0      #熵初始化
    for key in labelCounts:
        p = float(labelCounts[key])/numEntries      #选择该标签的概率
        shannonEnt-= p*np.log2(p)
    return shannonEnt   #返回经验熵
#根据某一特征划分数据集
def splitDataset(dataset,axis,value):
# dataset 待划分的数据集 axis 划分数据集的特征 value 返回数据属性值为value
    retDataSet = [] #创建新的list对象
    for featVec in dataset: #遍历元素
        if featVec[axis]==value:    #符合条件的抽取出来
            reducedFeatVec = featVec[:axis]
            reducedFeatVec.extend(featVec[axis+1:])
            retDataSet.append(reducedFeatVec)
    return retDataSet
# 统计出现次数最多的元素(类标签)
def majorityCnt(classList):
    classCount={}  #统计classList中每个类标签出现的次数
    for vote in classList:
        if vote not in classCount.keys():
            classCount[vote] = 0
        classCount[vote] += 1
    sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)    #根据字典的值降序排列
    return sortedClassCount[0][0]  #返回出现次数最多的类标签
def createTree(dataset,labels):#数据集和标签列表
    classList =[example[-1] for example in dataset]#数据所属类得值
    if classList.count(classList[0])==len(classList):#条件1:classList只剩下一种值
        return classList[0]
    if len(dataset[0])==1:#条件2:数据dataset中属性已使用完毕,但没有分配完毕
        return majorityCnt(classList)#取数量多的作为分类
    bestFeat = chooseBestFeatureToSplit(dataset)#选择最好的分类点,即香农熵值最小的
    labels2 = labels.copy()#复制一分labels值,防止原数据被修改。
    bestFeatLabel = labels2[bestFeat]
    myTree = {bestFeatLabel:{}}#选取获取的最好的属性作为
    del(labels2[bestFeat])
    featValues = [example[bestFeat] for example in dataset]#获取该属性下的几类值
    uniqueVals = set(featValues)
    for value in uniqueVals:
        subLabels = labels2[:]#剩余属性列表
        myTree[bestFeatLabel][value] = createTree(splitDataset(dataset,bestFeat,value),subLabels)
    return myTree
if __name__ == '__main__':
    dataSet, labels = loadData( )
    print("数据集信息熵:"+str(calShannonEnt(dataSet)))
    mytree = createTree(dataSet,labels)
    print(mytree)
import  numpy as np
import pandas as pd
from sklearn import tree
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.feature_extraction import DictVectorizer
from sklearn.tree import export_graphviz
import matplotlib.pyplot as plt
 
# 加载数据
data = pd.read_csv('titanic.csv')
# print(data.head())
# print(data.shape) # (891, 12)
# 获取数据
x = data[['Pclass','Age','Sex']]
y = data['Survived']
# print(x.head())
# print(y.head())
# 缺失值处理
x['Age'].fillna(x['Age'].mean(),inplace=True)
# 特征处理
x['Sex'] = np.array([0 if i == 'male' else 1 for i in x['Sex']]).T
# 打印查看是否替换成功
# print(x.head())
# 划分数据集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2,random_state=22)
 
 
# 创建模型
model = DecisionTreeClassifier(criterion='entropy',max_depth=3)
# 3 准确率: 0.7653631284916201
# 4 准确率: 0.7653631284916201
# 5 准确率: 0.7430167597765364
# 6 准确率: 0.7486033519553073
# 8 准确率: 0.7541899441340782
# 12 准确率: 0.770949720670391
model.fit(x_train,y_train)
# 评估
score = model.score(x_test,y_test)
pred = model.predict(x_test)
print('准确率:',score)
print('预测值:',pred)
# 可视化方法一:
# export_graphviz(model, out_file="tree.dot", feature_names=['pclass','age','sex'])
# 更简单的方法:
plt.figure(figsize=(20,20))
feature_name = ['pclass','age','sex']
class_name = ['survived','death']
tree.plot_tree(model,feature_names=feature_name,class_names=class_name)
plt.savefig('tree.png')

五、决策树的优缺点

1、ID3决策树的优点:
 

简单性:ID3算法简单易懂,易于实现。它基于简单的数学原理,不需要复杂的数学模型或大量的参数调整。
  高效性:在处理大规模数据时,ID3算法表现出较高的效率。它的时间复杂度较低,可以在短时间内完成分类任务。
  健壮性:ID3算法对噪声数据具有较强的鲁棒性。即使是在数据集存在一定程度的噪声或不完整的情况下,ID3也能够较好地捕捉到数据的本质特征,从而做出准确的分类。
可扩展性:ID3算法具有良好的可扩展性。当需要处理更多特征的数据时,ID3可以轻松地添加新的分支,而不会导致性能下降。
  易于理解:ID3算法的决策过程清晰可见,易于理解和解释。用户可以根据树的结构直观地了解分类器的逻辑推理过程。
适用于多种数据类型:ID3算法可以处理数值型和离散型数据。对于连续型的数据,它可以将其转化为离散型数据来进行处理。
快速学习:ID3算法的学习速度较快,能够在较短的时间内完成模型构建。

2、ID3决策树的缺点:


  过度拟合:ID3算法可能会产生过度的树形结构,导致模型在训练数据上表现良好,但在测试数据上表现不佳。这是因为ID3在选择分裂属性时倾向于选择那些在训练集中区分能力强的属性,而这些属性可能并不总是适用于测试集。
  忽略相关性:ID3算法没有考虑属性的相关性,可能导致某些属性被过度重视,而其他更有意义的属性却被忽视。
  无法处理缺失数据:当数据集中存在大量缺失值时,ID3算法可能会遇到困难。因为它依赖于完整的数据集来构建决策树,缺失的数据会导致树的结构不完整或不准确。
  空间复杂度高:随着树深度的增加,ID3算法的空间复杂度也会增加。这可能会导致内存消耗过大,尤其是在处理大型数据集时。
  不适合处理连续数据:虽然ID3可以处理部分连续数据,但它更适合处理离散数据。对于连续数据,需要进行预处理,将其转换为适合ID3处理的离散形式。
  总的来说,ID3决策树在许多实际应用中是一种有效的分类方法,但其性能受到数据质量和算法参数的影响。在使用ID3时,应充分考虑其优缺点,并根据具体情况进行调整和改进

  • 8
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值