基于python的python 决策树包能进行多分类吗

Sklearn库例子——决策树分类
来源:博客园
Sklearn上关于决策树算法使用的介绍:1、关于决策树:决策树是一个非参数的监督式学习方法,主要用于分类和回归。算法的目标是通过推断数据特征,学习决策规则从而创建一个预测目标变量的模型。如下如所示,决策树通过一系列if-then-else 决策规则 近似估计一个正弦曲线。  决策树优势:简单易懂,原理清晰,决策树可以实现可视化数据准备简单。其他的方法需要实现数据归一化,创建虚拟变量,删除空白变量。(注意:这个模块不支持缺失值)使用决策树的代价是数据点的对数级别。能够处理数值和分类数据能够处理多路输出问题使用白盒子模型(内部结构可以直接观测的模型)。一个给定的情况是可以观测的,那么就可以用布尔逻辑解释这个结果。相反,如果在一个黑盒模型(ANN),结果可能很难解释可以通过统计学检验验证模型。这也使得模型的可靠性计算变得可能即使模型假设违反产生数据的真实模型,表现性能依旧很好。 决策树劣势:可能会建立过于复杂的规则,即过拟合。为避免这个问题,剪枝、设置叶节点的最小样本数量、设置决策树的最大深度有时候是必要的。决策树有时候是不稳定的,因为数据微小的变动,可能生成完全不同的决策树。 可以通过总体平均(ensemble)减缓这个问题。应该指的是多次实验。学习最优决策树是一个NP完全问题。所以,实际决策树学习算法是基于试探性算法,例如在每个节点实现局部最优值的贪心算法。这样的算法是无法保证返回一个全局最优的决策树。可以通过随机选择特征和样本训练多个决策树来缓解这个问题。有些问题学习起来非常难,因为决策树很难表达。如:异或问题、奇偶校验或多路复用器问题如果有些因素占据支配地位,决策树是有偏的。因此建议在拟合决策树之前先平衡数据的影响因子。 2、分类DecisionTreeClassifier 能够实现多类别的分类。输入两个向量:向量X,大小为[n_samples,n_features],用于记录训练样本;向量Y,大小为[n_samples],用于存储训练样本的类标签。from sklearn import treeX = [[0, 0], [1, 1]]Y = [0, 1]clf = tree.DecisionTreeClassifier()clf = clf.fit(X, Y) clf.predict([[2., 2.]])clf.predict_proba([[2., 2.]])
下面我们使用iris数据集:from sklearn.datasets import load_irisfrom sklearn import treeiris = load_iris()clf = tree.DecisionTreeClassifier()clf = clf.fit(iris.data, iris.target) # export the tree in Graphviz format using the export_graphviz exporterwith open("iris.dot", 'w') as f:
f = tree.export_graphviz(clf, out_file=f) # predict the class of samplesclf.predict(iris.data[:1, :])# the probability of each classclf.predict_proba(iris.data[:1, :]) 安装Graphviz将其添加到环境变量,使用dot创建一个PDF文件。dot -Tpdf iris.dot -o iris.pdf  关于安装Graphviz方法请参照:运行结果在文件夹下会有:这两个文件。我们打开iris.pdf你也可以通过安装pydotplus包。安装方式:pip install pydotplus.在Python 中直接生成:import pydotplus dot_data = tree.export_graphviz(clf, out_file=None) graph = pydotplus.graph_from_dot_data(dot_data) graph.write_pdf("iris.pdf") 注意:运行这段代码是会出错。我解决了很久没有解决掉。可以参考:下面代码是Sklearn官网上的演示代码:import numpy as npimport matplotlib.pyplot as pltfrom sklearn.datasets import load_irisfrom sklearn.tree import DecisionTreeClassifier# Parametersn_classes = 3plot_colors = "bry"plot_step = 0.02# Load datairis = load_iris()for pairidx, pair in enumerate([[0, 1], [0, 2], [0, 3],
[1, 2], [1, 3], [2, 3]]):
# We only take the two corresponding features
X = iris.data[:, pair]
y = iris.target
clf = DecisionTreeClassifier().fit(X, y)
# Plot the decision boundary
plt.subplot(2, 3, pairidx + 1)
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, plot_step),
np.arange(y_min, y_max, plot_step))
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
cs = plt.contourf(xx, yy, Z, cmap=plt.cm.Paired)
plt.xlabel(iris.feature_names[pair[0]])
plt.ylabel(iris.feature_names[pair[1]])
plt.axis("tight")
# Plot the training points
for i, color in zip(range(n_classes), plot_colors):
idx = np.where(y == i)
plt.scatter(X[idx, 0], X[idx, 1], c=color, label=iris.target_names[i],
cmap=plt.cm.Paired)
plt.axis("tight")plt.suptitle("Decision surface of a decision tree using paired features")plt.legend()plt.show() 代码运行结果:
免责声明:本站部分内容、图片、文字、视频等来自于互联网,仅供大家学习与交流。相关内容如涉嫌侵犯您的知识产权或其他合法权益,请向本站发送有效通知,我们会及时处理。反馈邮箱&&&&。
学生服务号
在线咨询,奖学金返现,名师点评,等你来互动购买商品:
商品价格:
价格读取中
支付方式:
请扫码进行支付
请扫码进行支付
适合人群所有人已参加学习1986
Python 在机器学习领域应用是非常广泛的,比如,我们可以使用机器学习进行验证码识别,使用机器学习实现计算机视觉项目,或者,我们也可以使用机器学习技术实现网页分类、文本挖掘、情感分析等等各种各样的事情。机器学习的重点在于算法,而算法的学习相对来说是比较枯燥的,所以,只有在学习的时候让算法跟实例结合,才能够让算法的学习变得不枯燥,并且也才能够更好的将理论运用与实践。
高校教师 / 培训机构讲师
重庆韬翔网络科技有限公司董事长兼CEO,国内知名出版社IT作家,CSDN学院特邀IT专家,《知道日报》特约作者,国家工信部高级网络营销师,蜻蜓FM独家签约主播,国家专利发明人,多年IT从业经验,曾出品发明过多门IT课程并获得大量学员的支持与喜爱。
付费用户才能下载
领取优惠券
正在努力加载中~~
购买讲师卡
权益 : 免费学习韦老师发布的所有课程,免费学习在会员有效期内讲师新发布的所有课程。
承诺 : 保持好课程质量,并不断地更新课程,让更多的学员受益。用Python开始机器学习(2:决策树分类算法) - CSDN博客
用Python开始机器学习(2:决策树分类算法)
从这一章开始进入正式的算法学习。首先我们学习经典而有效的分类算法:决策树分类算法。1、决策树算法决策树用树形结构对样本的属性进行分类,是最直观的分类算法,而且也可以用于回归。不过对于一些特殊的逻辑分类会有困难。典型的如异或(XOR)逻辑,决策树并不擅长解决此类问题。决策树的构建不是唯一的,遗憾的是最优决策树的构建属于NP问题。因此如何构建一棵好的决策树是研究的重点。J. Ross Quinlan在1975提出将信息熵的概念引入决策树的构建,这就是鼎鼎大名的ID3算法。后续的C4.5, C5.0, CART等都是该方法的改进。熵就是“无序,混乱”的程度。刚接触这个概念可能会有些迷惑。想快速了解如何用信息熵增益划分属性,可以参考这位兄弟的文章:如果还不理解,请看下面这个例子。假设要构建这么一个自动选好苹果的决策树,简单起见,我只让他学习下面这4个样本:样本
0样本中有2个属性,A0表示是否红苹果。A1表示是否大苹果。那么这个样本在分类前的信息熵就是S = -(1/2 * log(1/2) +&1/2 * log(1/2)) = 1。信息熵为1表示当前处于最混乱,最无序的状态。本例仅2个属性。那么很自然一共就只可能有2棵决策树,如下图所示:显然左边先使用A0(红色)做划分依据的决策树要优于右边用A1(大小)做划分依据的决策树。当然这是直觉的认知。定量的考察,则需要计算每种划分情况的信息熵增益。先选A0作划分,各子节点信息熵计算如下:0,1叶子节点有2个正例,0个负例。信息熵为:e1 = -(2/2 * log(2/2) + 0/2 * log(0/2)) = 0。2,3叶子节点有0个正例,2个负例。信息熵为:e2 =&-(0/2 * log(0/2) + 2/2 * log(2/2)) = 0。因此选择A0划分后的信息熵为每个子节点的信息熵所占比重的加权和:E = e1*2/4 + e2*2/4 = 0。选择A0做划分的信息熵增益G(S, A0)=S - E = 1 - 0 = 1.事实上,决策树叶子节点表示已经都属于相同类别,因此信息熵一定为0。同样的,如果先选A1作划分,各子节点信息熵计算如下:0,2子节点有1个正例,1个负例。信息熵为:e1 = -(1/2 * log(1/2) + 1/2 * log(1/2)) = 1。1,3子节点有1个正例,1个负例。信息熵为:e2 =&-(1/2 * log(1/2) + 1/2 * log(1/2)) = 1。因此选择A1划分后的信息熵为每个子节点的信息熵所占比重的加权和:E = e1*2/4 + e2*2/4 = 1。也就是说分了跟没分一样!选择A1做划分的信息熵增益G(S, A1)=S - E = 1 - 1 = 0.因此,每次划分之前,我们只需要计算出信息熵增益最大的那种划分即可。2、数据集为方便讲解与理解,我们使用如下一个极其简单的测试数据集:1.5 50 thin
1.5 60 fat
1.6 40 thin
1.6 60 fat
1.7 60 thin
1.7 80 fat
1.8 60 thin
1.8 90 fat
1.9 70 thin
1.9 80 fat这个数据一共有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(&data\\1.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']))
输出结果类似如下所示:[ 0..7511438]array([[ &1.6, &60. ],& & & &[ &1.7, &60. ],& & & &[ &1.9, &80. ],& & & &[ &1.5, &50. ],& & & &[ &1.6, &40. ],& & & &[ &1.7, &80. ],& & & &[ &1.8, &90. ],& & & &[ &1.5, &60. ]])array([ 1., &0., &1., &0., &0., &1., &1., &1.])array([ 1., &0., &1., &0., &0., &1., &1., &1.])1.0& & & & & & &precision & &recall &f1-score & support& & & &thin & & & 0.83 & & &1.00 & & &0.91 & & & & 5& & & & fat & & & &1.00 & & &0.80 & & &0.89 & & & & 5avg / total & & & 1.00 & & &1.00 & & &1.00 & & & & 8array([ 0., &1., &0., &1., &0., &1., &0., &1., &0., &0.])array([ 0., &1., &0., &1., &0., &1., &0., &1., &0., &1.])可以看到,对训练过的数据做测试,准确率是100%。但是最后将所有数据进行测试,会出现1个测试样本分类错误。说明本例的决策树对训练集的规则吸收的很好,但是预测性稍微差点。这里有3点需要说明,这在以后的机器学习中都会用到。1、拆分训练数据与测试数据。这样做是为了方便做交叉检验。交叉检验是为了充分测试分类器的稳定性。代码中的0.2表示随机取20%的数据作为测试用。其余80%用于训练决策树。也就是说10个样本中随机取8个训练。本文数据集小,这里的目的是可以看到由于取的训练数据随机,每次构建的决策树都不一样。2、特征的不同影响因子。样本的不同特征对分类的影响权重差异会很大。分类结束后看看每个样本对分类的影响度也是很重要的。在本例中,身高的权重为0.25,体重为0.75,可以看到重量的重要性远远高于身高。对于胖瘦的判定而言,这也是相当符合逻辑的。3、准确率与召回率。这2个值是评判分类准确率的一个重要标准。比如代码的最后将所有10个样本输入分类器进行测试的结果:测试结果:array([ 0., &1., &0., &1., &0., &1., &0., &1., &0., &0.])真实结果:array([ 0., &1., &0., &1., &0., &1., &0., &1., &0., &1.])分为thin的准确率为0.83。是因为分类器分出了6个thin,其中正确的有5个,因此分为thin的准确率为5/6=0.83。分为thin的召回率为1.00。是因为数据集中共有5个thin,而分类器把他们都分对了(虽然把一个fat分成了thin!),召回率5/5=1。分为fat的准确率为1.00。不再赘述。分为fat的召回率为0.80。是因为数据集中共有5个fat,而分类器只分出了4个(把一个fat分成了thin!),召回率4/5=0.80。很多时候,尤其是数据分类难度较大的情况,准确率与召回率往往是矛盾的。你可能需要根据你的需要找到最佳的一个平衡点。比如本例中,你的目标是尽可能保证找出来的胖子是真胖子(准确率),还是保证尽可能找到更多的胖子(召回率)。代码还把决策树的结构写入了tree.dot中。打开该文件,很容易画出决策树,还可以看到决策树的更多分类信息。本文的tree.dot如下所示:digraph Tree {
0 [label=&X[1] &= 55.0000\nentropy = 0.\nsamples = 8&, shape=&box&] ;
1 [label=&entropy = 0.0000\nsamples = 2\nvalue = [ 2.
0.]&, shape=&box&] ;
2 [label=&X[1] &= 70.0000\nentropy = 0.\nsamples = 6&, shape=&box&] ;
3 [label=&X[0] &= 1.6500\nentropy = 0.\nsamples = 3&, shape=&box&] ;
4 [label=&entropy = 0.0000\nsamples = 2\nvalue = [ 0.
2.]&, shape=&box&] ;
5 [label=&entropy = 0.0000\nsamples = 1\nvalue = [ 1.
0.]&, shape=&box&] ;
6 [label=&entropy = 0.0000\nsamples = 3\nvalue = [ 0.
3.]&, shape=&box&] ;
根据这个信息,决策树应该长的如下这个样子:
本文已收录于以下专栏:
相关文章推荐
一、决策树原理
决策树是用样本的属性作为结点,用属性的取值作为分支的树结构。
决策树的根结点是所有样本中信息量最大的属性。树的中间结点是该结点为根的子树所包含的样本子集中信息量最大的属性。决策树...
本文数据参照 机器学习-周志华 一书中的决策树一章。可作为此章课后习题3的答案
代码则参照《机器学习实战》一书的内容,并做了一些修改。
本文使用的Python库包括
numpypandasma...
文章参考自:http://blog.csdn.net/wzmsltw/article/details/
# -*- coding: utf-8 -*-
Created on ...
文本特征抽取与向量化 TF-IDF 词频-反转文档频率
机器学习算法与Python实践之(一)k近邻(KNN)http://blog.csdn.net/zouxy09        机器学习算法与Python实践这个系列主要是参...
在本系列文章中提到过用Python开始机器学习(3:数据拟合与广义线性回归)中提到过回归算法。逻辑回归算法本质还是回归,只是其引入了逻辑函数来帮助其分类。实践发现,逻辑回归在文本分类领域表现的也很优秀...
他的最新文章
讲师:宋宝华
讲师:何宇健
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)决策树的python实现方法
投稿:shichen2014
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了决策树的python实现方法,详细分析了决策树的优缺点及算法思想并以完整实例形式讲述了Python实现决策树的方法,具有一定的借鉴价值,需要的朋友可以参考下
本文实例讲述了决策树的python实现方法。分享给大家供大家参考。具体实现方法如下:
决策树算法优缺点:
优点:计算复杂度不高,输出结果易于理解,对中间值缺失不敏感,可以处理不相关的特征数据
缺点:可能会产生过度匹配的问题
适用数据类型:数值型和标称型
算法思想:
1.决策树构造的整体思想:
决策树说白了就好像是if-else结构一样,它的结果就是你要生成这个一个可以从根开始不断判断选择到叶子节点的树,但是呢这里的if-else必然不会是让我们认为去设置的,我们要做的是提供一种方法,计算机可以根据这种方法得到我们所需要的决策树。这个方法的重点就在于如何从这么多的特征中选择出有价值的,并且按照最好的顺序由根到叶选择。完成了这个我们也就可以递归构造一个决策树了
2.信息增益
划分数据集的最大原则是将无序的数据变得更加有序。既然这又牵涉到信息的有序无序问题,自然要想到想弄的信息熵了。这里我们计算用的也是信息熵(另一种方法是基尼不纯度)。公式如下:
数据需要满足的要求:
① 数据必须是由列表元素组成的列表,而且所有的列白哦元素都要具有相同的数据长度
② 数据的最后一列或者每个实例的最后一个元素应是当前实例的类别标签
calcShannonEnt(dataSet)
计算数据集的香农熵,分两步,第一步计算频率,第二部根据公式计算香农熵
splitDataSet(dataSet, aixs, value)
划分数据集,将满足X[aixs]==value的值都划分到一起,返回一个划分好的集合(不包括用来划分的aixs属性,因为不需要)
chooseBestFeature(dataSet)
选择最好的属性进行划分,思路很简单就是对每个属性都划分下,看哪个好。这里使用到了一个set来选取列表中唯一的元素,这是一中很快的方法
majorityCnt(classList)
因为我们递归构建决策树是根据属性的消耗进行计算的,所以可能会存在最后属性用完了,但是分类还是没有算完,这时候就会采用多数表决的方式计算节点分类
createTree(dataSet, labels)
基于递归构建决策树。这里的label更多是对于分类特征的名字,为了更好看和后面的理解。
#coding=utf-8
import operator
from math import log
import time
def createDataSet():
&&& dataSet=[[1,1,'yes'],
&&&&&&&&&&& [1,1,'yes'],
&&&&&&&&&&& [1,0,'no'],
&&&&&&&&&&& [0,1,'no'],
&&&&&&&&&&& [0,1,'no']]
&&& labels = ['no surfaceing','flippers']
&&& return dataSet, labels
#计算香农熵
def calcShannonEnt(dataSet):
&&& numEntries = len(dataSet)
&&& labelCounts = {}
&&& for feaVec in dataSet:
&&&&&&& currentLabel = feaVec[-1]
&&&&&&& if currentLabel not in labelCounts:
&&&&&&&&&&& labelCounts[currentLabel] = 0
&&&&&&& labelCounts[currentLabel] += 1
&&& shannonEnt = 0.0
&&& for key in labelCounts:
&&&&&&& prob = float(labelCounts[key])/numEntries
&&&&&&& shannonEnt -= prob * log(prob, 2)
&&& return shannonEnt
def splitDataSet(dataSet, axis, value):
&&& retDataSet = []
&&& for featVec in dataSet:
&&&&&&& if featVec[axis] == value:
&&&&&&&&&&& reducedFeatVec = featVec[:axis]
&&&&&&&&&&& reducedFeatVec.extend(featVec[axis+1:])
&&&&&&&&&&& retDataSet.append(reducedFeatVec)
&&& return retDataSet
def chooseBestFeatureToSplit(dataSet):
&&& numFeatures = len(dataSet[0]) - 1#因为数据集的最后一项是标签
&&& baseEntropy = calcShannonEnt(dataSet)
&&& bestInfoGain = 0.0
&&& bestFeature = -1
&&& for i in range(numFeatures):
&&&&&&& featList = [example[i] for example in dataSet]
&&&&&&& uniqueVals = set(featList)
&&&&&&& newEntropy = 0.0
&&&&&&& for value in uniqueVals:
&&&&&&&&&&& subDataSet = splitDataSet(dataSet, i, value)
&&&&&&&&&&& prob = len(subDataSet) / float(len(dataSet))
&&&&&&&&&&& newEntropy += prob * calcShannonEnt(subDataSet)
&&&&&&& infoGain = baseEntropy -newEntropy
&&&&&&& if infoGain & bestInfoGain:
&&&&&&&&&&& bestInfoGain = infoGain
&&&&&&&&&&& bestFeature = i
&&& return bestFeature
&&&&&&&&&&&
#因为我们递归构建决策树是根据属性的消耗进行计算的,所以可能会存在最后属性用完了,但是分类
#还是没有算完,这时候就会采用多数表决的方式计算节点分类
def majorityCnt(classList):
&&& classCount = {}
&&& for vote in classList:
&&&&&&& if vote not in classCount.keys():
&&&&&&&&&&& classCount[vote] = 0
&&&&&&& classCount[vote] += 1
&&& return max(classCount)&&&&&&&&
def createTree(dataSet, labels):
&&& classList = [example[-1] for example in dataSet]
&&& if classList.count(classList[0]) ==len(classList):#类别相同则停止划分
&&&&&&& return classList[0]
&&& if len(dataSet[0]) == 1:#所有特征已经用完
&&&&&&& return majorityCnt(classList)
&&& bestFeat = chooseBestFeatureToSplit(dataSet)
&&& bestFeatLabel = labels[bestFeat]
&&& myTree = {bestFeatLabel:{}}
&&& del(labels[bestFeat])
&&& featValues = [example[bestFeat] for example in dataSet]
&&& uniqueVals = set(featValues)
&&& for value in uniqueVals:
&&&&&&& subLabels = labels[:]#为了不改变原始列表的内容复制了一下
&&&&&&& myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& bestFeat, value),subLabels)
&&& return myTree
def main():
&&& data,label = createDataSet()
&&& t1 = time.clock()
&&& myTree = createTree(data,label)
&&& t2 = time.clock()
&&& print myTree
&&& print 'execute for ',t2-t1
if __name__=='__main__':
&&& main()
希望本文所述对大家的Python程序设计有所帮助。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具

我要回帖

更多关于 python 决策树分类 的文章

 

随机推荐