【手搓深度学习算法】用决策树预测天气-离散数据篇

用决策树预测天气

想看连续型数据的,请看另一篇文章 “【手搓深度学习算法】用决策树预测天气-线性数据篇”
【手搓深度学习算法】用决策树预测天气-连续数据篇

前言

前几天已经探讨了使用决策树训练和预测连续型数据,观察到训练连续数据存在一个问题:训练时间过长,如果数据中特征很多,特征取值范围很大,将会难以计算,于是想要对比决策树对于离散型数据的处理方法和训练时间。
本文使用信息增益率来生成决策树,现如今有更流行和高效的决策树生成方法,有待进一步探索

决策树发展过程可以分为以下几个阶段:
早期决策树算法:最早的决策树算法可以追溯到上世纪60年代,当时主要用于解决分类问题。这些算法比较简单,通常采用静态规则进行决策,但缺乏对数据内在结构的深入理解和挖掘。
ID3算法:1970年代末,Ross Quinlan提出了ID3算法。ID3算法基于信息增益来选择划分属性,并使用树结构来表示分类模型。ID3算法的优点是简单易理解,可解释性强;缺点是容易过拟合,对可取值数目多的属性有所偏好。
C4.5算法:C4.5算法是ID3算法的改进版,主要解决了ID3算法中存在的两个问题:对于可取值数目多的属性有所偏好以及无法处理连续属性。C4.5算法采用信息增益率来选择划分属性,同时引入了剪枝策略来避免过拟合。C4.5算法还能够处理缺失值和自动进行特征选择。
CART算法:CART(Classification and Regression Trees)算法是一种非常流行的决策树算法,它既可以用于分类问题也可以用于回归问题。CART算法采用基尼不纯度来选择划分属性,并使用二叉树来表示分类模型。CART算法的优点是简单易理解、可解释性强,能够处理连续属性和缺失值;缺点是可能会产生过于复杂的决策树。
随机森林和梯度提升树:随机森林和梯度提升树是近年来发展起来的集成学习算法,它们结合了决策树和其他学习算法的优点,具有更高的准确率和更好的泛化性能。随机森林通过构建多棵决策树并取平均值来提高准确率;梯度提升树则通过迭代地添加新的决策树来改进模型。
以上就是决策树算法的发展过程和各代流行算法的优缺点。在实际应用中,可以根据具体问题和数据的特点选择合适的决策树算法来构建分类或回归模型。

–离散型数据

在决策树中,处理离散型数据和连续性数据的方式存在一些区别。

离散型数据:对于离散型数据,我们可以直接使用决策树的基本操作来进行训练和预测。例如,我们可以根据某个特定的属性值(也就是离散的取值)来划分数据集,然后在每个子节点中再次进行相同的操作。这种方式非常直观,也容易理解。

和连续型数据的区别

在本次实验中,我们使用相同的数据集,但是,对数据集的每一个特征进行了离散化处理,如果,假设气温的取值范围是-5到23度,那么我们将气温通过取值范围简单的划分为“低,中,高”,于是气温特征取值不再连续,而被认为是三种截然不同的选择,这样的处理方式可能不一定科学,仅供研究。

变化

数据集变化

离散型数据

额外的处理

离散型数据可能存在用完了所有特征还是无法做出决策,或者某些特征分支的信息增益比太低,会被剪枝,因此当特征用完时需要计算训练集中,到当前特征为止,各种可能性存在的概率,以便在预测时,当运行到叶子节点还是无法做出决策时,使用概率来预测结果。

更快的构建速度

在连续型数据中,我们需要为每个特征计算所有可能的决策边界,然后计算其左右子树的信息增益比的和,在离散型数据中,只需要计算当前可选的每个特征带来的信息增益比的和,显而易见,离散型数据的计算量更小。
如下图,
连续型数据构建时间为29.53秒
连续型数据训练时间
手动离散的数据构建时间为0.29秒
在这里插入图片描述

相似的精度

在本文讨论的数据集中,两种方式具有相似的精度
在这里插入图片描述

定义数据集

