python机器学习算法实训 - (四)实现决策树

1.什么是决策树

决策树是一种树型结构,其中每个内部结点表示在一个属性上的测试,每个分支代表一个测试输出,每个叶结点代表一种类别。
决策树学习是以实例为基础的归纳学习,通过一系列规则对数据进行分类的过程。
决策树学习采用的是自顶向下的递归方法,其基本思想是以信息熵为度量构造一棵熵值下降最快的树,到叶子节点处的熵值为零,此时每个叶节点中的实例都属于同一类。
简单来说,我们生活中随时会用到这样的判断方法,比如这样:
在这里插入图片描述

2.决策树的特点

决策树学习算法的最大优点是,它可以自学习
在学习的过程中,不需要使用者了解过多背景知识,只需要对训练实例进行较好的标注,就能够进行学习
属于有监督学习:从一类无序、无规则的事物(概念)中推理出决策树表
示的分类规则
包含特征选择、决策树的生成和决策树的剪枝

3.基本概念

要用上算法,先来看基本几个概念。

3.1 信息量

定义随机变量X的概率分布为p(x),则定义X信息量:
在这里插入图片描述
特性:
某事件发生的概率小,则该事件的信息量大。
如果两个事件X和Y独立,即p(xy)=p(x)p(y) ,假定X和Y的信息量分别为h(X)和h(Y),则二者同时发生的信息量应该为h(XY)=h(X)+h(Y)。

3.2 熵

对随机事件的信息量求期望,得熵的定义:
在这里插入图片描述
经典熵的定义,底数是2,单位是bit
本例中,为分析方便使用底数e,单位是nat(奈特)
熵只依赖于X的概率分布,与X的取值无关
熵越大,随机变量(样本)的不确定性就越大

3.3 条件熵

两个随机变量X,Y的联合分布,可以形成联合熵用H(X,Y)表示
H(X,Y) – H(X)
(X,Y)发生所包含的熵,减去X单独发生包含的熵:在X发生的前提下,Y发生“新”带来的熵,该式子定义为X发生前提下,Y的熵:
条件熵H(Y|X)表示在已知随机变量X的条件下随机变量Y的不确定性。
在这里插入图片描述

3.4 信息增益

特征选择的准则之一
信息增益表示得知特征A的信息而使得类X的信息的不确定性减少的程度 。
定义:特征A对训练数据集D的信息增益g(D,A),定义为集合D的经验熵H(D)与特征A给定条件下D的经验条件熵H(D|A)之差,即:
g(D,A)=H(D)–H(D|A) ,即为训练数据集D和特征A的互信息。
当熵和条件熵中的概率由数据估计(特别是极大似然估计)得到时,所对应的熵和条件熵分别称为经验熵和经验条件熵。
熵H(Y) 与条件熵 H(Y|X)之差成为互信息,决策树学习中的信息增益等价于训练数据集中类与特征的互信息。

3.5 决策树的生成算法

这是建立决策树的关键,即在当前状态下选择哪个属性作为分类依据。根据不同的目标函数,建立决策树经典算法主要有以下三种:

ID3:使用信息增益/互信息g(D,A)进行特征选择

信息增益是以某特征划分数据集前后的熵的差值。熵可以表示样本集合的不确定性,熵越大,样本的不确定性就越大。因此,可以用某特征划分数据集前后的熵的差值来衡量此特征对于样本集合D划分效果的好坏。
信息增益的缺点是偏向取值较多的特征。特征的值较多时,根据此特征划分更容易得到纯度更高的子集,故划分之后的熵更低,因为划分前的熵是一定的,所以信息增益更大,更偏向取值较多的特征
容易训练得到的是一棵庞大且深度浅的树:不合理。

C4.5:信息增益率

gr(D,A) = g(D,A) / H(A)

CART:分类与回归树(CART)

它即可以用于分类,也可以用于回归。回归生成树采用平方误差最小化策略,分类生成树采用基尼指数最小化策略。

4 基本流程

说了这么多,我们的决策树是怎么工作的呢。
在这里插入图片描述
在整个决策过程中,我们一直在对记录的特征进行提问。最初的问题所在的地方叫做根节点,在得到结论前的每一个问题都是中间节点,而得到的每一个结论(动物的类别)都叫做叶子节点。
这样一层一层的分下去,我们就会得到前面那样的类似于树状的结构。

