Python决策树分类算法学习
从这一章开始进入正式的算法学习。 首先我们学习经典而有效的分类算法:决策树分类算法。 1、决策树算法 决策树用树形结构对样本的属性进行分类,是最直观的分类算法,而且也可以用于回归。不过对于一些特殊的逻辑分类会有困难。典型的如异或(XOR)逻辑,决策树并不擅长解决此类问题。 熵就是“无序,混乱”的程度。刚接触这个概念可能会有些迷惑。想快速了解如何用信息熵增益划分属性,可以参考这位兄弟的文章:Python机器学习之决策树算法 如果还不理解,请看下面这个例子。 假设要构建这么一个自动选好苹果的决策树,简单起见,我只让他学习下面这4个样本: 样本中有2个属性,A0表示是否红苹果。A1表示是否大苹果。 那么这个样本在分类前的信息熵就是S = -(1/2 * log(1/2) + 1/2 * log(1/2)) = 1。 信息熵为1表示当前处于最混乱,最无序的状态。 本例仅2个属性。那么很自然一共就只可能有2棵决策树,如下图所示: 显然左边先使用A0(红色)做划分依据的决策树要优于右边用A1(大小)做划分依据的决策树。 因此选择A0划分后的信息熵为每个子节点的信息熵所占比重的加权和:E = e1*2/4 + e2*2/4 = 0。 事实上,决策树叶子节点表示已经都属于相同类别,因此信息熵一定为0。 同样的,如果先选A1作划分,各子节点信息熵计算如下: 2、数据集 为方便讲解与理解,我们使用如下一个极其简单的测试数据集: 这个数据一共有10个样本,每个样本有2个属性,分别为身高和体重,第三列为类别标签,表示“胖”或“瘦”。该数据保存在1.txt中。 我们的任务就是训练一个决策树分类器,输入身高和体重,分类器能给出这个人是胖子还是瘦子。 决策树对于“是非”的二值逻辑的分枝相当自然。而在本数据集中,身高与体重是连续值怎么办呢? 虽然麻烦一点,不过这也不是问题,只需要找到将这些连续值划分为不同区间的中间点,就转换成了二值逻辑问题。 使用python的机器学习库,实现起来相当简单和优雅。 3、Python实现 Python代码实现如下: # -*- coding: utf-8 -*- import numpy as np import scipy as sp from sklearn import tree from sklearn.metrics import precision_recall_curve from sklearn.metrics import classification_report from sklearn.cross_validation import train_test_split ''''' 数据读入 ''' data = [] labels = [] with open("data1.txt") as ifile: for line in ifile: tokens = line.strip().split(' ') data.append([float(tk) for tk in tokens[:-1]]) labels.append(tokens[-1]) x = np.array(data) labels = np.array(labels) y = np.zeros(labels.shape) ''''' 标签转换为0/1 ''' y[labels=='fat']=1 ''''' 拆分训练数据与测试数据 ''' x_train,x_test,y_train,y_test = train_test_split(x,y,test_size = 0.2) ''''' 使用信息熵作为划分标准,对决策树进行训练 ''' clf = tree.DecisionTreeClassifier(criterion='entropy') print(clf) clf.fit(x_train,y_train) ''''' 把决策树结构写入文件 ''' with open("tree.dot",'w') as f: f = tree.export_graphviz(clf,out_file=f) ''''' 系数反映每个特征的影响力。越大表示该特征在分类中起到的作用越大 ''' print(clf.feature_importances_) '''''测试结果的打印''' answer = clf.predict(x_train) print(x_train) print(answer) print(y_train) print(np.mean( answer == y_train)) '''''准确率与召回率''' precision,recall,thresholds = precision_recall_curve(y_train,clf.predict(x_train)) answer = clf.predict_proba(x)[:,1] print(classification_report(y,answer,target_names = ['thin','fat'])) 输出结果类似如下所示: 可以看到,对训练过的数据做测试,准确率是100%。但是最后将所有数据进行测试,会出现1个测试样本分类错误。 1、拆分训练数据与测试数据。 这样做是为了方便做交叉检验。交叉检验是为了充分测试分类器的稳定性。 2、特征的不同影响因子。 样本的不同特征对分类的影响权重差异会很大。分类结束后看看每个样本对分类的影响度也是很重要的。 3、准确率与召回率。 这2个值是评判分类准确率的一个重要标准。比如代码的最后将所有10个样本输入分类器进行测试的结果: 代码还把决策树的结构写入了tree.dot中。打开该文件,很容易画出决策树,还可以看到决策树的更多分类信息。 digraph Tree { 0 [label="X[1] <= 55.0000nentropy = 0.954434002925nsamples = 8",shape="box"] ; 1 [label="entropy = 0.0000nsamples = 2nvalue = [ 2. 0.]",shape="box"] ; 0 -> 1 ; 2 [label="X[1] <= 70.0000nentropy = 0.650022421648nsamples = 6",shape="box"] ; 0 -> 2 ; 3 [label="X[0] <= 1.6500nentropy = 0.918295834054nsamples = 3",shape="box"] ; 2 -> 3 ; 4 [label="entropy = 0.0000nsamples = 2nvalue = [ 0. 2.]",shape="box"] ; 3 -> 4 ; 5 [label="entropy = 0.0000nsamples = 1nvalue = [ 1. 0.]",shape="box"] ; 3 -> 5 ; 6 [label="entropy = 0.0000nsamples = 3nvalue = [ 0. 3.]",shape="box"] ; 2 -> 6 ; } 根据这个信息,决策树应该长的如下这个样子: 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Python的hashlib提供了常见的摘要算法
- 从另一个python程序运行python程序(有一定的要求)
- 详解Python中 __get__和__getattr__和__getattribute__的区
- python2.7 mayavi 安装图文教程(推荐)
- python – 迭代时从列表中删除
- python – 为什么在memcache上调用get()会增加Google App E
- 基python实现多线程网页爬虫
- python – 在PyGObject中找不到gdk_property_change
- python实现忽略大小写对字符串列表排序的方法
- python-2.7 – 如何在AWS Lambda函数中使用boto3通过AWS SN