最简单的决策树实例项目:心脏病分析和预测

决策树是一种有效的数据分析技术,可以用于基于给定的条件和规则来做出最佳决策。它利用树状图来模拟人类进行决策过程的过程,从而帮助决策者明确目标以及到达该目标所需要采取的行动。

数据集放在我的网盘里了,在这里 

当然,这里也可以

概述

决策树是常用的机器学习技术,可以根据给定的条件做出最佳决策,从而解决遇到特定情况时不确定性最大的问题,如垃圾邮件筛选、欺诈检测、市场分割以及金融、医疗和制造领域的决策分析等。

实例项目:心脏病分析和预测

为什么要做这个?

哈哈哈很简单啊,就是那天在逛kaggle的时候看到了这个数据集,很简单所以就想试一试。

那么就简单介绍一下数据集中的内容吧。

Age : 患者的年龄
Sex : 患者的性别
    M : male 男
    F : female 女
ChestPainType : 心绞痛类型
    Value 1: typical angina : TA
    Value 2: atypical angina : ATA
    Value 3: non-anginal pain : NAP
    Value 4: asymptomatic : ASY
RestingBP : 静息血压
Cholesterol : 胆固醇
FastingBS : 禁食血糖(空腹血糖浓度>120mg/dl)
    0 : 错误(<120)
    1 : 正确(>120)
RestingECG : 静息心电图
    Value 1: normal : Normal
    Value 2: ST-T 波异常(T 波倒置和/或 ST 抬高或压低 > 0.05 mV) : ST
    Value 3: 根据 Estes 标准显示可能或明确的左心室肥大 : LVH
MaxHR : 最大心率
ExerciseAngina : 运动诱发的心绞痛
    Value 1 : Y = 是
    Value 0 : N = 否
Oldpeak : ST段下降, 上一个峰值
ST_Slope : ST斜率
    Value 1 : Up   : 上升
    Value 2 : Flat : 平稳
    Value 3 : Down : 下降
HeartDisease : 心脏疾病

经过测试,准确率预估在80%左右,当然做的十分简单。(PS:初学者多多见谅呀) 

构建决策树

第一步是对数据集中的内容进行分析

因为这个数据集内容并不多,简单看一下就好了

看得到其中的一些特征不是数字,那么我们可以使用一些方法将它们映射数字就可以了

我准备了一些方法

def genderClassifier(x):
    if x == 'M':
        return 1
    if x == 'F':
        return 0


def chestPainTypeClassifier(x):
    if x == 'TA':
        return 1
    if x == 'ATA':
        return 2
    if x == 'NAP':
        return 3
    if x == 'ASY':
        return 4


def restingECGClassifier(x):
    if x == 'Normal':
        return 1
    if x == 'ST':
        return 2
    if x == 'LVH':
        return 3


def exerciseAnginaClassifier(x):
    if x == 'N':
        return 0
    if x == 'Y':
        return 1


def ST_SlopeClassifier(x):
    if x == 'Up':
        return 1
    if x == 'Flat':
        return 2
    if x == 'Down':
        return 3

划分数据集

对数据集进行划分:训练集与测试集

X_train, X_test, Y_train, Y_test = train_test_split(
    X, Y, random_state=2019, test_size=0.2)

准备训练

以上,准备工作就做好了,可以开始训练了,当然训练的过程十分简单

tree_clf = DecisionTreeClassifier(max_depth=6)
tree_clf.fit(X_train, Y_train)

max_depth:决策树的最大深度 

测试

(我第一次做的时候,被震惊到了,居然这么简单啊,学理论的时候真的很抓马)

tree_clf.predict(X_test)

可视化决策树模型

决策树作为少有的可以被可视化的模型,最好还是需要看一下

feature_names=dataset.keys().values[:11]

export_graphviz(
    tree_clf,
    out_file='HeartAttackAnalysisAndPredictionDataset.dot',
    feature_names=feature_names,
    class_names=['1','0'],
    rounded=True,
    filled=True
)

经过上面的过程,就得到了一个决策树的模型

可视化的时候需要在终端运行如下指令,让原本生成的dot文件转换为png

dot -Tpng HeartAttackAnalysisAndPredictionDataset.dot -o HeartAttackAnalysisAndPredictionDataset.png

PS:当然需要先下载这个可视化程序了

brew install graphviz

最后

到这里,决策树就构建完成了,是不是巨简单

当然这里面的算法都没有被体现,因为都是由DecisionTreeClassifier完成的。