5. 代码环节

首先我们自己现实一棵树

//定义类DecisionTreeClassifier的初始化函数init(),包括self.degree每个属性的取值。
class DecisionTreeClassifier(object):
    def __init__(self, criterion, degree=16):
        self.criterion = criterion
        self.order = []
        self.degree = degree
        self.de1 = np.zeros([self.degree, x_train.shape[1]])
        self.rate = np.zeros([self.degree, x_train.shape[1]])
        self.feature = []
        self.classes_num = np.zeros([self.degree, self.degree])
        self.max = np.zeros(x_train.shape[1])
        self.min = np.zeros(x_train.shape[1])
//定义信息熵,信息熵是度量样本集合纯度最常用的一种指标。
def info(self, y_train):
        Ent_D = 0
        for i in range(3):
            pk = np.sum(y_train == i) / y_train.shape[0]
            if pk > 0:
                Ent_D -= pk * math.log(pk, 2)
        return Ent_D
//计算信息增益,在鸢尾花的2个属性下,信息增益只需要计算一次,选择长度和宽度某一属性作为最优属性。Gain为每一个属性的信息增益值,按照从小到大的顺序排序得到gain_sort,self.feature为对应的最优属性从大到小的索引。
def best_feature(self, x_train, y_train):
        Ent_D = self.info(y_train)
        gain = []
        for k in range(x_train.shape[1]):
            gain_var = 0
            for i in range(self.degree):
                self.rate[i, k] = np.sum(x_train[:, k] == i)
                ent = self.info(y_train[x_train[:, k] == i])
                gain_var = gain_var + self.rate[i, k] / y_train.shape[0] * ent
            gain.append(Ent_D - gain_var)
        gain_sort = sorted(gain)
        for k in range(x_train.shape[1]):
            self.feature.append(np.where(gain == gain_sort[x_train.shape[1] - 1 - k])[0][0])
        return 0
//因为鸢尾花的四个属性取值是连续变量,将其离散化。此处设置鸢尾花的每个属性self.degree有8个或者16个离散值,因为鸢尾花一共有四种类别,所以必须大于4。属性的取值为0~self.degree。
def normal(self, x_train, flag=0):
        for k in range(x_train.shape[1]):
            if (flag == 0):
                x1_max = max(x_train[:, k]);
                x1_min = min(x_train[:, k]);
                for j in range(self.degree):
                    self.de1[j, k] = x1_min + (x1_max - x1_min) / self.degree * j
            else:
                x1_max = self.max[k]
                x1_min = self.min[k]
            var = x_train[:, k].copy()

            for j in range(self.degree):
                var[x_train[:, k] >= self.de1[j, k]] = j
            x_train[:, k] = var
            if (flag == 0):
                self.min[k] = x1_min
                self.max[k] = x1_max
        return x_train
//最大值求解。在决策树算法流程中叶节点被标记为对应样本子集中样本数最多的类别,argmax函数实现了这一功能。
def argmax(self, y_train):
        maxnum = 0
        for i in range(4):
            a = np.where(y_train == i)
            if (a[0].shape[0] > maxnum):
                maxnum = i
        return maxnum
//定义fit训练函数,实现决策树。首先数据离散化,并求解最优属性,计算每一个叶结点的类,下式中从根节点中得到2级属性样本集合a,从a中选择叶节点b,如果叶节点的样本为零,则从a中选择样本最多的类作为叶节点的类别。同样如果a样本为0,则从根节点选择类别。
def fit(self, x_train, y_train):
        x_train = self.normal(x_train, flag=0)
        self.best_feature(x_train, y_train)
        for i in range(self.degree):
            a = np.where(x_train[:, self.feature[0]] == i)
            print(a)
            for j in range(self.degree):
                var2 = []
                var2_y = []
                if (a != []):
                    b = []
                    for k in a[0]:
                        if (x_train[k, self.feature[1]] == j):
                            b.append(k)
                    if (b != []):
                        self.classes_num[i, j] = self.argmax(y_train[b])
                    else:
                        self.classes_num[i, j] = self.argmax(y_train[a[0]])
                else:
                    self.classes_num[i, j] = self.argmax(y_train)
        return (0)