用于从CSV文件中读取数据,并将其转换为数组形式。如果is_test参数为真,则返回测试数据集;否则,返回训练数据集。

import numpy as np
import csv

kunming_weather = "J:\\MachineLearning\\数据集\\kunming_weather_new.txt"
def create_dataset(is_test = False):
    dataset = [] 
    # 打开CSV文件  
    with open(kunming_weather, 'r') as file:  
        reader = csv.reader(file) 
        # 初始化一个空数组来存储数据  
        dataset = [] 
        # 遍历每一行数据  
        for row in reader:  
            # 将每一行数据转换为数组,并添加到data数组中  
            dataset.append(row)  
    
    np.random.shuffle(dataset) #将数据按行充分打乱
    '''
    labels = ["MeanAirPressure",
              "DailyMinimumAirPressure",
              "MeanTempe",
              "DailyMinTempe",
              "MeanRelativeHumidity",
              "CumulativePrecipitation",
              "LargeEvaporation",
              "AverageWindSpd",
              "MaximumWindSpd",
              "SunshineDuration",
              "MeanSurfaceTempe",
              "DailyMinimumSurfaceTempe",
              "WhetherItSnows"]
    '''
    features = ["MAP",
                "DMAP",
                "MT",
                "DMT",
                "MRH",
                "CP",
                "LE",
                "AWS",
                "MWS",
                "SD",
                "MST",
                "DMST"]
    train_count = int(len(dataset) * 0.8)
    train_dataset = dataset[1 : train_count]
    if (is_test):
        test_dataset = dataset[train_count:]
        test_source = []
        for data in test_dataset:
            row_data = {}
            for feature_index in range(len(features)):
                row_data[features[feature_index]] = data[feature_index]
            row_data["result"] = data[-1]
            test_source.append(row_data)
        return test_source
    

    return train_dataset, features

create_dataset(True)

创建决策树

构建决策树。它首先选择最优的特征进行分割,然后递归地在每个子节点上重复这个过程。

import operator


def create_tree(dataset, lables, feature_lables):
    # 获取数据集中所有样本的类别
    class_list = [example[-1] for example in dataset]
    # 如果所有样本的类别都相同,那么返回这个类别,比如剩下的样本标签全部都是“会下雪”,那么当前前置的所有条件都会连接“会下雪”的结果
    if class_list.count(class_list[0]) == len(class_list):
        return class_list[0]
    # 如果数据集中只剩下一个特征,那么返回最多的类别
    if len(dataset[0]) == 1:
        return majority_cnt(class_list)
    # 选择最好的特征进行分割
    best_feature = choose_best_feature_to_split(dataset)
    # 获取最好的特征的标签
    best_feature_label = lables[best_feature]
    # 将最好的特征的标签添加到特征标签列表中
    feature_lables.append(best_feature_label)
    # 创建决策树
    my_tree = {best_feature_label:{}}
    # 计算并添加默认类别
    my_tree[best_feature_label]['default'] = majority_cnt(class_list)
    # 删除已经使用的特征标签
    del lables[best_feature]
    # 获取最好的特征的所有值
    feature_value = [example[best_feature] for example in dataset]
    # 获取最好的特征的所有唯一值
    unique_val = set(feature_value)
    # 对每一个唯一值,递归创建决策树
    for value in unique_val:
        sublabels = lables[:]
        my_tree[best_feature_label][value] = create_tree(
            remove_feature_from_dataset(dataset, best_feature, value),
            sublabels, 
            feature_lables)
    # 返回决策树
    return my_tree

当特征时最后一个,且子节点分类并不唯一,选取数量较多的那一类返回

选取当前特征对应的样本中,出现次数最多的可能

import operator


def majority_cnt(class_list):
    class_count = {}
    for vote in class_list:
        if vote not in class_count.keys():
            class_count[vote] = 0 #创建节点,值置为0
        class_count[vote] += 1
        sorted_class_count = sorted(class_count.items(), key=operator.itemgetter(1), reverse=True)
        return sorted_class_count[0][0]

计算当前决策树的熵值

