0.5decision-tree

import matplotlib.pyplot as plt
import numpy as np 
import pandas as pd
import scipy as sc
import seaborn as sns
import queue
from sklearn import datasets
from sklearn.metrics import accuracy_score,f1_score
from sklearn.tree import DecisionTreeClassifier

Decision Tree

  • 把产生的连续变量转化成类别标签,用这个数据做决策树,就方便很多了。
x,y=datasets.make_classification()
#三个分位数:
x=np.apply_along_axis(lambda a:np.searchsorted(np.quantile(a,np.sort(np.random.rand(5))),a),0,x)
for i in list(set(y)):
    plt.plot(x[y==i][:,0],x[y==i][:,1],'*',label=i)
plt.legend()
plt.show()

在这里插入图片描述

1.1信息熵

def Entropy(series):
    '''
    计算类别变量的熵
    '''
    pi=pd.Series(series).value_counts()/len(series)
    return -1*np.sum(pi*np.log2(pi))
en=np.apply_along_axis(Entropy,0,x)
plt.plot(en,'*')
[<matplotlib.lines.Line2D at 0x2dec9264b00>]

在这里插入图片描述

1.2条件熵

  • D 为样本
  • k为类别个数 ,Ck为类别为k的样本数
  • 特征A有不同的特征1,2,3…n,根据特征A可以将特征分为D1,D2,D3…Dn ,|D1|为样本个数
  • 即Di中属于Ck的样本集合为Dik
def EntropyCondition(series,y):
    '''
    计算series的条件熵
    
    series:数据集
    y:类别
    先数据集按照特征A分开,然后计算没一份数据的经验熵
    '''    
    return -1*np.sum([Entropy(y[series==i]) for i in set(series)])
        
EntropyCondition(x[:,1],y)
-5.8599831625893435

1.4 信息增益

def GainInf(array,y):
    '''
    计算信息增益
    
    array: data
    y:label
    
    return 返回每个特征的增益
    '''
    gain=np.zeros(array.shape[1])
    for i,series in enumerate(array.T):
        gain[i]=Entropy(y)-EntropyCondition(series,y)
    return gain   
        
'''
测试全都一样的数据
'''
a=np.ones_like(x)
b=np.ones_like(y)

GainInf(a,b)#.argmax()    
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0.])
def GainInfRatio(array,y):
    '''
    计算信息增益比
    ??? 如果信息增益比的分为0怎么办??
    返回信息增益比
    '''
    #对于信息熵等于0的特征,直接把所有特征的信息熵平均值*10
    gain=np.apply_along_axis(Entropy,0,array)   
    #尽量不要找都一样的数据,因为这样会导致分不下去
    gain[gain==0]+=np.mean(gain)*10
    
    return GainInf(array,y)/gain
    
GainInfRatio(x,y).argmax()
3

ID3

  • 每棵树不一定有几个子树,所以用列表表示他的所有子树
  • 如果信息增益最大的那个特征有多个取值,我应该怎么选取呢?难道是随便选,直接分开n个?
class Node():
    '''
    决策树单棵树的实现(只要提供树的数据集,就可以继续下一步了。)
    
    决策树的子树不一定只有两颗树,所以用列表表示所有的子树
    每课树保留自己的数据集、维度、值
    '''
    def __init__(self,data,value=None,nodes=None,iIndex=None):
        self.nodes=nodes #保存左树
        self.data=data  #保存数据集
        self.iIndex=iIndex #记录切割的维度
        self.value=value # 当前维度的值
    def set_node(self,value=None,nodes=None,iIndex=None):
        self.nodes=nodes
        self.value=value
        self.iIndex=iIndex 
        
def DecisionTree(node):
    '''
    通过计算信息增益比来切割数据集
    
    对数据的第iIndex个维度分割
    包含左侧数据集的树节点,右侧数据集节点,切分点
    '''
    array,y=node.data# 
    Childes=[]
    iIndex=GainInfRatio(array,y).argmax()
    node.iIndex=iIndex
    currentFeature=array[:,iIndex]
    for i in set(currentFeature):
        nodei=Node((array[currentFeature==i],y[currentFeature==i]))
        nodei.value=i
        Childes.append(nodei)
        #print(iIndex,i,np.sum(currentFeature==i))
    node.nodes=Childes 
    
    return Childes

构建决策树

  • 第一步构建跟目录
  • 第二步根据某个特征(iIndex)切分,切分后的数据保存到子节点nodes,设置子节点value(如果该特征的值等于values)则搜索时进入该子节点
  • 第三步,选择一个nodes 继续构建,或者增益比较少,或者节点数少于2
  • 考虑?等于零之类的呢?
