开启生长之旅!这是我参加「日新计划 12 月更文挑战」的第29天,点击查看活动详情

视频作者:菜菜TsaiTsai 链接:【技能干货】菜菜的机器学习sklearn【全85集】Python进阶_哔哩哔哩_bilibili

决议计划树的优缺陷

决议计划树长处

  1. 易于理解和解说,由于树木能够画出来被看见
  2. 需求很少的数据预备。其他许多算法通常都需求数据规范化,需求创立虚拟变量并删除空值等。但请留意, sklearn中的决议计划树模块不支撑对缺失值的处理。
  3. 运用树的本钱(比如说,在猜测数据的时分)是用于练习树的数据点的数量的对数,比较于其他算法,这是一个很低的本钱。

个人理解,关于一个树模型,假设有n级,那么咱们树木的结点数目最大为2n−12^{n-1},关于一个新的样本,咱们要猜测其标签,咱们就需求判别n−1n-1n−1=log⁡2n−1n-1=\log 2^{n-1} 这便是为什么说运用树的本钱是用于练习树的数据点的数量的对数

  1. 能够同时处理数字和分类数据,既能够做回归又能够做分类。其他技能通常专门用于剖析仅具有一种变量类型的数据集。

类DecisionTreeClassifier和DecisionTreeRegressor 分类树是依据叶结点处所含样本的标签的大都类来决议该叶结点的标签 回归树能够认为是依据叶结点处所含样本的均值来决议该叶结点的标签

  1. 能够处理多输出问题,即含有多个标签的问题,留意与一个标签中含有多种标签分类的问题区别开

个人理解,多个标签指输入的Y为多列,即多标签问题;一个标签中含有多种标签值输入的Y为一列,可是这一列的取值有多种,即单标签多分类问题,对应的是二分类问题

  1. 是一个白盒模型,成果很简单能够被解说。假如在模型中能够观察到给定的情况,则能够经过布尔逻辑轻松解说条件。相反,在黑盒模型中(例如,在人工神经网络中),成果或许更难以解说。
  2. 能够运用统计测验验证模型,这让咱们能够考虑模型的可靠性。
  3. 即使其假设在某种程度上违反了生成数据的真实模型,也能够体现良好。

决议计划树的缺陷

  1. 决议计划树学习者或许创立过于杂乱的树,这些树不能很好地推行数据。这称为过度拟合。修剪,设置叶节点所需的最小样本数或设置树的最大深度等机制是防止此问题所必需的,而这些参数的整合和调整对初学者来说会比较晦涩
  2. 决议计划树或许不稳定,数据中细小的变化或许导致生成彻底不同的树,这个问题需求经过集成算法来处理。
  3. 决议计划树的学习是基于贪婪算法,它靠优化部分最优(每个节点的最优)来企图达到全体的最优,但这种做法不能保证回来大局最优决议计划树。这个问题也能够由集成算法来处理,在随机森林中,特征和样本会在分枝进程中被随机采样。

2、3都被集成算法很好的处理,也便是后边要讲的随机森林算法

  1. 有些概念很难学习,由于决议计划树不简单表达它们,例如XOR,奇偶校验或多路复用器问题。
  2. 假如标签中的某些类占主导地位,决议计划树学习者会创立偏向主导类的树。因而,主张在拟合决议计划树之前平衡数据集。

能够考虑上采样(?)或许调整class_weight

分类树在合成数集上的体现

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import make_moons,make_circles,make_classification
from sklearn.tree import DecisionTreeClassifier
X, y = make_classification(n_samples=100
                          ,n_features=2
                          ,n_redundant=0
                          ,n_informative=2
                          ,random_state=1
                          ,n_clusters_per_class=1)
plt.scatter(X[:,0],X[:,1])

详解决策树-决策树的优缺点 & 分类树在合成数集上的表现【菜菜的sklearn课堂笔记】

关于make_classification