信息增益比是决策树算法中的一个重要概念,它是用来选择最优划分属性的一种方法。信息增益比的计算流程可以分为以下几个步骤:

  1. 计算数据集的原始信息熵:信息熵是度量数据集混乱程度的一个指标。在决策树中,我们首先需要计算出整个数据集的信息熵。这个过程通常是通过统计数据集中每个类别的样本数量,然后计算出每个类别的概率,最后将这些概率代入信息熵的公式进行计算。

  2. 计算每个属性划分后的信息熵:接下来,我们需要计算出每个属性划分后的信息熵。这个过程通常是通过将数据集按照每个属性的不同取值进行划分,然后分别计算出每个子集的信息熵,最后将这些信息熵按照每个子集的样本数量权重进行加权平均。

  3. 计算每个属性的信息增益:信息增益是指数据集在某个属性划分后的信息熵减去原始信息熵。我们需要计算出每个属性的信息增益,这个过程通常是通过将每个属性划分后的信息熵减去原始信息熵进行计算。

  4. 计算每个属性的分裂信息值:分裂信息值是度量属性划分样本集合的一个指标。我们需要计算出每个属性的分裂信息值,这个过程通常是通过统计每个属性的不同取值的样本数量,然后计算出每个取值的概率,最后将这些概率代入分裂信息值的公式进行计算。

  5. 计算每个属性的信息增益比:信息增益比是指信息增益除以分裂信息值。我们需要计算出每个属性的信息增益比,这个过程通常是通过将每个属性的信息增益除以其分裂信息值进行计算。

  6. 选择信息增益比最大的属性作为最优划分属性:最后,我们需要选择出信息增益比最大的属性作为最优划分属性。这个过程通常是通过比较所有属性的信息增益比,然后选择出信息增益比最大的属性。

Gain Ratio = Information Gain Split Information \text{Gain Ratio} = \frac{\text{Information Gain}}{\text{Split Information}} Gain Ratio=Split InformationInformation Gain

其中,

信息增益 (Information Gain):

Information Gain = Entropy(Parent) − ∑ ( Number of samples in child Number of samples in parent ∗ Entropy(Child) ) \text{Information Gain} = \text{Entropy(Parent)} - \sum \left(\frac{\text{Number of samples in child}}{\text{Number of samples in parent}} * \text{Entropy(Child)}\right) Information Gain=Entropy(Parent)(Number of samples in parentNumber of samples in childEntropy(Child))

分裂信息 (Split Information):

Split Information = − ∑ ( Number of samples in child Number of samples in parent ∗ log ⁡ 2 ( Number of samples in child Number of samples in parent ) ) \text{Split Information} = - \sum \left(\frac{\text{Number of samples in child}}{\text{Number of samples in parent}} * \log_2 \left(\frac{\text{Number of samples in child}}{\text{Number of samples in parent}}\right)\right) Split Information=(Number of samples in parentNumber of samples in childlog2(Number of samples in parentNumber of samples in child))

熵 (Entropy):

Entropy = − ∑ ( P i ∗ log ⁡ 2 ( P i ) ) \text{Entropy} = - \sum (P_i * \log_2(P_i)) Entropy=(Pilog2(Pi))

其中, P i P_i Pi 是第 i i i 类样本在总样本中的比例。

from math import log


def calcEnt(dataset):
    num_examples = len(dataset) # 计算数据集中的样本数量
    label_counts = {} # 创建一个字典,用来存储每个标签的数量

    # 遍历数据集中的每个样本
    for feature in dataset:
        current_label = feature[-1] # 获取样本的标签,假设标签是样本的最后一个特征

        # 如果当前标签不在字典中,就在字典中添加这个标签,并设置数量为0
        if (current_label not in label_counts.keys()):
            label_counts[current_label] = 0

        # 将当前标签的数量加1
        label_counts[current_label] += 1

    ret_ent = 0 # 初始化熵为0

    # 遍历每个标签
    for key in label_counts:
        prop = float(label_counts[key] / num_examples) # 计算当前标签的概率

        # 根据熵的公式,计算并累加每个标签的熵
        ret_ent += - (prop * log(prop, 2))

    return ret_ent # 返回数据集的熵

删掉已经被选作特征的数据集部分

