机器学习实践 学习笔记3 decision trees

决策树(decision trees)

工作原理:

决策树属于监督类型的算法,同样,我们有数据集,知道每一条数据的分类。然后我们按照某种规则,选取数据集上的特征作为分割点,把数据集进行划分。循环重复以上动作,直至所有数据集各自的分类都是唯一的,或者所有特征已经被选择无法再进行划分。使用何种规则进行特征的选取下文将会叙述。

优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据。

缺点:可能会产生过度匹配问题。

适用数据类型:数值型和标称型。

伪代码:

CreateBranch():

IF 数据集里的数据都属于同一个分类   RETURN 分类

ELSE

根据规则寻找用于划分数据集的特征

划分数据集

创建分支节点

for 循环每个子数据集

递归调用CreateBranch()并把结果放在创建的分支节点中

RETURN 分支节点

python代码:

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

部分函数将会在下文说明。

选取用于划分数据集特征的规则:

划分数据的大原则是使无序的数据变得相对有序。划分数据后的有序程度,与划分数据前的有序程度之间的差,称为信息增益(Information gain)。可以使用熵(entropy)来计算数据的无序程度。熵越高,则数据的无序程度越高。

要计算熵,首先要了解熵的定义。熵的定义为:信息的期望值。信息的定义为:如果待分类的事物可能划分在多个分类之中, 则)xi(分类为第i种的信息定义为

其中p(xi)是选择该分类的概率。

那么可以这样计算熵:

其中,n是分类的数目,i是第i个分类。

由此,可以创建用于计算给定数据集熵的python函数

def calcShannonEnt(dataSet):
	numEntries = len(dataSet)
	labelCounts = {}
	for featVec in dataSet:
		currentLabel = featVec[-1]
		if currentLabel not in labelCounts.keys():
		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 createDataSet():
	dataSet = [[1, 1, 'yes'],
		[1, 1, 'yes'],
		[1, 0, 'no'],
		[0, 1, 'no'],
		[0, 1, 'no']]
labels = ['no surfacing','flippers']
return dataSet, labels

在此操作之前,先来实现根据任意给定的特征切割数据集的函数。

def splitDataSet(dataSet,axis,value):
	retDataSet = []
	for featVec in dataSet:
		if featVec[axis] == value:#把复合条件的数据除去axis列塞进retDataSet
			reducedFeatvec = featVec[:axis]
			reducedFeatvec.extend(featVec[axis+1:]);#axis列并不复制
			retDataSet.append(reducedFeatvec)
	return retDataSet

接下来,对每一个特征都进行划分,然后计算划分后的熵,找出最适合进行划分的特征:

def chooseBestFeatureToSplit(dataSet):
	numFeatures = len(dataSet[0]) - 1 #特征数,最后一个是分类所以要减1
	baseEntropy = calcShannonEnt(dataSet)#划分前的熵
	bestInfoGain = 0.0;bestFeature = -1
	for i in range(numFeatures):
		featList = [example[i] for example in dataSet]#提取低i列的所有值
		uniqueVals = set(featList)#通过set函数,筛选值
		newEntropy = 0.0
		for value in uniqueVals:
			subDataSet = splitDataSet(dataSet,i,value)
			prob = len(subDataSet)/float(len(dataSet))#概率
			newEntropy += calcShannonEnt(subDataSet)
		infoGain = baseEntropy - newEntropy
		if(infoGain > bestInfoGain):
			bestInfoGain = infoGain
			bestFeature = i
	return bestFeature

递归构建决策树:

首先是递归结束条件:

1)子集全部属于同一种分类

2)如果特征已被提取完,选取子集分类数目最多的分类作为返回值

def majorityCnt(classList):
	classCount = {}
	for vote in classList:
		if vote not in classCount.keys():classCount[vote] = 0
		classCount[vote] += 1
	sortedClassCount = sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)
	return sortedClassCount[0][0]
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 classify(inputTree,featLabels,testVec):
	firstStr = inputTree.keys()[0]
	secondDict = inputTree[firstStr]
	featIndex = featLabels.index(firstStr)
	for key in secondDict.keys():
		if testVec[featIndex] == key:#比较特征值,决策树是根据特征的值划分的
			if type(secondDict[key]).__name__=='dict':#比较是否到达叶结点
				classLabel = classify(secondDict[key],featLabels,testVec)#递归调用
			else: classLabel = secondDict[key]
	return classLabel

决策树至此完毕,还有一些问题,如树的字典表示并不好阅读,可以使用Matplotlib绘制树形图,储存生成好的决策树在硬盘上,以免重复生成耗时等。这里暂时不述。决策树还有其他生成方法,如C4.5,CART等,将在后面章节探讨。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-12 09:14:32

机器学习实践 学习笔记3 decision trees的相关文章

机器学习实战学习笔记(一)

1.k-近邻算法 算法原理: 存在一个样本数据集(训练样本集),并且我们知道样本集中的每个数据与其所属分类的对应关系.输入未知类别的数据后将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似(最近邻)的k组数据.然后将k组数据中出现次数最多的分类,来作为新数据的分类. 算法步骤: 计算已知类别数据集中的每一个点与当前点之前的距离.(相似度度量) 按照距离递增次序排序 选取与当前点距离最小的k个点 确定k个点所在类别的出现频率 返回频率最高的类别作为当前点的分类 py

