初识机器学习之决策树对鸢尾花进行分类

来源:互联网 发布:java软件认证培训 编辑:程序博客网 时间:2024/04/28 17:39
今天想简单聊一下对机器学习中决策树分类的认识,并实现了一个用决策树对经典鸢尾花数据集分类的应用。在我看来,决策树中最重要的一个概念就是信息熵。X的信息熵用H(X)表示,也就是X所含的信息量大小。                  H(X)=P(X)logP(X)                  H(X,Y)=P(X,Y)logP(X,Y)在决策树分类的建树过程中,由根节点到叶子节点,熵的值应该越来越小,一直到0(对分类结果越来越确定)。基本思想是:以信息熵为度量构造一棵熵值下降最快的树,到叶子结点熵值为0。决策树的选择特征属性的方式也有很多种,例如ID3,C4.5,CART等等。以ID3为例,这种方式在每一步时选择信息增益最大的属性做下一步的判别属性。          信息增益Gain(X,f)=H(X)-H(X|f)=I(X|f)   而C4.5依靠信息增益率Gr(X,f)=Gain(X,f)/H(f);CART依靠Gini系数。在下面的应用中,我们选择ID3对属性进行选择。鸢尾花数据集是最有名的模式识别测试数据。共包括三个鸢尾花种类,每个类别有五十个样本,四个特征分别为花萼长度,花萼宽度,花瓣长度,花瓣宽度。

鸢尾花数据集
代码使用python实现,随机在四个特征中选择两个进行分类,共六种组合。训练集占0.7,测试集占0.3。

import numpy as npimport pandas as pdimport matplotlib as mplimport matplotlib.pyplot as pltfrom sklearn.tree import DecisionTreeClassifier# 'sepal length', 'sepal width', 'petal length', 'petal width'iris_feature = u'花萼长度', u'花萼宽度', u'花瓣长度', u'花瓣宽度'if __name__ == "__main__":    mpl.rcParams['font.sans-serif'] = [u'SimHei']  # 黑体 FangSong/KaiTi    mpl.rcParams['axes.unicode_minus'] = False    path = 'D:\iris.data'  # 数据文件路径    data = pd.read_csv(path, header=None)    x_prime = data[range(4)]    y = pd.Categorical(data[4]).codes    feature_pairs = [[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3]]    plt.figure(figsize=(10, 9), facecolor='#FFFFFF')    for i, pair in enumerate(feature_pairs):        # 准备数据        x = x_prime[pair]        x_train, x_testt, y_train, y_test = train_test_split(x, y, train_size=0.7, random_state=1)        # 决策树学习        clf = DecisionTreeClassifier(criterion='entropy', min_samples_leaf=3)        clf.fit(x_train, y_train)        # 画图        # 横纵各采样多少个值        N, M = 500, 500          x1_min, x2_min = x.min()        x1_max, x2_max = x.max()        t1 = np.linspace(x1_min, x1_max, N)        t2 = np.linspace(x2_min, x2_max, M)        x1, x2 = np.meshgrid(t1, t2)  # 生成网格采样点        x_test = np.stack((x1.flat, x2.flat), axis=1)  # 测试点        # 训练集上的预测结果        y_test_hat = clf.predict(x_testt)        y_train_hat = clf.predict(x_train)        #print y_test_hat,y_test        #y = y.reshape(-1)        c = np.count_nonzero(y_test_hat == y_test)    # 统计预测正确的个数        d = np.count_nonzero(y_train_hat==y_train)        #print 'c=',c        print '\n特征:  ', iris_feature[pair[0]], ' + ', iris_feature[pair[1]],        print '\n测试集预测正确数目:', c,'\n训练集预测正确数目:',d,        #print '\nacc:',accuracy_score(y_test,y_test_hat)        print '\n测试集准确率: %.2f%%' % (100 * float(c) / float(len(y_test)))        print '训练集准确率: %.2f%%' % (100 * float(d) / float(len(y_train)))        # 显示        cm_light = mpl.colors.ListedColormap(['#A0FFA0', '#FFA0A0', '#A0A0FF'])        cm_dark = mpl.colors.ListedColormap(['g', 'r', 'b'])        y_hat = clf.predict(x_test)  # 预测值        #y_test_hat = clf.predict(x_testt)        y_hat = y_hat.reshape(x1.shape)  # 使之与输入的形状相同        plt.subplot(2, 3, i+1)        plt.pcolormesh(x1, x2, y_hat, cmap=cm_light)  # 预测值,画背景颜色        plt.scatter(x[pair[0]], x[pair[1]], c=y, edgecolors='k', cmap=cm_dark)  # 样本        plt.xlabel(iris_feature[pair[0]], fontsize=14)        plt.ylabel(iris_feature[pair[1]], fontsize=14)        plt.xlim(x1_min, x1_max)        plt.ylim(x2_min, x2_max)        plt.grid()    plt.suptitle(u'决策树对鸢尾花数据的两特征组合的分类结果', fontsize=18)    plt.tight_layout(2)    plt.subplots_adjust(top=0.92)    plt.show()

最终结果如下图
分类结果 这里写图片描述 可视化结果
最终可以看出,通过花瓣长度和花瓣宽度可以得到最佳分类结果。