def remove_feature_from_dataset(dataset, axis, val):
    ret_dataset = []
    for feature in dataset:
        if (feature[axis] == val):
            reduced_feature = feature[:axis] #取当前列前面的列
            #np.concatenate((reduced_feature, feature[axis+1:]), axis=0)
            reduced_feature.extend(feature[axis+1:]) #连接当前列后面的列
            ret_dataset.append(reduced_feature)
    return ret_dataset

选取最佳特征

用于选择最优的特征进行分割。它通过计算每个特征的信息增益来选择最优的特征。

def choose_best_feature_to_split(dataset):
    num_features = len(dataset[0]) - 1 #特征数量(减去标签列)
    base_entropy = calcEnt(dataset) #数据集的初始熵
    best_info_gain = 0 #初始信息增益比为0
    best_feature = -1
    for i in range(num_features):
        feature_list = [example[i] for example in dataset] #取当前特征对应的所有的样本值
        unique_vals = set(feature_list) #取当前特征对应的所有可能样本
        new_entropy = 0
        for val in unique_vals:
            sub_dataset = remove_feature_from_dataset(dataset, i, val) #当前特征已经加入决策树了,需要移除
            prop = len(sub_dataset) / float(len(dataset))
            new_entropy += prop * calcEnt(sub_dataset) #当前分类的概率乘子类的熵
        info_gain = base_entropy - new_entropy #信息增益
        if (info_gain > best_info_gain): # base_entropy - new_entropy > base_entropy
            best_info_gain = info_gain
            best_feature = i
    return best_feature

可视化展示

from graphviz import Digraph


def visualize_decision_tree(tree, name="DecisionTree"):    
    def add_edges(graph, subtree, parent_node):    
        for key, value in subtree.items():    
            if isinstance(value, dict):    
                sub_node = f"{parent_node}_{str(key)}"  # 将key转换为字符串  
                graph.edge(parent_node, sub_node, label=str(key))  # 将label转换为字符串  
                add_edges(graph, value, sub_node)    
            else:    
                graph.edge(parent_node, str(value), label=str(key))  # 将value和label转换为字符串  
    
    graph = Digraph(name=name, format="png")    
    graph.attr('node', shape='Mrecord')    
    add_edges(graph, tree, "root")    
    return graph    

预测

用于预测新的数据。它通过遍历决策树,根据输入的参数选择合适的路径,最终得到预测结果。

def predict(node, parameters : dict):
    # 如果当前节点是字符串,那么直接返回这个字符串
    if isinstance(node, str):
        return node
    # 如果当前节点是字典,那么根据参数字典中的值选择一个子节点
    else:
        for key, value in node.items():
            #print ("key = {}, value = {}".format(key, value))
            if (key in parameters.keys()):
                if not (parameters[key] in value.keys()):
                    return value.get('default', None)
                current_node = value[parameters[key]]
                result = predict(current_node, parameters)
                if result is not None:
                    return result
            else:
                current_node = None
        return None

训练和验证

import json


if (__name__ == "__main__"):
    dataset, label = create_dataset()
    test_source = create_dataset(True)
    feature_labels = [] #特征排序,初始化为空
    my_tree = create_tree(dataset, label, feature_labels)
    
    test_tree = my_tree
    predict_true_count = 0
    predict_count = 0
    fail_info_array = []
    for test_item in test_source:
        predict_count += 1
        predict_result = predict(test_tree, test_item)
        if (predict_result == test_item["result"]):
            predict_true_count += 1
            if (predict_true_count % 100 == 0):
                print("Test {} / {} pcs of data is true".format(predict_true_count, predict_count))
        else:
            fail_info = ""
            for key, value in test_item.items():
                fail_info += "{} : {} , ".format(key, value)
            fail_info = "Predict result is {} actual is {} ".format(predict_result, test_item["result"]) + fail_info
            fail_info_array.append(fail_info)
    print(fail_info_array)
    print("Accuracy is {}".format(predict_true_count / len(test_source)))
    with open('data.json', 'w') as file:  
        json.dump(my_tree, file)
    
    # 可视化决策树  
    graph = visualize_decision_tree(my_tree)  
    graph.view()  # 这将在默认的图片查看器中显示决策树图像

