您好,欢迎访问代理记账网站
  • 价格透明
  • 信息保密
  • 进度掌控
  • 售后无忧

实验3:决策树

实验3:决策树

  • 实验目的

了解决策树的构建过程和代码实现,应用决策树解决实际问题。

  • 实验准备

安装python和pycharm,了解python基础编程和pycharm使用。

三、实验内容

基于iris数据集,补充完整下面决策树的相关程序,粘贴运行成功的结果截图,并给每行程序添加注释。

 

实验内容:

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
import numpy as np
import matplotlib.pyplot as plt
from collections import Counter
from math import log
from graphviz import Digraph                                  #以上均是导包操作

iris = load_iris()                  #数据集导入,加载 iris 数据集
x = iris.data                      

#包括样本的特征  data 里面是花萼长度、花萼宽度、花瓣长度、花瓣宽度的测量数据
y = iris.target                   

 #存储了data中每条记录属于哪一类鸢尾植物    标签(结果)
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=666666)
'''
feature_train, feature_test, target_train, target_test 分别代表训练集特征、测试集特征、训练集目标值、验证集特征。

train_data:待划分样本数据 对应x

train_target:待划分样本数据的结果(标签)  对应y

test_size:测试数据占样本数据的比例,,如果是整数的话就是样本的数量

random_state:设置随机数种子,保证每次都是同一个随机数。若为0或不填,则每次得到数据都不一样

'''

#树结构
class Node:
    def __init__(self,x_data, y_label, dimension, value):                 

 #创建树的结构,定义决策树节点包含的数据,及其赋值
        self.x_data = x_data      #样本数据
        self.y_label = y_label     #标签(什么种类的花)
        self.dimension = dimension  #维度索引
        self.value = value      #结果   划分特征的数值
        self.left = None     #左孩子
        self.right = None     #右孩子

    #计算熵H=-p1log(p1)-p2log(p2)-p3log(p3)-……-pnlog(pn)
def entropy(y_label):
    counter = Counter(y_label)  

 #读取标签数据,并用counter生成标签的字典数组,标签为键,值为出现的次数
    ent = 0.0                     #初始化熵值
    for num in counter.values():  #遍历counter.values(遍历标签的对应的个数)
        p =    float(num)/len(y_label)    

 #计算每个标签的概率    num对应标签出现的次数,len(y_label) 代表总体的数目,相除求概率
ent +=  -p*log(p)  

#计算熵           累加求和计算熵值
    return ent                    #返回熵值

#划分数据集    不断被调用,进行划分操作
def split(x_data, y_label, dimension, value):    #对所给数据进行划分
    """
    x_data:
输入特征
    y_label:输入标签类别
    dimension:选取输入特征的维度索引
    value:划分特征的数值
    return 左子树特征,右子树特征,左子树标签,右子树标签
    """
   
# 比较划分特征的数值与自身特征值
    index_left = (x_data[:, dimension] <= value)          #若小于则为左子树
    index_right = (x_data[:, dimension] > value)          #否则为右子树
    #相当于进行划分
    return x_data[index_left], x_data[index_right], y_label[index_left], y_label[index_right]  

 #将划分之后的树返回

#划分一次数据集    确定特征和数值     训练过程
#遍历所有维度的特征,不断寻找一个合适的划分数值,找到能把熵降到最低的那个特征和数值
def one_split(x_data, y_label):                  #将数据集和数据标签传递到函数中
    best_entropy = float('inf') #正无穷
    best_dimension = -1         #初始化维度索引,无意义
    best_value = -1             #初始化划分特征的数值,无意义

    for d in range(  x_data.shape[1]     ):  

 #循环特征      #####对每个特征进行划分,所以这里要循环遍历维度索引
        sorted_index = np.argsort(x_data[:, d])  

 #对数据按照不同纬度方向进行排序,并返回索引
        for i in range(1, len(x_data)):            #遍历数据集中所有的数据
            if x_data[sorted_index[i], d] != x_data[sorted_index[i - 1], d]:   

#判断前后两组数据的值是否相等,除掉一些不必要的运算,加快程序执行时间
                value = (x_data[sorted_index[i], d] + x_data[sorted_index[i - 1], d]) / 2  