X, y = make_classification(n_samples=300
                          ,n_features=2
                          ,n_redundant=0
                          ,n_informative=2
                          ,random_state=1
                          ,n_clusters_per_class=2)
plt.scatter(X[:,0],X[:,1],c=y)
# n_clusters_per_class每个类的集群数
# n_features:int,默许20,特征总数。这些包含n_informative 信息特征、n_redundant冗余特征、 n_repeated重复特征和 n_features-n_informative-n_redundant-n_repeated随机抽取的无用特征。
# n_informative:int,默许2,信息特征的数量。
# n_redundant:int,默许2,冗余特征的数量。这些特征是作为信息特征的随机线性组合生成的。(假设n_informative=F1,F2,…那么n_redundant= aF1+bF2+… a,b,c便是随机数)
# n_repeated:int,默许0,从信息特征和冗余特征中随机抽取的重复特征的数量。
# n_classes:int,默许2,分类问题的类(或标签)数。
# 关于冗余特征如同有个叫mRMR算法的,不太了解

详解决策树-决策树的优缺点 & 分类树在合成数集上的表现【菜菜的sklearn课堂笔记】

链接:make_classification函数_BlackStar_L的博客-CSDN博客_make_classification

从图上能够看出,生成的二分型数据的两个簇离互相很远,这样不利于咱们测验分类器的作用,因而咱们生成随机数组,经过让现已生成的二分型数据点加减0~1之间的随机数,使数据分布变得更散更稀少

留意,这个进程只能够运转一次,由于多次运转之后X会变得十分稀少,两个簇的数据会混合在一起,分类器的效应会继续下降

rng = np.random.RandomState(2)
X += 2 * rng.uniform(size=X.shape)
# 加0~2之间的随机数
# uniform(low,high,size),从一个均匀分布[low,high)中随机采样
# 默许low=0,high=1
linearly_separable = (X,y)
plt.scatter(X[:,0],X[:,1])

详解决策树-决策树的优缺点 & 分类树在合成数集上的表现【菜菜的sklearn课堂笔记】

datasets = [make_moons(noise=0.3,random_state=0)
           ,make_circles(noise=0.2,factor=0.5,random_state=1)
           ,linearly_separable]

画出三种数据集和三棵决议计划树的分类效应图像