完整代码(数据集在绑定的资源里,想尝试的去下载吧)

import numpy as np
import csv
import json
import time

kunming_weather = "J:\\MachineLearning\\数据集\\kunming_weather_new.txt"
def create_dataset(is_test = False):
    dataset = [] 
    # 打开CSV文件  
    with open(kunming_weather, 'r') as file:  
        reader = csv.reader(file) 
        # 初始化一个空数组来存储数据  
        dataset = [] 
        # 遍历每一行数据  
        for row in reader:  
            # 将每一行数据转换为数组,并添加到data数组中  
            dataset.append(row)  
    
    np.random.shuffle(dataset) #将数据按行充分打乱
    '''
    labels = ["MeanAirPressure",
              "DailyMinimumAirPressure",
              "MeanTempe",
              "DailyMinTempe",
              "MeanRelativeHumidity",
              "CumulativePrecipitation",
              "LargeEvaporation",
              "AverageWindSpd",
              "MaximumWindSpd",
              "SunshineDuration",
              "MeanSurfaceTempe",
              "DailyMinimumSurfaceTempe",
              "WhetherItSnows"]
    '''
    features = ["MAP",
                "DMAP",
                "MT",
                "DMT",
                "MRH",
                "CP",
                "LE",
                "AWS",
                "MWS",
                "SD",
                "MST",
                "DMST"]
    train_count = int(len(dataset) * 0.8)
    train_dataset = dataset[1 : train_count]
    if (is_test):
        test_dataset = dataset[train_count:]
        test_source = []
        for data in test_dataset:
            row_data = {}
            for feature_index in range(len(features)):
                row_data[features[feature_index]] = data[feature_index]
            row_data["result"] = data[-1]
            test_source.append(row_data)
        return test_source
    

    return train_dataset, features

import operator


def majority_cnt(class_list):
    class_count = {}
    for vote in class_list:
        if vote not in class_count.keys():
            class_count[vote] = 0 #创建节点,值置为0
        class_count[vote] += 1
        sorted_class_count = sorted(class_count.items(), key=operator.itemgetter(1), reverse=True)
        return sorted_class_count[0][0]
        
from math import log


def calcEnt(dataset):
    num_examples = len(dataset) # 计算数据集中的样本数量
    label_counts = {} # 创建一个字典,用来存储每个标签的数量

    # 遍历数据集中的每个样本
    for feature in dataset:
        current_label = feature[-1] # 获取样本的标签,假设标签是样本的最后一个特征

        # 如果当前标签不在字典中,就在字典中添加这个标签,并设置数量为0
        if (current_label not in label_counts.keys()):
            label_counts[current_label] = 0

        # 将当前标签的数量加1
        label_counts[current_label] += 1

    ret_ent = 0 # 初始化熵为0

    # 遍历每个标签
    for key in label_counts:
        prop = float(label_counts[key] / num_examples) # 计算当前标签的概率

        # 根据熵的公式,计算并累加每个标签的熵
        ret_ent += - (prop * log(prop, 2))

    return ret_ent # 返回数据集的熵

def remove_feature_from_dataset(dataset, axis, val):
    ret_dataset = []
    for feature in dataset:
        if (feature[axis] == val):
            reduced_feature = feature[:axis] #取当前列前面的列
            #np.concatenate((reduced_feature, feature[axis+1:]), axis=0)
            reduced_feature.extend(feature[axis+1:]) #连接当前列后面的列
            ret_dataset.append(reduced_feature)
    return ret_dataset