#如果不相等,让两组数据中的value值取中,作为备选值
                x_left, x_right, y_left, y_right = split(x_data, y_label, d, value)        

#调用划分函数,进行划分操作
                p_left=len(x_left)/len(x_data)                                                                 

#求出划分到左子树的概率
                p_right = len(x_right) / len(x_data)                                       

#求出划分到右子树的概率
                ent = p_left * entropy(y_left) + p_right * entropy(y_right)                

#计算两者熵值之和
                if ent < best_entropy:                                                      

#若新的熵值较小,那么证明新的value值更适合,则将对应维度的最佳熵  值、最佳划分值进行更新

best_entropy =ent                                                      

#将当前熵值赋值给最佳熵值
                    best_dimension =d                                                      

#维度索引更新,保持与当前一致
                    best_value = value                                                     

#更新value值
    return best_entropy, best_dimension, best_value                                        

#返回最优的划分熵值、索引、划分值

#创建决策树
def create_tree(x_data, y_label):                     #传入数据集以及标签结果
    ent, dim, value = one_split(x_data, y_label)      #对数据集进行一次划分
    x_left, x_right, y_left, y_right = split(x_data, y_label, dim, value)  

 #根据得到的划分数据(dim、vlaue值)对测试数据集进行划分
    node = Node(x_data, y_label, dim, value)                                 

#初始化划分节点,根据划分节点进行判断花的种类  (二分)
    if ent < 0.000000001:                                                   

#判断精度,即当熵值小于一定值时,认为划分是正确的
        return node                                                         

#返回这个节点,叶子节点
    node.left = create_tree(      x_left    ,    y_left        )#创建左子树
    node.right = create_tree(     x_right     ,        y_right   ) #创建右子树
    return node      

#返回当前树根节点,这样就构造出一棵决策树,所以第一个返回的值即为整棵树的根节点

#根据已创建的决策树,查找所属类别
def travel(x_data, node):        

 #   传入待验证样本数据    传入已创建完成的决策树的根节点
    p = node                       #将树的根节点赋值给p
    if x_data[p.dimension] <= p.value and p.left:                

#如果满足左子树条件且左子树不为空
        pred = travel(x_data, p.left)
    elif x_data[p.dimension] > p.value and p.right:             

#如果满足右子树条件且右子树不为空
        pred = travel(x_data, p.right)
    else:     #否则到达叶子节点,判断结束
        counter = Counter(p.y_label)                             

#将标签种类生成对应的字典数组
        pred = counter.most_common(1)[0][0]                     

#统计出现频率最高的标签,只有一个也就是0 1判断,将是1(值)的标签(key)返回
    return pred            #将该值返回,证明此数据

#预测函数
def predict(node,x_predict):                 #传入决策树和预测样本集
    y_predict = []                                             

 #用于存储获得的决策结果标签集   (由该程序创建的决策树的决策结果)
    for data in x_predict:                   #遍历预测样本
        y_pred = travel(data, node)          #对每一个遍历的数据进行决策判断
        y_predict.append(y_pred)           #存储正确的结果集
    return np.array(y_predict)               #返回该结果集

#预测准确率
def score( x_test, y_test,node):          #传入测试数据集、测试数据标签集、决策树根节点
    y_predict = predict(node,x_test)     #调用预测函数,返回值为预测数据标签集
    return np.sum(y_predict == y_test) / len(y_predict)         

 #比较预测数据标签集和正确测试数据标签集,并返回正确预测的个数与测试个树的比值,即是预测正确率





if __name__ == '__main__':
    node=create_tree(x_data=x_train,y_label=y_train)           

  #根据训练集生成决策树,并保存决策树根节点
    xx=score(x_test,y_test,node)        #调用计算预测正确率函数,返回正确率
    print(xx)                        #打印正确率

 

 

实验结果:


分享:

低价透明

统一报价,无隐形消费

金牌服务

一对一专属顾问7*24小时金牌服务

信息保密

个人信息安全有保障

售后无忧

服务出问题客服经理全程跟进