//定义预测函数,同样对测试集离散化,需要注意离散化的最小值和最大值是从训练集得到的,而不能从测试集中选择。根据属性值选择对应的类别。
def predict(self, x_test):
        y_show_hat = np.zeros([x_test.shape[0]])
        x_test = self.normal(x_test, 1)
        for j in range(x_test.shape[0]):
            var = int(x_test[j, self.feature[0]])
            var2 = int(x_test[j, self.feature[1]])
            y_show_hat[j] = self.classes_num[var, var2]
        return y_show_hat
//添加如下所示代码,分别为鸢尾花数据集的特征和分类,包含4个特征和3种分类。x数组包含150个植物的数据,y为对应的分类标签,用0、1、2表示。
iris_feature_E = ['sepal length', 'sepal width', 'petal length', 'petal width']
iris_feature = ['elength', 'ewidth', 'blength', 'bwidth']
iris_class = 'Iris-setosa', 'Iris-versicolor', 'Iris-virginica'
//定义main函数,将数据集特征和标签按照7:3的比例分为训练数据集和测试数据集。数据集仅使用前两个特征训练和测试。
if __name__ == "__main__":
    mpl.rcParams['font.sans-serif'] = [u'simHei']
    mpl.rcParams['axes.unicode_minus'] = False
    data = load_iris()
    x = data.data
    print(x.shape)
    y = data.target
    print(y.shape)
    x = x[:, :2]
    x_train, x_test, y_train, y_test = train_test_split(x, y, train_size=0.7, test_size=0.3, random_state=1)
    model = DecisionTreeClassifier(criterion='entropy', degree=16)
    model.fit(x_train, y_train)
    y_test_hat = model.predict(x_test)
    y_test = y_test.reshape(-1)
    result = (y_test_hat == y_test)
    accuracy = np.mean(result)
    print( u'准确度: %.2f%%' % (100 * accuracy))   
//画图       
N, M = 50, 50
    x1_min, x2_min = [min(x[:, 0]), min(x[:, 1])]
    x1_max, x2_max = [max(x[:, 0]), max(x[:, 1])]

    t1 = np.linspace(x1_min, x1_max, N)
    t2 = np.linspace(x, x2_max, M)
    x1, x2 = np.meshgrid(t1, t2)
    x_show = np.stack((x1.flat, x2.flat), axis=1)
    cm_light = mpl.colors.ListedColormap(['#A0FFA0', '#FFA0A0', '#A0A0FF'])
    cm_dark = mpl.colors.ListedColormap(['g', 'r', 'b'])
    y_show_hat = model.predict(x_show)
    y_show_hat = y_show_hat.reshape(x1.shape)
    plt.figure(1, figsize=(10, 4), facecolor='w')
    plt.subplot(1, 2, 1)
    plt.pcolormesh(x1, x2, y_show_hat, cmap=cm_light)
    plt.scatter(x_test[:, 0], x_test[:, 1], c=y_test.ravel(), edgecolors='k', s=150, zorder=10, cmap=cm_dark,marker='*')
    plt.scatter(x[:, 0], x[:, 1], c=y.ravel(), edgecolors='k', s=40, cmap=cm_dark)
    plt.xlabel('sepal length', fontsize=15)
    plt.ylabel('sepal width', fontsize=15)
    plt.xlim(x1_min, x1_max)
    plt.ylim(x2_min, x2_max)
    plt.grid(True)
    plt.title('class', fontsize=17)
    plt.show()

degree为16时:
在这里插入图片描述
在这里插入图片描述
degree为8时:
在这里插入图片描述
然后我们看下选经典鸢尾花数据不同特征数带来的影响

//调用sklearn中的库完成拟合,并探究特征选取数和最大树高度max_degree不同时的测试集测试结果
from sklearn import *
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.tree import DecisionTreeClassifier
from numpy import *
import matplotlib.pyplot as plt
//分别选前两个特征和前四个特征,按70-30划分训练-测试集
data = datasets.load_iris()
x = data.data
y = data.target
x_2 = x[:, :2] # only 2 features
x_4 = x[:, :4] # 4 features
x_train2, x_test2, y_train2, y_test2 = train_test_split(x_2, y, train_size=0.7, test_size=0.3, random_state=1)
x_train4, x_test4, y_train4, y_test4 = train_test_split(x_4, y, train_size=0.7, test_size=0.3, random_state=1)
//分别设置树的最大高度为1-15,对x2和x4训练模型,记录每次的正确率,用两个数组记录。
Accuracy2 = []
Accuracy4 = []
for i in range(15):
    depth = i+1
    clf = DecisionTreeClassifier(criterion='entropy', max_depth=depth)
    clf.fit(x_train2, y_train2)
    score2 = clf.score(x_test2, y_test2)
    print("Depth: " , depth," | Accuracy:",score2)
    Accuracy2.append(score2)