def choose_best_feature_to_split(dataset):
    num_features = len(dataset[0]) - 1 #特征数量(减去标签列)
    base_entropy = calcEnt(dataset) #数据集的初始熵
    best_info_gain = 0 #初始信息增益比为0
    best_feature = -1
    for i in range(num_features):
        feature_list = [example[i] for example in dataset] #取当前特征对应的所有的样本值
        unique_vals = set(feature_list) #取当前特征对应的所有可能样本
        new_entropy = 0
        for val in unique_vals:
            sub_dataset = remove_feature_from_dataset(dataset, i, val) #当前特征已经加入决策树了,需要移除
            prop = len(sub_dataset) / float(len(dataset))
            new_entropy += prop * calcEnt(sub_dataset) #当前分类的概率乘子类的熵
        info_gain = base_entropy - new_entropy #信息增益
        if (info_gain > best_info_gain): # base_entropy - new_entropy > base_entropy
            best_info_gain = info_gain
            best_feature = i
    return best_feature

import operator


def create_tree(dataset, lables, feature_lables):
    # 获取数据集中所有样本的类别
    class_list = [example[-1] for example in dataset]
    # 如果所有样本的类别都相同,那么返回这个类别,比如剩下的样本标签全部都是“会下雪”,那么当前前置的所有条件都会连接“会下雪”的结果
    if class_list.count(class_list[0]) == len(class_list):
        return class_list[0]
    # 如果数据集中只剩下一个特征,那么返回最多的类别
    if len(dataset[0]) == 1:
        return majority_cnt(class_list)
    # 选择最好的特征进行分割
    best_feature = choose_best_feature_to_split(dataset)
    # 获取最好的特征的标签
    best_feature_label = lables[best_feature]
    # 将最好的特征的标签添加到特征标签列表中
    feature_lables.append(best_feature_label)
    # 创建决策树
    my_tree = {best_feature_label:{}}
    # 计算并添加默认类别
    my_tree[best_feature_label]['default'] = majority_cnt(class_list)
    # 删除已经使用的特征标签
    del lables[best_feature]
    # 获取最好的特征的所有值
    feature_value = [example[best_feature] for example in dataset]
    # 获取最好的特征的所有唯一值
    unique_val = set(feature_value)
    # 对每一个唯一值,递归创建决策树
    for value in unique_val:
        sublabels = lables[:]
        my_tree[best_feature_label][value] = create_tree(
            remove_feature_from_dataset(dataset, best_feature, value),
            sublabels, 
            feature_lables)
    # 返回决策树
    return my_tree

from graphviz import Digraph


def visualize_decision_tree(tree, name="DecisionTree"):    
    def add_edges(graph, subtree, parent_node):    
        for key, value in subtree.items():    
            if isinstance(value, dict):    
                sub_node = f"{parent_node}_{str(key)}"  # 将key转换为字符串  
                graph.edge(parent_node, sub_node, label=str(key))  # 将label转换为字符串  
                add_edges(graph, value, sub_node)    
            else:    
                graph.edge(parent_node, str(value), label=str(key))  # 将value和label转换为字符串  
    
    graph = Digraph(name=name, format="png")    
    graph.attr('node', shape='Mrecord')    
    add_edges(graph, tree, "root")    
    return graph   

def predict(node, parameters : dict):
    # 如果当前节点是字符串,那么直接返回这个字符串
    if isinstance(node, str):
        return node
    # 如果当前节点是字典,那么根据参数字典中的值选择一个子节点
    else:
        for key, value in node.items():
            #print ("key = {}, value = {}".format(key, value))
            if (key in parameters.keys()):
                if not (parameters[key] in value.keys()):
                    return value.get('default', None)
                current_node = value[parameters[key]]
                result = predict(current_node, parameters)
                if result is not None:
                    return result
            else:
                current_node = None
        return None