MinSample=3 #最小样本点
myqueue=queue.Queue()
root=Node((x,y),value=0,iIndex=0) #生成根节点
currentDecision=root
myqueue.put(currentDecision)

while not myqueue.empty():
    #随便取出来一个继续决策
    currentDecision=myqueue.get()
    childe_nodes=DecisionTree(currentDecision)
    #print(myqueue.qsize(),childe_nodes[0].data[1].shape,len(childe_nodes))
    for i in childe_nodes:
        # 只有子节点大于5个样本点才回继续
        if len(i.data[1])>MinSample:            
            myqueue.put(i)
            

搜索决策树

y_pred=[]
for i in range(y.shape[0]):
    search=x[i]#设置搜索目标
    searchDecision=root
    #当前擦找的决策树,的索引
    while searchDecision.iIndex!=None:
        # 
        searchDecision=[i  for i in searchDecision.nodes if i.value==search[searchDecision.iIndex]][0]
    y_pred.append(np.mean(searchDecision.data[1])>0.5)
#我自己写的,还有一个主要的问题。
accuracy_score(y>0.5,y_pred),f1_score(y>0.5,y_pred)
(0.63, 0.5066666666666666)
tree=DecisionTreeClassifier()
tree.fit(x,y)
y_pred=tree.predict(x)
accuracy_score(y>0.5,y_pred),f1_score(y>0.5,y_pred)
(1.0, 1.0)

总结

  • 主要的问题,当变量变少后,容易选择完全一致的变量。
此压缩包包含了本毕业设计项目的完整内容,具体包括源代码、毕业论文以及演示PPT模板。 开发语言:Java 框架:SSM(Spring、Spring MVC、MyBatis) JDK版本:JDK 1.8 或以上 开发工具:Eclipse 或 IntelliJ IDEA Maven版本:Maven 3.3 或以上 数据库:MySQL 5.7 或以上 项目配置完成后即可运行,若需添加额外功能,可根据需求自行扩展。 运行条件 确保已安装 JDK 1.8 或更高版本,并正确配置 Java 环境变量。 使用 Eclipse 或 IntelliJ IDEA 打开项目,导入 Maven 依赖,确保依赖包下载完成。 配置数据库环境,确保 MySQL 服务正常运行,并导入项目中提供的数据库脚本。 在 IDE 中启动项目,确认所有服务正常运行。 主要功能简述: 请假审批流程:系统支持请假申请的逐级审批,包括班主任审批和院系领导审批(针对超过三天的请假)。学生可以随时查看请假申请的审批进展情况。 请假记录管理:系统记录学生的所有请假记录,包括请假时间、原因、审批状态及审批意见等,供学生和审批人员查询。 学生在线请假:学生可以通过系统在线填写请假申请,包括请假的起止日期和请假原因,并提交给班主任审批。超过三天的请假需经班主任审批后,再由院系领导审批。 出勤信息记录:任课老师可以在线记录学生的上课出勤情况,包括迟到、早退、旷课和请假等状态。 出勤信息查询:学生、任课老师、班主任、院系领导和学校领导均可根据权限查看不同范围的学生上课出勤信息。学生可以查看自己所有学年的出勤信息,任课老师可以查看所教班级的出勤信息,班主任和院系领导可以查看本班或本院系的出勤信息,学校领导可以查看全校的出勤信息。 出勤统计与分析:系统提供出勤统计功能,可以按班级、学期等条件统计学生的出勤情况,帮助管理人员了解学生的出勤状况。 用户管理:系统管理员负责管理所有用户信息,包括学生、任课老师、班主任、院系领导和学校领导的账号创建、权限分配等。 数据维护:管理员可以动态更新和维护系统所需的数据,如学生信息、课程安排、学年安排等,确保系统的正常运行。 系统配置:管理员可以对系统进行配置,如设置数据库连接参数、调整系统参数等,以满足不同的使用需求。 身份验证:系统采用用户名和密码进行身份验证,确保只有授权用户才能访问系统。不同用户类型(学生、任课老师、班主任、院系领导、学校领导、系统管理员)具有不同的操作权限。 权限控制:系统根据用户类型分配不同的操作权限,确保用户只能访问和操作其权限范围内的功能和数据。 数据安全:系统采取多种措施保障数据安全,如数据库加密、访问控制等,防止数据泄露和非法访问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值