for i in range(15):
    depth = i+1
    clf = DecisionTreeClassifier(criterion='entropy', max_depth=depth)
    clf.fit(x_train4, y_train4)
    score4 = clf.score(x_test4, y_test4)
    print("Depth: " , depth," | Accuracy:",score4)
    Accuracy4.append(score4)

在这里插入图片描述
在这里插入图片描述
就酱,希望对大家有帮助,欢迎点赞和在评论区讨论^

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 如果你想进行Python机器学习实训,可以考虑以下步骤: 1. 了解机器学习的基本概念和理论知识,例如监督学习、无监督学习、深度学习等。 2. 选择合适的Python机器学习库,例如Scikit-learn、TensorFlow、PyTorch、Keras等。 3. 学习Python机器学习库的使用方法,可以通过官方文档、教程视频或在线课程等方式进行学习。 4. 找到一些适合的机器学习案例进行实践,例如房价预测、图像识别、情感分析等。 5. 在实践中不断调试和优化模型,提高模型的准确度和性能。 6. 将学习到的知识和经验进行总结和分享,可以写博客、参与开源项目等方式进行交流。 ### 回答2: python机器学习实训是一种专门针对机器学习算法及其应用的培训课程。通过学习这门课程,学员可以了解机器学习的基本概念、算法原理和实际应用,掌握使用Python进行机器学习的技能。 在这门实训课程中,学员将学习Python编程语言的基础知识,包括语法、数据结构和常用库的使用。随后,学员将学习机器学习的基本概念,如训练集、测试集、分类、回归等,了解常用的机器学习算法和模型。 在实训过程中,学员将通过实际案例进行实践,使用Python编写机器学习模型的代码,进行数据预处理、特征提取、模型训练和评估。学员还可以学习到如何使用不同的机器学习库,如scikit-learn和tensorflow,来简化机器学习任务的实现。 此外,实训还将涵盖机器学习的应用领域,如自然语言处理、图像识别和推荐系统等。学员可以了解不同领域的机器学习应用,学习如何将机器学习算法应用到实际的问题中。 总之,python机器学习实训是一门系统化的培训课程,通过学习这门课程,学员可以获得Python编程和机器学习的双重能力,在实际应用中能够独立完成机器学习任务。 ### 回答3: Python机器学习实训是一种针对机器学习领域的培训课程,主要以Python语言为工具,让学员学习和掌握机器学习的相关知识和技能。 这种实训课程通常包含理论学习和实践操作两个方面。在理论学习阶段,学员会学习机器学习的基本概念、原理和算法,包括监督学习、无监督学习、深度学习等内容。学员会了解各种常用的机器学习算法,如线性回归、逻辑回归、决策树、支持向量机、神经网络等,并学习如何选择和优化合适的算法。 在实践操作阶段,学员会通过真实的数据集进行实际案例分析和建模实验。他们将使用Python编程语言和相关的机器学习库,如NumPy、SciPy、Scikit-learn等,进行数据预处理、特征工程、模型选择和评估等工作。学员会学习如何使用交叉验证、网格搜索等技术来优化模型,并通过可视化技术来展示和解释结果。 Python机器学习实训的目的是培养学员在机器学习领域的实际操作能力和解决问题的能力。通过这种实训,学员可以掌握Python语言,熟悉常见的机器学习算法和工具,并能够应用于实际项目中。实训过程中,学员还可以通过与导师和其他学员的互动交流,提高解决问题的能力和团队合作精神。 总而言之,Python机器学习实训提供了一个系统的学习机会,让学员在实践中掌握机器学习的技术和工具。这种实训有助于学员在人工智能领域中有竞争力,并为他们进一步深入研究和应用机器学习打下坚实的基础。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值