figure = plt.figure(figsize=(6,9))
# figsize中的元组第一个6对应列宽,第二个9对应行高
i = 1
# 设置用来组织图像显现方位的大局变量i
for ds_index, ds in enumerate(datasets):
    X,y = ds
    # 对X中的数据进行标准化处理,然后分练习集和测验集
    # 决议计划树不进行数据标准化应该也没什么问题,而且数据标准化后会让取值更难解说
    X = StandardScaler().fit_transform(X)
    X_train,X_test,Y_train,Y_test = train_test_split(X,y,test_size=0.4,random_state=42)
    X1_min, X1_max = X[:,0].min() - 0.5, X[:,0].max() + 0.5
    X2_min, X2_max = X[:,1].min() - 0.5, X[:,1].max() + 0.5
    array1,array2 = np.meshgrid(np.arange(X1_min,X1_max,0.2)
                               ,np.arange(X2_min,X2_max,0.2))
    # array1能够看做一行横坐标纵向仿制铺满一个矩阵,从负到正
    # array2能够看做一列纵坐标横向仿制铺满一个矩阵,从负到正
    # 用ListedColormap为画布创立颜色,#FF0000正红,#0000FF正蓝
    cm = plt.cm.RdBu
    cm_bright = ListedColormap(['#FF0000','#0000FF'])
    ax = plt.subplot(len(datasets),2,i)
    # 在画布上加上一个子图,数据为len(datasets)行,2列,放在方位i上
    # i的取值关于整个画布,从左到右,从上到下,一行一行的向下添加
    # subplots和subplot。两者都能够完成画子图功能,只不过subplots帮咱们把画板规划好了,而且创立时能够直接指定画板的大小,回来画布目标和坐标数组目标。而subplot是在现已创立好的画布上添加子图,每次只能回来一个坐标目标。
    if ds_index == 0:
        ax.set_title("Input data")
    ax.scatter(X_train[:,0],X_train[:,1],c=Y_train,cmap=cm_bright,edgecolors='k')
    ax.scatter(X_test[:,0],X_test[:,1],c=Y_test,cmap=cm_bright,edgecolors='k',alpha=0.6)
    # 其实基本区分不出测验集的点hhhh
    # 为图设置坐标轴的最大值和最小值,并设定没有坐标轴
    ax.set_xlim(array1.min(),array1.max())
    ax.set_ylim(array2.min(),array2.max())
    ax.set_xticks(())
    ax.set_yticks(())
    # 每次循环之后,改动i的取值让图每次位列不同的方位
    i += 1
    ax = plt.subplot(len(datasets),2,i)
    # 在函数最开始,咱们界说了i=1,而且在上边树立数据集的图像的时分,现已让i+1,所以i在这儿每次循环中的取值为2,4,6
    clf = DecisionTreeClassifier(max_depth=5,random_state=1) # 也有随机性
    clf.fit(X_train,Y_train)
    score = clf.score(X_test,Y_test)
    Z = clf.predict_proba(np.c_[array1.ravel(),array2.ravel()])[:,1]
    # np.c_[array1.ravel(),array2.ravel()]回来的便是坐标点
    # np.c_是能够将两个数组组合起来的函数
    # 从左下,到右下,然后一行一行的从左向右往上走
    Z = Z.reshape(array1.shape)
    ax.contourf(array1,array2,Z,cmap=cm,alpha=0.8)
    # 将回来的类概率作为数据,放到contourf里面绘制去绘制概括
    # 这儿咱们指定levels是没有意义的,假如查看Z会发现,任何一个维度的所有数据只要两个取值,即0,1
    # 所以说假如咱们运用contour,由于无法指定level就没有意义了
    # 假如运用contour合作pcolormesh着色,可是要指定Z的范围,交界处仍然会有问题,所以考虑运用contourf
    # 比较于contour,contourf自身就会对不同区域进行着色
    # 实际上predict_proba回来的不只是0,1,依据界说它能够回来[0,1]
    # 只是由于这儿样本太少,导致生成的决议计划树每个叶结点上刚好只要一类样本,所以回来值只要0,1
    ax.scatter(X_train[:,0],X_train[:,1],c=Y_train,cmap=cm_bright,edgecolors='k')
    ax.scatter(X_test[:,0],X_test[:,1],c=Y_test,cmap=cm_bright,edgecolors='k',alpha=0.6)
    ax.set_xlim(array1.min(),array1.max())
    ax.set_ylim(array2.min(),array2.max())
    ax.set_xticks(())
    ax.set_yticks(())
    if ds_index == 0:
        ax.set_title("Decision Tree")
    # 写在右下角的数字
    ax.text(array1.max() - 0.3,array2.min() + 0.3
           ,("{:.1f}%").format(score*100)
           ,size=15
           ,horizontalalignment='right')
    # 让i继续加一
    i += 1
plt.tight_layout()
plt.show()

详解决策树-决策树的优缺点 & 分类树在合成数集上的表现【菜菜的sklearn课堂笔记】

很简单看得出,分类树天生不拿手环形数据。每个模型都有自己的决议计划上限,所以一个怎样调整都无法提升体现的或许性也是有的。当一个模型怎么调整都不可的时分,咱们能够挑选换其他的模型运用。

最拿手月亮型数据的是最近邻算法,RBF支撑向量机和高斯进程;最拿手环形数据的是最近邻算法和高斯进程;最拿手对半分的数据的是朴素贝叶斯,神经网络和随机森林。