if (__name__ == "__main__"):
    dataset, label = create_dataset()
    test_source = create_dataset(True)
    feature_labels = [] #特征排序,初始化为空
    train_start_time = time.time()
    my_tree = create_tree(dataset, label, feature_labels)
    train_end_time = time.time()
    elapsed_time = train_end_time - train_start_time
    print ("train takes {} seconds".format(elapsed_time))
    test_tree = my_tree
    predict_true_count = 0
    predict_count = 0
    fail_info_array = []
    test_start_time = time.time()
    for test_item in test_source:
        predict_count += 1
        predict_result = predict(test_tree, test_item)
        if (predict_result == test_item["result"]):
            predict_true_count += 1
            if (predict_true_count % 100 == 0):
                print("Test {} / {} pcs of data is true".format(predict_true_count, predict_count))
        else:
            fail_info = ""
            for key, value in test_item.items():
                fail_info += "{} : {} , ".format(key, value)
            fail_info = "Predict result is {} actual is {} ".format(predict_result, test_item["result"]) + fail_info
            fail_info_array.append(fail_info)
    test_end_time = time.time()
    elapsed_test_time = test_end_time - test_start_time
    print ("test takes {} seconds".format(elapsed_test_time))
    print(fail_info_array)
    print("Accuracy is {}".format(predict_true_count / len(test_source)))
    with open('data.json', 'w') as file:  
        json.dump(my_tree, file)
    
    # 可视化决策树  
    graph = visualize_decision_tree(my_tree)  
    graph.view()  # 这将在默认的图片查看器中显示决策树图像
  • 25
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面我分别回答你的两个问题。 关于莺尾花数据集,我需要先介绍一下这个数据集。莺尾花数据集是机器学习领域中常用的数据集之一,由英国统计学家Ronald Fisher在1936年收集整理。它包含了150个样本,分为三类,每类50个样本。每个样本都有4个特征,分别是花萼长度、花萼宽度、花瓣长度和花瓣宽度。莺尾花数据集是一个非常经典的分类问题,可以用来训练各种机器学习模型,比如决策树决策树是一种基于树结构进行决策的算法,它可以用于分类和回归问题。在分类问题中,决策树通过对特征的判断逐步向下遍历树结构,最终得到分类结果。决策树的训练过程就是寻找最优的特征划分,使得每个子节点的样本都属于同一类别。在莺尾花数据集上训练出的决策树可以用来对新的样本进行分类。 下面是使用 Python 中的 scikit-learn 库对莺尾花数据集训练决策树的示例代码: ```python from sklearn.datasets import load_iris from sklearn.tree import DecisionTreeClassifier from sklearn.tree import export_graphviz import graphviz # 加载莺尾花数据集 iris = load_iris() # 构建决策树模型 clf = DecisionTreeClassifier() # 训练决策树模型 clf.fit(iris.data, iris.target) # 导出决策树图形 dot_data = export_graphviz(clf, out_file=None, feature_names=iris.feature_names, class_names=iris.target_names, filled=True, rounded=True, special_characters=True) graph = graphviz.Source(dot_data) graph.render("iris") # 可视化决策树 graph.view() ``` 上述代码中,我们首先使用 scikit-learn 库中的 load_iris() 函数加载莺尾花数据集,然后构建一个 DecisionTreeClassifier 类的实例 clf,并使用 fit() 方法对数据集进行训练。最后,使用 export_graphviz() 函数将决策树导出为图形,并使用 graphviz 库将图形可视化。 接下来是关于 K-means 聚类算法的部分。 K-means 聚类算法是一种常用的无监督学习算法,它将样本集合分成 K 个簇,使得簇内的样本相似度较高,而簇间的相似度较低。K-means 算法的过程可以概括为以下几个步骤: 1. 随机初始化 K 个簇的质心; 2. 将每个样本分配到距离其最近的质心所在的簇; 3. 计算每个簇的质心; 4. 重复步骤2和步骤3,直到质心不再变化或达到最大迭代次数。 K-means 算法的输出结果是 K 个簇的质心以及每个样本所属的簇。 下面是使用 Python 中的 scikit-learn 库对莺尾花数据集进行 K-means 聚类的示例代码: ```python from sklearn.datasets import load_iris from sklearn.cluster import KMeans # 加载莺尾花数据集 iris = load_iris() # 构建 K-means 聚类模型 kmeans = KMeans(n_clusters=3) # 训练 K-means 聚类模型 kmeans.fit(iris.data) # 输出聚类结果 print(kmeans.labels_) ``` 上述代码中,我们首先使用 scikit-learn 库中的 load_iris() 函数加载莺尾花数据集,然后构建一个 KMeans 类的实例 kmeans,并使用 fit() 方法对数据集进行训练。最后,使用 labels_ 属性输出每个样本所属的簇。 希望这些代码能够对你有所帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值