下面是算法的一些笔记(PS:下面的笔记是根据B站上的一位UP主写的,这是连接

决策树树模型

  • 决策树:从根节点开始一步步走到叶子节点(决策)

  • 所有的数据最终都会落到叶子节点,既可以做分类也可以做回归

树的组成

  • 根节点

  • 非叶子节点与分支

  • 叶子节点

决策树的训练与测试

  • 训练阶段:从给定的训练集构造出来一棵树(从根节点开始选择特征,如何进行特征切分)。

  • 测试阶段:根据构造出来的树模型从上到下走一遍。

  • 一旦构造好了决策树,那么分类或者预测任务就很简单了,只需要走一遍就可以,那么难点就在于如何构造出一棵树,就这没那么容易了,需要考虑的问题还有很多。

如何切分特征(选择节点)

  • 问题:根结点的选择该用什么特征?接下来?如何切分?

  • 想象一下:我们的目标应该是根节点就像一个老大一样能更好的切分数据(分类效果好),根节点下面的节点就是稍微弱一点的。

  • 目标:通过一种衡量标准,来计算通过不同特征进行分支选择后的分类情况,找出来最好的那个当成根节点,以此类推。

衡量标准--熵

  • 熵:表示随机变量不确定性的度量 不确定性越大,得到的熵值也越大

  • 公式

    $$
    H(x)=-\sum{p_i*\log_2{p_i},i=1,2,...,n}
    $$

     

    pi为i在集合中出现的概率

  • example

    $$
    A=[1,2,1,1,1,1,1,2] B=[1,4,2,5,8,4,6,9]
    $$

     

    A集合熵值低,B会高些

  • 信息增益:表示特征X使得类Y的不确定性减少的程度。(分类后的专一性,希望分类后的结果是同类的在一起) 书中定义:信息熵H从先前状态到获取某些信息(t)的状态的变化,可以写成

    $$
    G(Q|t)=H(Q)-H(Q|t)
    $$

决策树算法

  • ID3:信息增益

  • C4.5:信息增益率(解决ID3问题,考虑自身熵)

  • CART:使用GINI系数来当做衡量标准

  • GINI系数:

    $$
    Gini(p)=\sum_{k=0}^kp_k(1-p_k)=1-\sum_{k=1}^kp_k^2
    $$

     

    和熵的衡量标准类似,计算方式不同

连续值怎么办?

选取(连续值的)那个分界点?

五大算法思想

  1. 贪心算法/贪婪算法

  2. 分治思想(二分查找、归并排序、快速排序)

  3. 动态规划/线性规划

  4. 动态回溯

  5. 分支定界

在使用信息熵衡量标准时,如果遇到连续值,需要首先对该连续特征进行离散化处理。离散化可以将连续特征划分为多个离散值,将其转换为分类型特征,然后再根据离散化后的特征进行决策树的构建和计算信息熵。

通常,离散化方法有两种:

  1. 基于划分点的二元离散化方法:该方法将连续特征划分为两个部分,通过比较每个二元点的信息增益来选择最优的分割点。

  2. 基于聚类的多元离散化方法:该方法使用聚类算法将连续特征划分为多个部分,并将聚类结果用作新的分类型特征。

需要注意的是,在离散化过程中,需要选择不同的划分方式和不同的划分标准,以获得较好的决策树分类结果。同时,离散化的效果也会受到参数设置的影响,所以需要进行适当的调参。

决策树剪枝策略

  • 为什么需要剪枝:决策树过拟合风险很大,理论上完全可以分得开数据

  • 剪枝策略:预剪枝、后剪枝

  • 预剪枝:边建立决策树边进行剪枝 限制深度、叶子结点个数、叶子结点样本数、信息增益等

  • 后剪枝:但建立完决策树后进行剪枝 通过一定的衡量标准

    $$
    C_\alpha(T)=C(T)+\alpha\cdot|T_{leaf}|
    $$

     

    叶子节点越多,损失越大

附录:全部代码

import pandas as pd  # 数据科学计算工具
dataset = pd.read_csv('heart.csv')
X = dataset.iloc[:, 0:11]
Y = dataset.HeartDisease
def genderClassifier(x):
    if x == 'M':
        return 1
    if x == 'F':
        return 0


def chestPainTypeClassifier(x):
    if x == 'TA':
        return 1
    if x == 'ATA':
        return 2
    if x == 'NAP':
        return 3
    if x == 'ASY':
        return 4


def restingECGClassifier(x):
    if x == 'Normal':
        return 1
    if x == 'ST':
        return 2
    if x == 'LVH':
        return 3


def exerciseAnginaClassifier(x):
    if x == 'N':
        return 0
    if x == 'Y':
        return 1


def ST_SlopeClassifier(x):
    if x == 'Up':
        return 1
    if x == 'Flat':
        return 2
    if x == 'Down':
        return 3
X.Sex = X.Sex.apply(lambda x: genderClassifier(x))
X.ChestPainType = X.ChestPainType.apply(lambda x: chestPainTypeClassifier(x))
X.RestingECG = X.RestingECG.apply(lambda x: restingECGClassifier(x))
X.ExerciseAngina = X.ExerciseAngina.apply(lambda x: exerciseAnginaClassifier(x))
X.ST_Slope = X.ST_Slope.apply(lambda x: ST_SlopeClassifier(x))
from sklearn.model_selection import train_test_split

X_train, X_test, Y_train, Y_test = train_test_split(
    X, Y, random_state=2019, test_size=0.2)
from sklearn.tree import DecisionTreeClassifier

tree_clf = DecisionTreeClassifier(max_depth=6)
tree_clf.fit(X_train, Y_train)
tree_clf.predict(X_test)
from sklearn.tree import export_graphviz

feature_names=dataset.keys().values[:11]

export_graphviz(
    tree_clf,
    out_file='HeartAttackAnalysisAndPredictionDataset.dot',
    feature_names=feature_names,
    class_names=['1','0'],
    rounded=True,
    filled=True
)
from IPython.display import Image

Image(filename='HeartAttackAnalysisAndPredictionDataset.png', width=400, height=400)

猜你喜欢

转载自blog.csdn.net/Orlando_Ari/article/details/130033436
今日推荐