精华内容
下载资源
问答
  • 2020-11-14 00:04:15

    链接:https://pan.baidu.com/s/1ix_c0dGHsET4yxPhc025cg
    提取码:h24l
    提取码是永久的,直接提取就好了。

    更多相关内容
  • 《机器学习》第五章所介绍了BP网络,这个西瓜数据集是我为了方便进行BP网络测试而制作的。 测试过程:https://blog.csdn.net/weixin_40973138/article/details/118073949?spm=1001.2014.3001.5501
  • 西瓜数据集

    2019-05-22 14:55:22
    西瓜数据集3.0 及西瓜数据集4.0 ,方便以后学习与使用。
  • 30条西瓜数据集,机器学习样例数据。
  • 关于C4.5的MATLAB实现,包含数据集在内,可以实现西瓜数据集的分类,比较简陋,大家拿来做个参考吧~
  • 西瓜数据集3.0-数据集

    2021-03-04 21:37:37
    西瓜数据集3.0 包括(3.0和3.0a) watermelon_3.csv watermelon_3a.csv
  • 西瓜数据集共17个数据,用这个数据集做一个决策树,输出以图形的形式输出或以列表的形式输出,每一次中间节点分类的时候都要把输出的图形显示出来
  • 该数据集为西瓜数据集4.0,可做多种聚类使用,在我的博客《机器学习之K-means算法(小白入门级别)》的代码中使用。
  • 西瓜书-西瓜数据集2.0

    2021-03-31 13:27:35
    csv格式,u-f8编码
  • 朴素贝叶斯相关西瓜数据集,用于自然语言处理>01.朴素贝叶斯介绍 中的案例数据,该数据集仅作参考使用
  • 西瓜书的西瓜数据集,用于决策树算法
  • 人工智能西瓜数据集——决策树
  • 南瓜、西瓜、西红柿图片数据集,用于Fine Tuning的学习,包括训练集和验证集。 具体代码可参考:https://cchang.blog.csdn.net/article/details/86422080
  • 周志华《机器学习》一书中大量例题习题用到了“西瓜数据集3.0”和“西瓜数据集3.0a”,两个数据集的区别是“西瓜数据集3.0”有离散属性而“西瓜数据集3.0a”都是连续属性。生成这两个数据集的代码如下,运行代码即可...

    周志华《机器学习》一书中大量例题习题用到了“西瓜数据集3.0”和“西瓜数据集3.0a”,两个数据集的区别是“西瓜数据集3.0”有离散属性而“西瓜数据集3.0a”都是连续属性。生成这两个数据集的代码如下,运行代码即可生成python数据文件watermelon_3.0.npzwatermelon_3.0a.npz

    write_dataset_watermelon3.py

    # -*- coding: utf-8 -*-
    """
    Created on Mon Aug 27 21:24:11 2018
    
    Write 'Machine Learning, Zhihua Zhou' P84 watermelon_3.0 dataset to
    'watermelon_3.0.npy'
    
    @author: weiyx15
    """
    
    ''' 
    [x]
    色泽:乌黑-0, 青绿-1, 浅白-2
    根蒂:蜷缩-0, 稍蜷-1, 硬挺-2
    敲声:浊响-0, 沉闷-1, 清脆-2
    纹理:清晰-0, 稍糊-1, 模糊-2
    脐部:凹陷-0, 稍凹-1, 平坦-2
    触感:硬滑-0, 软粘-1
    密度:<数值>
    含糖率:<数值>
    [y]
    好瓜:是-0, 否-1
    '''
    
    import numpy as np
    
    xn_discrete = 6
    xn_continuous = 2
    yn = 2
    x_discrete =  [3, 3, 3, 3, 3, 2]
    x = np.array([[1, 0, 0, 0, 0, 0, .697, .46], 
                  [0, 0, 1, 0, 0, 0, .774, .376], 
                  [0, 0, 0, 0, 0, 0, .634, .264], 
                  [1, 0, 1, 0, 0, 0, .608, .318], 
                  [2, 0, 0, 0, 0, 0, .556, .215], 
                  [1, 1, 0, 0, 1, 1, .403, .237], 
                  [0, 1, 0, 1, 1, 1, .481, .149], 
                  [0, 1, 0, 0, 1, 0, .437, .211], 
                  [0, 1, 1, 1, 1, 0, .666, .091], 
                  [1, 2, 2, 0, 2, 1, .243, .267], 
                  [2, 2, 2, 2, 2, 0, .245, .057], 
                  [2, 0, 0, 2, 2, 1, .343, .099], 
                  [1, 1, 0, 1, 0, 0, .639, .161], 
                  [2, 1, 1, 1, 0, 0, .657, .198], 
                  [0, 1, 0, 0, 1, 1, .36, .37], 
                  [2, 0, 0, 2, 2, 0, .593, .042], 
                  [1, 0, 1, 1, 1, 0, .719, .103]])
    y = np.array([1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0])
    np.savez('watermelon_3.0.npz', xn_discrete, xn_continuous, yn, x_discrete, x, y)

    write_dataset_watermelon3a.py

    # -*- coding: utf-8 -*-
    """
    Created on Mon Aug 20 20:19:18 2018
    
    Write 'Machine Learning, Zhihua Zhou' P89 watermelon_3.0a dataset to
    'watermelon_3.0a.npy'
    
    @author: weiyx15
    """
    
    import numpy as np
    
    x = np.array([[.697, .46], [.774, .376], [.634, .264], [.608, .318], 
                  [.556, .215], [.403, .237], [.481, .149], [.437, .211], 
                  [.666, .091], [.243, .267], [.245, .057], [.343, .099], 
                  [.639, .161], [.657, .198], [.36, .37], [.593, .042], 
                  [.719, .103]])
    y = np.array([1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0])
    np.savez('watermelon_3.0a.npz', x, y)

     

    展开全文
  • xgboost训练数据集
  • 1 则为离散值,若长度为 2 , 则为连续值 :param X: 当前所有特征的数据 pd.DaraFrame格式 :param y: 标签值 :return: 以信息增益率来选择的最佳划分属性,第一个返回值为属性名称,第二个为最佳划分属性对应的信息...
    import numpy as np
    import pandas as pd
    from sklearn.utils.multiclass import type_of_target
    from decision_tree import treePlottter
    
    
    class Node(object):
        def __init__(self):
            self.feature_name = None  # 特性的名称
            self.feature_index = None  # 特性的下标
            self.subtree = {}  # 树节点的集合
            self.impurity = None  # 信息此节点的信息增益
            self.is_continuous = False  # 是否为连续值
            self.split_value = None  # 连续值时的划分依据
            self.is_leaf = False  # 是否为叶子节点
            self.leaf_class = None  # 叶子节点对应的类
            self.leaf_num = 0  # 叶子数目
            self.high = -1  # 树的高度
    
    
    def entroy(y):
        p = pd.value_counts(y) / y.shape[0]  # 计算各类样本所占比率
        ent = np.sum(-p * np.log2(p))
        return ent
    
        return node
    
    def gini(y):
            p = pd.value_counts(y) / y.shape[0]
            gini = 1 - np.sum(p ** 2)
            return gini
    def gini_index(feature, y, is_continuous=False):
            '''
            计算基尼指数, 对于连续值,选择基尼系统最小的点,作为分割点
            -------
            :param feature:
            :param y:
            :return:
            '''
            m = y.shape[0]
            unique_value = pd.unique(feature)
            if is_continuous:
                unique_value.sort()  # 排序, 用于建立分割点
                # 这里其实也可以直接用feature值作为分割点,但这样会出现空集, 所以还是按照书中4.7式建立分割点。好处是不会出现空集
                split_point_set = [(unique_value[i] + unique_value[i + 1]) / 2 for i in range(len(unique_value) - 1)]
    
                min_gini = float('inf')
                min_gini_point = None
                for split_point_ in split_point_set:  # 遍历所有的分割点,寻找基尼指数最小的分割点
                    Dv1 = y[feature <= split_point_]
                    Dv2 = y[feature > split_point_]
                    gini_index = Dv1.shape[0] / m * gini(Dv1) + Dv2.shape[0] / m * gini(Dv2)
    
                    if gini_index < min_gini:
                        min_gini = gini_index
                        min_gini_point = split_point_
                return [min_gini, min_gini_point]
            else:
                gini_index = 0
                for value in unique_value:
                    Dv = y[feature == value]
                    m_dv = Dv.shape[0]
                    gini_ = gini(Dv)  # 原书4.5式
                    gini_index += m_dv / m * gini_  # 4.6式
    
                return [gini_index]
    def info_gain(feature, y, entD, is_continuous=False):
        '''
        计算信息增益
        ------
        :param feature: 当前特征下所有样本值
        :param y:       对应标签值
        :return:        当前特征的信息增益, list类型,若当前特征为离散值则只有一个元素为信息增益,若为连续值,则第一个元素为信息增益,第二个元素为切分点
        '''
        m = y.shape[0]
        unique_value = pd.unique(feature)
        if is_continuous:
            unique_value.sort()  # 排序, 用于建立分割点
            split_point_set = [(unique_value[i] + unique_value[i + 1]) / 2 for i in range(len(unique_value) - 1)]
            min_ent = float('inf')  # 挑选信息熵最小的分割点
            min_ent_point = None
            for split_point_ in split_point_set:
    
                Dv1 = y[feature <= split_point_]
                Dv2 = y[feature > split_point_]
                feature_ent_ = Dv1.shape[0] / m * entroy(Dv1) + Dv2.shape[0] / m * entroy(Dv2)
    
                if feature_ent_ < min_ent:
                    min_ent = feature_ent_
                    min_ent_point = split_point_
            gain = entD - min_ent
    
            return [gain, min_ent_point]
    
        else:
            feature_ent = 0
            for value in unique_value:
                Dv = y[feature == value]  # 当前特征中取值为 value 的样本,即书中的 D^{v}
                feature_ent += Dv.shape[0] / m * entroy(Dv)
    
            gain = entD - feature_ent  # 原书中4.2式
            return [gain]
    
    def info_gainRatio(feature, y, entD, is_continuous=False):
            '''
            计算信息增益率 参数和info_gain方法中参数一致
            ------
            :param feature:
            :param y:
            :param entD:
            :return:
            '''
    
            if is_continuous:
                # 对于连续值,以最大化信息增益选择划分点之后,计算信息增益率,注意,在选择划分点之后,需要对信息增益进行修正,要减去log_2(N-1)/|D|,N是当前特征的取值个数,D是总数据量。
                # 修正原因是因为:当离散属性和连续属性并存时,C4.5算法倾向于选择连续特征做最佳树分裂点
                # 信息增益修正中,N的值,网上有些资料认为是“可能分裂点的个数”,也有的是“当前特征的取值个数”,这里采用“当前特征的取值个数”。
                # 这样 (N-1)的值,就是去重后的“分裂点的个数” , 即在info_gain函数中,split_point_set的长度,个人感觉这样更加合理。有时间再看看原论文吧。
    
                gain, split_point = info_gain(feature, y, entD, is_continuous)
                p1 = np.sum(feature <= split_point) / feature.shape[0]  # 小于或划分点的样本占比
                p2 = 1 - p1  # 大于划分点样本占比
                IV = -(p1 * np.log2(p1) + p2 * np.log2(p2))
    
                grain_ratio = (gain - np.log2(feature.nunique()) / len(y)) / IV  # 对信息增益修正
                return [grain_ratio, split_point]
            else:
                p = pd.value_counts(feature) / feature.shape[0]  # 当前特征下 各取值样本所占比率
                IV = np.sum(-p * np.log2(p))  # 原书4.4式
                grain_ratio = info_gain(feature, y, entD, is_continuous)[0] / IV
                return [grain_ratio]
    
    
    
    def choose_best_feature_gini( X, y):
            features = X.columns
            best_feature_name = None
            best_gini = [float('inf')]
            for feature_name in features:
                is_continuous = type_of_target(X[feature_name]) == 'continuous'
                gini_idex = gini_index(X[feature_name], y, is_continuous)
                if gini_idex[0] < best_gini[0]:
                    best_feature_name = feature_name
                    best_gini = gini_idex
    
            return best_feature_name, best_gini
    
    
    def choose_best_feature_gainratio( X, y):
            '''
            以返回值中best_gain_ratio 的长度来判断当前特征是否为连续值,若长度为 1 则为离散值,若长度为 2 , 则为连续值
            :param X: 当前所有特征的数据 pd.DaraFrame格式
            :param y: 标签值
            :return:  以信息增益率来选择的最佳划分属性,第一个返回值为属性名称,第二个为最佳划分属性对应的信息增益率
            '''
            features = X.columns
            best_feature_name = None
    
            best_gain_ratio = [float('-inf')]
            entD = entroy(y)
    
            for feature_name in features:
                is_continuous = type_of_target(X[feature_name]) == 'continuous'
                info_gain_ratio = info_gainRatio(X[feature_name], y, entD, is_continuous)
                if info_gain_ratio[0] > best_gain_ratio[0]:
                    best_feature_name = feature_name
                    best_gain_ratio = info_gain_ratio
    
            return best_feature_name, best_gain_ratio
    def choose_best_feature_infogain(X, y):
        '''
        以返回值中best_info_gain 的长度来判断当前特征是否为连续值,若长度为 1 则为离散值,若长度为 2 , 则为连续值
        :param X: 当前所有特征的数据 pd.DaraFrame格式
        :param y: 标签值
        :return:  以信息增益来选择的最佳划分属性,第一个返回值为属性名称,
    
        '''
        features = X.columns
        best_feature_name = None
        best_info_gain = [float('-inf')]
        entD = entroy(y)
        for feature_name in features:
            is_continuous = type_of_target(X[feature_name]) == 'continuous'
            infogain = info_gain(X[feature_name], y, entD, is_continuous)
            if infogain[0] > best_info_gain[0]:
                best_feature_name = feature_name
                best_info_gain = infogain
    
        return best_feature_name, best_info_gain
    
    
    def generate(X, y, columns,criterion):
        node = Node()
        # Pandas.Series.nunique()统计不同值的个数
        if y.nunique() == 1:  # 属于同一类别
            node.is_leaf = True
            node.leaf_class = y.values[0]
            node.high = 0
            node.leaf_num += 1
            return node
    
        if X.empty:  # 特征用完了,数据为空,返回样本数最多的类
            node.is_leaf = True
            node.leaf_class = pd.value_counts(y).index[0]  # 返回样本数最多的类
            node.high = 0
            node.leaf_num += 1
            return node
    
        if criterion == 'gini':
            best_feature_name, best_impurity=choose_best_feature_gini(X, y)
        elif criterion == 'infogain':
            best_feature_name, best_impurity=choose_best_feature_infogain(X, y)
        elif criterion == 'gainratio':
            best_feature_name, best_impurity=choose_best_feature_gainratio(X, y)
        # best_feature_name, best_impurity = choose_best_feature_infogain(X, y)
    
        node.feature_name = best_feature_name
        node.impurity = best_impurity[0]
        node.feature_index = columns.index(best_feature_name)
    
        feature_values = X.loc[:, best_feature_name]
    
        if len(best_impurity) == 1:  # 离散值
            node.is_continuous = False
    
            unique_vals = pd.unique(feature_values)
            sub_X = X.drop(best_feature_name, axis=1)
    
            max_high = -1
            for value in unique_vals:
                node.subtree[value] = generate(sub_X[feature_values == value], y[feature_values == value], columns,criterion)
                if node.subtree[value].high > max_high:  # 记录子树下最高的高度
                    max_high = node.subtree[value].high
                node.leaf_num += node.subtree[value].leaf_num
    
            node.high = max_high + 1
    
        elif len(best_impurity) == 2:  # 连续值
            node.is_continuous = True
            node.split_value = best_impurity[1]
            up_part = '>= {:.3f}'.format(node.split_value)
            down_part = '< {:.3f}'.format(node.split_value)
    
            node.subtree[up_part] = generate(X[feature_values >= node.split_value],
                                             y[feature_values >= node.split_value], columns,criterion)
            node.subtree[down_part] = generate(X[feature_values < node.split_value],
                                               y[feature_values < node.split_value], columns,criterion)
    
            node.leaf_num += (node.subtree[up_part].leaf_num + node.subtree[down_part].leaf_num)
    
            node.high = max(node.subtree[up_part].high, node.subtree[down_part].high) + 1
    
        return node
    
    
    if __name__ == "__main__":
        data = pd.read_csv("西瓜3.0.txt", index_col=0)  # index_col参数设置第一列作为index
        # 不带第一列,求得西瓜的属性
        x = data.iloc[:, :8]  # <class 'pandas.core.frame.DataFrame'>
        y = data.iloc[:, 8]  # <class 'pandas.core.series.Series'>
        columns_name = list(x.columns)  # 包括原数据的列名
        criterion = "gini" #'gainratio''infogain': 'gini':
        node = generate(x, y, columns_name,criterion)
        treePlottter.create_plot(node)
    

    画图的函数

    from matplotlib import pyplot as plt
    plt.rcParams['font.sans-serif'] = ['SimHei']
    decision_node = dict(boxstyle='round,pad=0.3', fc='#FAEBD7')
    leaf_node = dict(boxstyle='round,pad=0.3', fc='#F4A460')
    arrow_args = dict(arrowstyle="<-")
    
    y_off = None
    x_off = None
    total_num_leaf = None
    total_high = None
    
    
    def plot_node(node_text, center_pt, parent_pt, node_type, ax_):
        ax_.annotate(node_text, xy=[parent_pt[0], parent_pt[1] - 0.02], xycoords='axes fraction',
                     xytext=center_pt, textcoords='axes fraction',
                     va="center", ha="center", size=15,
                     bbox=node_type, arrowprops=arrow_args)
    
    
    def plot_mid_text(mid_text, center_pt, parent_pt, ax_):
        x_mid = (parent_pt[0] - center_pt[0]) / 2 + center_pt[0]
        y_mid = (parent_pt[1] - center_pt[1]) / 2 + center_pt[1]
        ax_.text(x_mid, y_mid, mid_text, fontdict=dict(size=10))
    
    
    def plot_tree(my_tree, parent_pt, node_text, ax_):
        global y_off
        global x_off
        global total_num_leaf
        global total_high
    
        num_of_leaf = my_tree.leaf_num
        center_pt = (x_off + (1 + num_of_leaf) / (2 * total_num_leaf), y_off)
    
        plot_mid_text(node_text, center_pt, parent_pt, ax_)
    
        if total_high == 0:  # total_high为零时,表示就直接为一个叶节点。因为西瓜数据集的原因,在预剪枝的时候,有时候会遇到这种情况。
            plot_node(my_tree.leaf_class, center_pt, parent_pt, leaf_node, ax_)
            return
        plot_node(my_tree.feature_name, center_pt, parent_pt, decision_node, ax_)
    
        y_off -= 1 / total_high
        for key in my_tree.subtree.keys():
            if my_tree.subtree[key].is_leaf:
                x_off += 1 / total_num_leaf
                plot_node(str(my_tree.subtree[key].leaf_class), (x_off, y_off), center_pt, leaf_node, ax_)
                plot_mid_text(str(key), (x_off, y_off), center_pt, ax_)
            else:
                plot_tree(my_tree.subtree[key], center_pt, str(key), ax_)
        y_off += 1 / total_high
    
    
    def create_plot(tree_):
        global y_off
        global x_off
        global total_num_leaf
        global total_high
    
        total_num_leaf = tree_.leaf_num
        total_high = tree_.high
        y_off = 1
        x_off = -0.5 / total_num_leaf
    
        fig_, ax_ = plt.subplots()
        ax_.set_xticks([])  # 隐藏坐标轴刻度
        ax_.set_yticks([])
        ax_.spines['right'].set_color('none')  # 设置隐藏坐标轴
        ax_.spines['top'].set_color('none')
        ax_.spines['bottom'].set_color('none')
        ax_.spines['left'].set_color('none')
        plot_tree(tree_, (0.5, 1), '', ax_)
    
        plt.show()
    

    展开全文
  • 一、问题描述:使用西瓜数据集构建决策树,并将构建的决策树进行可视化操作。 二、问题简析:首先我们简单的介绍一下什么是决策树。决策树是广泛用于分类和回归任务的模型。本质上,它从一层层的if/else问题中进行...

    最近在搞一些关于机器学习的小东西,其中有一部分就是关于决策树的。过程中遇到了一些小问题,现记录并与大家分享。

    一、问题描述:使用西瓜数据集构建决策树,并将构建的决策树进行可视化操作。

    二、问题简析:首先我们简单的介绍一下什么是决策树。决策树是广泛用于分类和回归任务的模型。本质上,它从一层层的if/else问题中进行学习,并得出结论。然后不妨看看下面这个小思考题吧:(故事我瞎编的,看问题就好了嘛)

    小鹿机缘巧合之下喜欢上了一个只有一面之缘的贝贝(一见钟情嘛)。对吧,爱情的力量是伟大的,小鹿就不顾一切的裸辞叻,去找人家。这不总算找到了人家里,但是考验接踵而至呀!人贝贝对小鹿还挺满意的哦,可姑娘的父母说还得考验一下不是?啥考验呢?

    思辨:家里有两个卧室,老丈人,丈母娘各站一个卧室门外,贝贝就在其中一个卧室中。老丈人向来只说真话,丈母娘向来只说假话。现在只允许小鹿向两人中任意一个人提一个问题,只有成功问出贝贝在哪间卧室之中才能抱得美人归。小鹿该怎么提问?(答案在文章末尾)

    为什么会来一个看似无关的废话连篇叻?其实问题有相通之处的,我们的目标是通过提出尽可能少的if/else问题来得到正确答案。

    三、代码实现
    为了控制文章篇幅,现在就直接给出问题的代码实现吧:

    from random import choice
    from collections import Counter
    import math
    
    # 定义数据集
    D = [
        {'色泽': '青绿', '根蒂': '蜷缩', '敲声': '浊响', '纹理': '清晰', '脐部': '凹陷', '触感': '硬滑', '好瓜': '是'},
        {'色泽': '乌黑', '根蒂': '蜷缩', '敲声': '沉闷', '纹理': '清晰', '脐部': '凹陷', '触感': '硬滑', '好瓜': '是'},
        {'色泽': '乌黑', '根蒂': '蜷缩', '敲声': '浊响', '纹理': '清晰', '脐部': '凹陷', '触感': '硬滑', '好瓜': '是'},
        {'色泽': '青绿', '根蒂': '蜷缩', '敲声': '沉闷', '纹理': '清晰', '脐部': '凹陷', '触感': '硬滑', '好瓜': '是'},
        {'色泽': '浅白', '根蒂': '蜷缩', '敲声': '浊响', '纹理': '清晰', '脐部': '凹陷', '触感': '硬滑', '好瓜': '是'},
        {'色泽': '青绿', '根蒂': '稍蜷', '敲声': '浊响', '纹理': '清晰', '脐部': '稍凹', '触感': '软粘', '好瓜': '是'},
        {'色泽': '乌黑', '根蒂': '稍蜷', '敲声': '浊响', '纹理': '稍糊', '脐部': '稍凹', '触感': '软粘', '好瓜': '是'},
        {'色泽': '乌黑', '根蒂': '稍蜷', '敲声': '浊响', '纹理': '清晰', '脐部': '稍凹', '触感': '硬滑', '好瓜': '是'},
        {'色泽': '乌黑', '根蒂': '稍蜷', '敲声': '沉闷', '纹理': '稍糊', '脐部': '稍凹', '触感': '硬滑', '好瓜': '否'},
        {'色泽': '青绿', '根蒂': '硬挺', '敲声': '清脆', '纹理': '清晰', '脐部': '平坦', '触感': '软粘', '好瓜': '否'},
        {'色泽': '浅白', '根蒂': '硬挺', '敲声': '清脆', '纹理': '模糊', '脐部': '平坦', '触感': '硬滑', '好瓜': '否'},
        {'色泽': '浅白', '根蒂': '蜷缩', '敲声': '浊响', '纹理': '模糊', '脐部': '平坦', '触感': '软粘', '好瓜': '否'},
        {'色泽': '青绿', '根蒂': '稍蜷', '敲声': '浊响', '纹理': '稍糊', '脐部': '凹陷', '触感': '硬滑', '好瓜': '否'},
        {'色泽': '浅白', '根蒂': '稍蜷', '敲声': '沉闷', '纹理': '稍糊', '脐部': '凹陷', '触感': '硬滑', '好瓜': '否'},
        {'色泽': '乌黑', '根蒂': '稍蜷', '敲声': '浊响', '纹理': '清晰', '脐部': '稍凹', '触感': '软粘', '好瓜': '否'},
        {'色泽': '浅白', '根蒂': '蜷缩', '敲声': '浊响', '纹理': '模糊', '脐部': '平坦', '触感': '硬滑', '好瓜': '否'},
        {'色泽': '青绿', '根蒂': '蜷缩', '敲声': '沉闷', '纹理': '稍糊', '脐部': '稍凹', '触感': '硬滑', '好瓜': '否'},
    ]
    
    
    # ==========
    # 决策树生成类
    # ==========
    class DecisionTree:
        def __init__(self, D, label, chooseA):
            self.D = D  # 数据集
            self.label = label  # 哪个属性作为标签
            self.chooseA = chooseA  # 划分方法
            self.A = list(filter(lambda key: key != label, D[0].keys()))  # 属性集合A
            # 获得A的每个属性的可选项
            self.A_item = {}
            for a in self.A:
                self.A_item.update({a: set(self.getClassValues(D, a))})
            self.root = self.generate(self.D, self.A)  # 生成树并保存根节点
    
        # 获得D中所有className属性的值
        def getClassValues(self, D, className):
            return list(map(lambda sample: sample[className], D))
    
        # D中样本是否在A的每个属性上相同
        def isSameInA(self, D, A):
            for a in A:
                types = set(self.getClassValues(D, a))
                if len(types) > 1:
                    return False
            return True
    
        # 构建决策树,递归生成节点
        def generate(self, D, A):
            node = {}  # 生成节点
            remainLabelValues = self.getClassValues(D, self.label)  # D中的所有标签
            remainLabelTypes = set(remainLabelValues)  # D中含有哪几种标签
    
            if len(remainLabelTypes) == 1:
                # 当前节点包含的样本全属于同个类别,无需划分
                return remainLabelTypes.pop()  # 标记Node为叶子结点,值为仅存的标签
    
            most = max(remainLabelTypes, key=remainLabelValues.count)  # D占比最多的标签
    
            if len(A) == 0 or self.isSameInA(D, A):
                # 当前属性集为空,或是所有样本在所有属性上取值相同,无法划分
                return most  # 标记Node为叶子结点,值为占比最多的标签
    
            a = self.chooseA(D,A,self)  # 划分选择
    
            for type in self.A_item[a]:
                condition = (lambda sample: sample[a] == type)  # 决策条件
                remainD = list(filter(condition, D))  # 剩下的样本
                if len(remainD) == 0:
                    # 当前节点包含的样本集为空,不能划分
                    node.update({type: most})  # 标记Node为叶子结点,值为占比最多的标签
                else:
                    # 继续对剩下的样本按其余属性划分
                    remainA = list(filter(lambda x: x != a, A))  # 未使用的属性
                    _node = self.generate(remainD, remainA)  # 递归生成子代节点
                    node.update({type: _node})  # 把生成的子代节点更新到当前节点
            return {a: node}
    
    
    
    #  定义划分方法
    
    # 随机选择
    def random_choice(D, A, tree: DecisionTree):
        return choice(A)
    
    # 信息熵
    def Ent(D,label,a,a_v):
        D_v = filter(lambda sample:sample[a]==a_v,D)
        D_v = map(lambda sample:sample[label],D_v)
        D_v = list(D_v)
        D_v_length = len(D_v)
        counter = Counter(D_v)
        info_entropy = 0
        for k, v in counter.items():
            p_k = v / D_v_length
            info_entropy += p_k * math.log(p_k, 2)
        return -info_entropy
    
    # 信息增益
    def information_gain(D, A, tree: DecisionTree):
        gain = {}
        for a in A:
            gain[a] = 0
            values = tree.getClassValues(D, a)
            counter = Counter(values)
            for a_v,nums in counter.items():
                gain[a] -= (nums / len(D)) * Ent(D,tree.label,a,a_v)
        return max(gain.keys(),key=lambda key:gain[key])
        
    #  创建决策树
    desicionTreeRoot = DecisionTree(D, label='好瓜',chooseA=information_gain).root
    print('决策树:', desicionTreeRoot)
    
    # 决策树可视化类
    class TreeViewer:
        def __init__(self):
            from graphviz import Digraph
            self.id_iter = map(str, range(0xffff))
            self.g = Digraph('G', filename='decisionTree.gv')
    
        def create_node(self, label, shape=None):
            id = next(self.id_iter)
            self.g.node(name=id, label=label, shape=shape, fontname="Microsoft YaHei")
            return id
    
        def build(self, key, node, from_id):
            for k in node.keys():
                v = node[k]
                if type(v) is dict:
                    first_attr = list(v.keys())[0]
                    id = self.create_node(first_attr+"?", shape='box')
                    self.g.edge(from_id, id, k, fontsize = '12', fontname="Microsoft YaHei")
                    self.build(first_attr, v[first_attr], id)
                else:
                    id = self.create_node(v)
                    self.g.edge(from_id, id, k, fontsize = '12', fontname="Microsoft YaHei")
    
        def show(self, root):
            first_attr = list(root.keys())[0]
            id = self.create_node(first_attr+"?", shape='box')
            self.build(first_attr, root[first_attr], id)
            self.g.view()
    
    
    # 显示创建的决策树
    viewer = TreeViewer()
    viewer.show(desicionTreeRoot)
    

    四、可能出现的错误
    实验中有一些库是必须要使用到的,总体上不会有太大的问题,但是我们需要特别注意一下graphviz库。一般情况下,使用AnaConda开发的话,我们会在AnaConda Prompt中直接使用pip install graphviz命令来安装包。这样使用之后,Jupyter Notebook中显示导包成功,但是有一堆报错,也无法让决策树成功可视化。上述问题的一般报错为graphviz.backend.ExecutableNotFound: failed to execute [‘dot’, ‘-Tpdf’, ‘-O’, ‘test-table.gv’], make sure the Graphviz executables are on your systems’ PATH为了解决这个问题在网上寻找了很多种方法,也基本上都尝试了一下。现在就直接给大家一个比较简便的解决方法!

    解决方法:去graphviz官网上下载graphviz-2.38.msi官网下载路径,或者直接点这个链接去下载graphviz绿色简便下载

    推荐使用绿色简便下载,当然要是不怕麻烦的话也可以选择去官网下载哈。下载解压完成之后还需要对graphivz进行配置,将graphviz文件夹的bin目录完整路径添加在系统变量Path中。最后重启Jupyter Notebook,便可以运行成功。

    五、样例运行结果
    运行结果截图

    今天要分享的到这儿就快结束了,希望我们能在学习的道路上携手共进。自己不会的有太多,希望各位大佬能给予指点,也希望小鹿的文章对小伙伴们是有帮助的,喜欢的可以点点关注和👍

    思辨部分的参考问法(以问老丈人为例): “老丈人,你说我要是问丈母娘贝贝在哪间卧室,她会告诉我什么答案?”

    这样问答案就出来了已经:因为老丈人只说真话,所以他告诉你的必然是丈母娘说的假话,故而正确的答案就是老丈人没有说的那一间卧室。向丈母娘提问也是一样的道理,解决问题的方法有很多,欢迎大家讨论发表意见。

    展开全文
  • 这个数据集合是配合【决策树】中案例代码的使用 文章地址在:https://blog.csdn.net/qq_37344125/article/details/103327909
  • 系统Ubuntu对话数据集下载地址 ubuntu对话系统数据集 Ubuntu对话数据集,可以用于多轮对话训练语料库,内附Ubuntu对话数据集的下载地址。智能聊天,chatbot,训练对话的语料库
  • 决策树对西瓜数据集2.0二分类

    千次阅读 2020-12-16 21:34:10
    西瓜数据集.jpg@生成分类字典# -*- coding: UTF-8 -*-#设置默认编码,否则中文会乱码import sysreload(sys)sys.setdefaultencoding('utf-8')from math import log#1、获取样例集和属性列表def filetodataset...
  • 西瓜3.0决策树.zip

    2021-06-19 08:52:22
    使用Python实现用于判断西瓜好坏的决策树程序。 程序详解:https://blog.csdn.net/weixin_40973138/article/details/117999991?spm=1001.2014.3001.5501
  • 西瓜数据集介绍以及获取。

    万次阅读 多人点赞 2018-03-14 21:35:35
    西瓜数据集介绍。 这里介绍一下《机器学习》中的西瓜数据。数据集也不少,放在别的文章中介绍就会略占篇幅,还是单独的介绍一下并且给出数据样本。 在西瓜书中,主要使用到的数据样本共有2.0、3.0、4.0这三个版本...
  • 西瓜3.0excel版的数据

    2018-08-27 16:24:31
    数据是基于周志华的《机器学习》中数据自己制作的数据
  • weka软件最全数据集

    2019-04-12 17:10:48
    weka软件最全数据集,共189个,用于weka软件的数据集训练和测试,包含天气 车辆 肝脏肿瘤等等数据集,格式为arff
  • 《机器学习(周志华)》 西瓜数据集3.0

    万次阅读 多人点赞 2016-03-24 14:23:40
    书上的一个常用数据集 编号,色泽,根蒂,敲声,纹理,脐部,触感,密度,含糖率,好瓜 1,青绿,蜷缩,浊响,清晰,凹陷,硬滑,0.697,0.46,是 2,乌黑,蜷缩,沉闷,清晰,凹陷,硬滑,0.774,0.376,是 3,乌黑,蜷缩,浊响,清晰,凹陷,硬滑,0...
  • 文章目录1 什么是逻辑回归1.1 Sigmoid函数介绍2 逻辑回归公式推导2.1 损失函数推导3 逻辑回归迭代公式3.1 函数特性3.2 求导过程4 逻辑回归实现西瓜数据集2.0的分类 我们在实现西瓜数据集2.0分类之前先讲讲逻辑回归...
  • 1.贝叶斯原理朴素贝叶斯分类(Naive Bayesian,NB)源于贝叶斯理论,是一类基于概率的分类器,其基本思想:假设样本属性之间相互独立,对于给定的待分类项,求解在此项...这一阶段的输入是所有待分类数据,输出是特...
  • 第一部分:数据集 X表示二维矩阵数据,表示西瓜密度和含糖率 总共30行,每行两列数据 第一列表示西瓜密度:x1 第二列表示西瓜含糖率:x2 from sklearn.cluster import Birch # 从sklearn.cluster机器学习聚类包中...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,629
精华内容 2,651
关键字:

西瓜数据集下载

友情链接: 1-1Z415154025.zip