《机器学习》学习笔记(一)

今天看了两集Stanford 的Machine Learning,先说说感受,在看的过程中,脑海里冒出来一个念头:在中国的大学里,教授们都是好像在做研究,而学生们都是好像在上课,到头来不知道学到了什么,我在屏幕的这边都能感受到他们和我们的不一样. 其实对于机器学习,我是真心不懂,也不知道为什么忽然就想学习一下了,然后看了第一集就觉得实在是太牛X了,他们做的那个爬越障碍物的狗和快速避障的小车,都不是我们能搞出来的,说来也奇怪,我们不是也有他们一样的课程体系吗?照理说在大学里能做出来的东西,我们也应

机器学习技法--学习笔记04--Soft SVM

背景 之前所讨论的SVM都是非常严格的hard版本,必须要求每个点都被正确的区分开.但是,实际情况时很少出现这种情况的,因为噪声数据时无法避免的.所以,需要在hard SVM上添加容错机制,使得可以容忍少量噪声数据. ? "软"化问题 软化SVM的思路有点类似正规化,在目标函数添加错误累加项,然后加一个系数,控制对错误的容忍度,并且在约束中添加错误容忍度的约束,形式如下: ? 现在问题就变成了(d+1+N)个变量和2N个约束.ξ用来描述错误的容忍度.C是常量,用来控制容忍度.C越大,由

【吴恩达机器学习】学习笔记——2.1单变量线性回归算法

1 回顾1.1 监督学习定义:给定正确答案的机器学习算法分类:(1)回归算法:预测连续值的输出,如房价的预测(2)分类算法:离散值的输出,如判断患病是否为某种癌症1.2 非监督学习定义:不给定数据的信息的情况下,分析数据之间的关系.聚类算法:将数据集中属性相似的数据点划分为一类. 2 单变量线性回归算法2.1 符号定义m = 训练样本的数量x = 输入变量y = 输出变量2.2 工作方式训练集通过学习算法生成线性回归函数hypothesis  hθ(x) = θ0 + θ1x 原文地址:http

机器学习基石--学习笔记01--linear hard SVM

背景 支持向量机(SVM)背后的数学知识比较复杂,之前尝试过在网上搜索一些资料自学,但是效果不佳.所以,在我的数据挖掘工具箱中,一直不会使用SVM这个利器.最近,台大林轩田老师在Coursera上的机器学习技法课程上有很详细的讲授SVM的原理,所以机会难得,一定要好好把握这次机会,将SVM背后的原理梳理清楚并记录下来.这篇文章总结第一讲linear hard SVM的相关内容. ? ? 最好的分割线 之前有讲过PLA,即在线性可分的数据中,找到一条线,能够区分开正负样本,如下所示: 上面三条线,

Python_sklearn机器学习库学习笔记(七)the perceptron(感知器)

一.感知器 感知器是Frank Rosenblatt在1957年就职于Cornell航空实验室时发明的,其灵感来自于对人脑的仿真,大脑是处理信息的神经元(neurons)细胞和链接神经元细胞进行信息传递的突触(synapses)构成. 一个神经元可以看做将一个或者多个输入处理成一个输出的计算单元.一个感知器函数类似于一个神经元:它接受一个或多个输入,处理 他们然后返回一个输出.神经元可以实时,错误驱动的学习,神经元可以通过一个训练样本不断的更新参数,而非一次使用整套的数据.实时学习可能有效的处理

【stanford 机器学习】学习笔记(2)--多变量线性回归(Linear Regression with Multiple Variables)

课程来自斯坦福大学吴恩达教授 machine learning: https://www.coursera.org/learn/machine-learning/home/welcome 多变量线性回归主要包括以下部分: 1) Multiple features(多维特征) 2) Gradient descent for multiple variables(梯度下降在多变量线性回归中的应用) 3) Gradient descent in practice I: Feature Scaling(

Python scikit-learn机器学习工具包学习笔记:feature_selection模块

sklearn.feature_selection模块的作用是feature selection,而不是feature extraction. Univariate feature selection:单变量的特征选择 单变量特征选择的原理是分别单独的计算每个变量的某个统计指标,根据该指标来判断哪些指标重要.剔除那些不重要的指标. sklearn.feature_selection模块中主要有以下几个方法: SelectKBest和SelectPercentile比较相似,前者选择排名排在前n个

《机器学习》学习笔记(二):神经网络

在解决一些简单的分类问题时,线性回归与逻辑回归就足以应付,但面对更加复杂的问题时(例如对图片中车的类型进行识别),运用之前的线性模型可能就得不到理想的结果,而且由于更大的数据量,之前方法的计算量也会变得异常庞大.因此我们需要学习一个非线性系统:神经网络. 我在学习时,主要通过Andrew Ng教授提供的网络,而且文中多处都有借鉴Andrew Ng教授在mooc提供的资料. 转载请注明出处:http://blog.csdn.net/u010278305 神经网络在解决一些复杂的非线性分类问题时,相