决策树基本 CART Python手写实现

参考资料:
https://blog.csdn.net/weixin_45666566/article/details/107954454
https://blog.csdn.net/Elenstone/article/details/105328111

代码如下:
python 复制代码
#-*- coding:utf-8 -*-
import numpy as np
import pandas as pd
import operator

def loadDataSet():
    csv = pd.read_csv(filepath_or_buffer=r'D:/PythonData/决策树.csv')
    dataSet = np.array(csv)
    labels = np.array(csv.columns)[:4]
    targets = sorted(np.unique(dataSet[:,-1:].flatten()), reverse=True)
    return dataSet, labels, targets

def calcProbabilityEnt(dataSet, targets):
    numEntries = len(dataSet)  # 数据条数
    feaCounts = 0
    fea1 = targets[0]
    for featVec in dataSet:
        if featVec[-1] == fea1:
            feaCounts +=1

    probabilityEnt = float(feaCounts) / numEntries
    return probabilityEnt    


def splitDataSet(dataSet, index, value):
    retDataSet = []
    noRetDataSet = []
    for featVec in dataSet:
        if featVec[index]  == value:
            retDataSet.append(np.concatenate((featVec[:index],featVec[index+1:])))
        if featVec[index]  != value:
            noRetDataSet.append(np.concatenate((featVec[:index],featVec[index+1:])))

    return retDataSet,noRetDataSet

def chooseBestFeatureToSplit(dataSet, targets):
    numFeatures = len(dataSet[0]) - 1
    if numFeatures == 1:
        return 0
    bestGini = 1
    bestFeatureIndex = -1
    for i in range(numFeatures):
        # 每一列中的唯一值集合
        uniqueVals = set(example[i] for example in dataSet)
        feaGini = 0
        for value in uniqueVals:
            subDataSet,noSubDataSet = splitDataSet(dataSet=dataSet, index=i,value=value)
            prod = len(subDataSet) / float(len(dataSet))
            noPord = len(noSubDataSet) / float(len(dataSet))
            probabilityEnt = calcProbabilityEnt(subDataSet, targets)
            noProbabilityEnt = calcProbabilityEnt(noSubDataSet,targets)
            feaGini = round(prod * 2 * probabilityEnt * (1 - probabilityEnt) +  (noPord * (2 * noProbabilityEnt * (1 - noProbabilityEnt))),2)
    
            if bestGini > feaGini:
                bestGini = feaGini
                bestFeatureIndex = i
    
    return bestFeatureIndex

def majorityCnt(classList):
    classCount = {}
    for vote in classList:
        try:
            classCount[vote] += 1
        except KeyError:
            classCount[vote] = 1
    
    sortedClassCount = sorted(iterable=classCount.items(),key=operator.itemgetter(1),reverse=True)
    return sortedClassCount[0][0]

def createTree(dataSet, labels,targets):
    classList = [example[-1]  for example in dataSet]
    if classList.count(classList[0]) == len(classList):
        return classList[0]
    if len(dataSet[0]) == 1:
        return majorityCnt(classList=classList)

    bestFeatIndex  = chooseBestFeatureToSplit(dataSet=dataSet,targets=targets)
    bestFeatLabel = labels[bestFeatIndex]
    np.delete(labels,bestFeatIndex)
    uniqueVals = set(example[bestFeatIndex] for example in dataSet) # 选出最优特征对应属性的唯一值
    myTree = {bestFeatLabel:{}} # 分类结果以字典形式保存
    for value in uniqueVals:
        subLabels = labels[:] # 深拷贝,拷贝后的值与原值无关(普通复制为浅拷贝,对原值或拷贝后的值的改变互相影响)
        subDataSet,noSubDataSet = splitDataSet(dataSet,bestFeatIndex,value)
        myTree[bestFeatLabel][value] = createTree(subDataSet,subLabels,targets) # 递归调用创建决策树
    return myTree
    


if __name__=='__main__':
    dataSet,labels,targets = loadDataSet()
    print(createTree(dataSet,labels,targets))
运行如果如下:
shell 复制代码
PS D:\PythonWorkSpace> & E:/anaconda3/python.exe d:/PythonWorkSpace/DecisionTreeDemo.py
{'有自己的房子': {'否': {'有工作': {'否': '不同意', '是': '同意'}}, '是': '同意'}}
相关推荐
维度攻城狮1 小时前
实现在Unity3D中仿真汽车,而且还能使用ros2控制
python·unity·docker·汽车·ros2·rviz2
简简单单做算法1 小时前
基于mediapipe深度学习和限定半径最近邻分类树算法的人体摔倒检测系统python源码
人工智能·python·深度学习·算法·分类·mediapipe·限定半径最近邻分类树
hvinsion2 小时前
基于PyQt5的自动化任务管理软件:高效、智能的任务调度与执行管理
开发语言·python·自动化·自动化任务管理
Tisfy2 小时前
LeetCode 2360.图中的最长环:一步一打卡(不撞南墙不回头) - 通过故事讲道理
算法·leetcode··题解
LuckyAnJo2 小时前
Leetcode-100 链表常见操作
算法·leetcode·链表
飞飞翼4 小时前
python-flask
后端·python·flask
双叶8364 小时前
(C语言)虚数运算(结构体教程)(指针解法)(C语言教程)
c语言·开发语言·数据结构·c++·算法·microsoft
工一木子4 小时前
大厂算法面试 7 天冲刺:第5天- 递归与动态规划深度解析 - 高频面试算法 & Java 实战
算法·面试·动态规划
林九生5 小时前
【Python】Browser-Use:让 AI 替你掌控浏览器,开启智能自动化新时代!
人工智能·python·自动化
猿界零零七5 小时前
执行paddle.to_tensor得到全为0
python·paddle