掰开揉碎机器学习系列-决策树(2)-CART决策树
一、CART决策树和ID3决策树的区别在哪里:
区别主要体现在对于连续型特征的处理方式,ID3决策树完全根据特征值等于几,做决策分支,这肯定容易出现很多很多分支,即所谓过拟合。
CART决策树在一定程度上缓解了这个问题,比如对于样本S的特征A的特征值1、2、3、4、5、6,如果是ID3决策树,那么可能会有6个分支,而对于CART决策树,只会有2个分支,如"特征A是否大于3.5",这也就是所谓CART决策树是一个二叉树,他对于连续型特征,只做二分切分。
CART和ID3的另一个区别是,CART使用基尼系数而不是熵,作为判断概率分布是否集中的标准。
二、CART决策树实现:
区别于ID3的主要是两个内容,一个是基尼系数,一个是连续型特征如何做分叉
1、基尼系数:
gini(A = AX) = 1 - sum(p(i) * p(i))
即特征A在取值AX时,1减去各个结果i的概率p(i)的乘积
基尼系数越小,反映概率分布越平稳,应优先作为分叉的特征。
2、连续型特征如何分叉:
对该特征A的所有特征值A1-AN排序,每两个特征值获取平均值,取得N-1个有序平均值,计算每个平均值的样本数据子集的基尼系数,取其中最小者,对所有特征均做此计算,基尼系数最小的特征及其最小基尼系数的平均值,作为分叉条件
如样本S的特征A的特征值1、2、3、4、5、6,并计算得平均值3,.5的样本数据子集的基尼系数最低,特征B的特征值1、2、3、4、5、6,并计算得平均值1,.5的样本数据子集的基尼系数最低,特征C的特征值1、2、3、4、5、6,并计算得平均值2,.5的样本数据子集的基尼系数最低.........最后得出最低基尼系数为特征A的平均值3.5,那么特征A是否大于3.5,作为分叉特征条件。
本例中,离散型特征同样计算基尼系数并和连续型特征一起参与比较,计算方式和ID3一样。
3、实现
#coding: utf8
from numpy import *
import pandas as pd
from math import log
import operator
from treeplot import *
import sysdef vote (dataset):map = {}for data in dataset:if map.has_key(data):map[data] += 1else:map[data] = 1max = -1best = 0for data in map:cnt = map[data]if max < cnt:max = cntbest = datareturn bestdef calcgini (dataset):results = [data[-1] for data in dataset]map = {}for result in results:if map.has_key(result):map[result] += 1else:map[result] = 1gini = 1.0for result in map:cnt = map[result]p = float(cnt) / len(dataset)gini -= p * preturn ginidef splitdata_disper (dataset, i, value):splitdata = []for data in dataset:curvalue = data[i]if curvalue == value:tmp = data[:i]tmp.extend(data[i + 1:])splitdata.append(tmp)return splitdatadef splitdata_contigus (dataset, i, value, flag):splitdata = []for data in dataset:curvalue = data[i]if flag == 0:if curvalue > value:leftpart = data[:i]leftpart.extend(data[i + 1:])splitdata.append(leftpart)else:if curvalue <= value:leftpart = data[:i]leftpart.extend(data[i + 1:])splitdata.append(leftpart)return splitdatadef getaverages (values):sorted_values = sorted(values)averages = []for i in range(len(sorted_values) - 1):average = float(sorted_values[i] + sorted_values[i + 1]) / 2averages.append(average)return averagesdef get_type (data):if type(data).__name__ in ['float', 'int', 'long']:return 1else:return 0def choose_bestfeature (dataset, labels):sum = len(dataset)bestgini = 100000.0bestfeatureidx = -1bestvalue_contigus = 0.0type = 0#遍历每一种特征for i in range(len(labels)):values = [data[i] for data in dataset]type = get_type(values[0])#如果是连续型,首先计算出所有连续特征值的排序后交叉均值#然后按这些均值为界,依次计算不同拆分结果的基尼系数,取基尼系数最小者if type == 1:averages = getaverages(values)mingini_contigus = 100000.0bestvalue = 0.0for average in averages:lesspart = splitdata_contigus(dataset, i, average, 0)lesspart_p = float(len(lesspart)) / sumleftpart_gini = lesspart_p * calcgini(lesspart)morepart = splitdata_contigus(dataset, i, average, 1)morepart_p = float(len(morepart)) / summorepart_gini = morepart_p * calcgini(morepart)gini = leftpart_gini + morepart_giniif gini < mingini_contigus:mingini_contigus = ginibestvalue = averageif mingini_contigus < bestgini:bestfeatureidx = ibestvalue_contigus = bestvaluetype = 1#如果是离散型,直接取基尼系数最小者的特征else:mingini_disper = 100000.0values = set(values)for value in values:otherpart = splitdata_disper(dataset, i, value)p = float(len(otherpart)) / len(dataset)gini = p * calcgini(otherpart)if gini < mingini_disper:mingini_disper = giniif mingini_disper < bestgini:bestfeatureidx = itype = 0#如果是连续性特征作为最优特征,要做二值化,就是根据是否大于最优均值,将标签名称和数据,都做二值化#为什么要做二值化,不是三值化,四值化?因为标准CART决策树是一个二叉树,就是根据每个连续型特征是否大于某值来分叉if type == 1:labels[bestfeatureidx] = labels[bestfeatureidx] + " > " + str(bestvalue_contigus)for data in dataset:curvalue = data[bestfeatureidx]if data[bestfeatureidx] > bestvalue_contigus:data[bestfeatureidx] = 1else:data[bestfeatureidx] = 0return bestfeatureidxdef createtree (dataset, labels):results = [data[-1] for data in dataset]#只剩下一种结果时,if len(results) == results.count(results[0]):return results[0]#只剩下结果没有特征了if len(dataset[0]) == 1:return vote(results)bestfeatureidx = choose_bestfeature(dataset, labels)bestfeature = labels[bestfeatureidx]label = labels[bestfeatureidx]tree = {label:{}}del(labels[bestfeatureidx])bestfeaturevalues = set(data[bestfeatureidx] for data in dataset)for value in bestfeaturevalues:splitdata = splitdata_disper(dataset, bestfeatureidx, value)splitlabels = labels[:]if splitdata == []:continuetree[label][value] = createtree(splitdata, splitlabels)return treedf = pd.read_table('nba.txt', sep = '\t')
#数据源,第一行是标题略过,第一列是球员名字略过
dataset = df.values[0:,1:].tolist()
labels = ['score', 'allscore', 'hitratio', 'threeratio', 'penaltyratio', 'time', 'count ', 'clublevel']
tree = createtree(dataset, labels)
createPlot(tree)
训练样本数据,以NBA球员当前的各方面数据(同时包括连续型和离散型特征),以及自设定的其球员档次等级:
name score allscore hitratio threeratio penaltyratio time count clublevel tag
安东尼-戴维斯 31.6 537 51.9 28.2 81.3 37.2 17 Middle 1.5
拉塞尔-威斯布鲁克 31.2 561 43.5 33.7 81.3 35.4 18 Middleupper 1.5
德玛尔-德罗赞 30.2 483 48.8 25.8 80.9 36.8 16 Middle 2
詹姆斯-哈登 28.9 491 45.9 36.3 83.4 37 17 Middleupper 1.5
德马库斯-考辛斯 28.3 481 47.2 40.8 76.9 33.7 17 Middle 1.5
达米安-利拉德 28.2 536 46.3 36.6 89.6 35.7 19 Middle 2
凯文-杜兰特 27.2 462 57.4 44.6 83.8 34.4 17 upper 1
斯蒂芬-库里 26.7 454 50.2 42.5 92.9 33.3 17 upper 1
伊赛亚-托马斯 26.1 417 43.2 33.6 87.6 33.1 16 lower 2.5
吉米-巴特勒 25.8 413 49 42.6 88.7 35.2 16 Middleupper 1.5
考瓦伊-莱昂纳德 24.8 421 46.2 38.6 92.5 34.2 17 upper 1.5
凯里-欧文 24.8 372 49 43.3 84 33.9 15 upper 2
肯巴-沃克 24.5 392 46.9 41.1 79.6 33.4 16 Middle 2.5
勒布朗-詹姆斯 23.6 331 49.8 36.1 74.2 36.1 14 upper 1
安德鲁-维金斯 23.5 376 43 39.1 76.7 36.4 16 Middle 2.5
约翰-沃尔 23.5 305 45.4 38.1 81.6 34.2 13 Middle 2
卡梅罗-安东尼 23 368 45.4 34.7 86.8 33.8 16 Middle 1.5
凯文-勒夫 22.3 335 45.4 43 86.5 31.7 15 upper 1.5
C.J.-迈克科伦姆 22.3 424 47.3 44.5 91 34.6 19 Middle 2.5
吉安尼斯-安特托孔波 22 330 51.4 18.8 78.7 34.7 15 Middle 2
卡尔-安东尼-唐斯 21.1 338 49.1 39.4 71 34.7 16 Middle 2
布雷克-格里芬 21.1 380 48.7 22.2 77.4 33.1 18 upper 1.5
乔治-希尔 20.9 188 55.2 47.1 86.7 32.7 9 Middle 2
克里斯塔普斯-波尔津吉斯 20.9 335 49 40 78.6 33.3 16 Middle 2.5
哈里森-巴恩斯 20.8 332 46 28.6 87.1 37.3 16 Middle 2.5
保罗-乔治 20.8 249 43.9 37.2 93 34.9 12 Middleupper 1.5
运行结果如下:可以发现分叉还是比较多。
掰开揉碎机器学习系列-决策树(2)-CART决策树相关推荐
- 决策树:CART决策树剪枝算法(超详细)
文章目录 CART算法 1. CART生成算法 2. CART剪枝算法 CART剪枝算法流程 CART剪枝算法解析( 超详细 ) CART算法 CART假设决策树是二叉树,内部结点特征的取值为&quo ...
- [机器学习算法]决策树和CART树
决策树综述 决策树的工作原理 决策树(decision tree)分类法是一种简单但广泛使用的分类技术.以是否贷款违约的二分类问题为例,当我们希望根据给定的训练集习得一个模型对新出现的贷款人进行分类时 ...
- 机器学习系列之手把手教你实现一个决策树
https://www.ibm.com/developerworks/cn/analytics/library/machine-learning-hands-on4-decision-tree/ind ...
- 【机器学习基础】数学推导+纯Python实现机器学习算法5:决策树之CART算法
目录 CART概述 回归树 分类树 剪枝 Python实现示例:分类树 在数学推导+纯Python实现机器学习算法4:决策树之ID3算法中笔者已经对决策树的基本原理进行了大概的论述.本节将在上一讲的基 ...
- 机器学习系列文章-决策树
决策树 由于我们是使用sklearn对决策树代码进行实现,所以并不是很关心其原理部分.但我仍需要对其进行一定的了解.通过查询资料,去学习了下决策树的原理,这里对其原理进行简要介绍. 注:这里决策树的原 ...
- 机器学习系列(10)_决策树与随机森林回归
注:本篇文章接上一篇文章>>机器学习系列(9)_决策树详解01 文章目录 一.决策树优缺点 二.泰坦尼克号幸存者案例 三.随机森林介绍 1.随机森林的分类 2.重要参数 [1]n_esti ...
- 【机器学习】 ID3,C4.5,CART决策树
决策树模型在监督学习中非常常见,可用于分类(二分类.多分类)和回归.虽然将多棵弱决策树的Bagging.Random Forest.Boosting等tree ensembel 模型更为常见,但是&q ...
- 机器学习爬大树之决策树(CART与剪枝)
分类与回归树(classification and regression tree,CART)是应用广泛的决策树学习方法,同样由特征选择,树的生成以及剪枝组成,既可以用于分类也可以用于回归.CART假 ...
- 机器学习算法(5)——决策树(ID3、C4.5、CART)
决策树又称为判定树,是运用于分类的一种树结构.决策树(decision tree)是一个树结构(可以是二叉树或非二叉树).其每个非叶节点表示一个特征属性上的测试,每个分支代表这个特征属性在某个值域上的 ...
最新文章
- Silverlight 解谜游戏 之三 消除名单
- c语言发送结构体 文件
- 图解机房空调制冷系统
- Who is the best at Dataset X?
- 33迭代器模式(Iterator Pattern)
- python创建sqlite3数据库_树莓派使用 Python + SQLite 建立温度数据库
- 青岛经济职业学校有计算机专业吗,青岛经济职业学校
- 三大开源生信基础教程和视频课程
- 基础数据类型,注释,变量
- oracle 退出循环 使变量清空,[转]Oracle 清除incident和trace -- ADRCI用法
- 基于MATLAB的语音信号设计,基于MATLAB的语音信号处理系统设计
- c语言自定义函数返回值的作用,C语言自定义函数
- 信息安全基础练习题(看完包过)
- 已知两点, 求直线斜率
- iptv增值服务_什么是IPTV,以及如何启动您自己的IPTV服务?
- erlang使用httpc:request报错nxdomain
- FreeRTOS移植到STM32
- 登录接口已修复梦想贩卖机V2 2.0.4 修复版,附带安装教程。
- Web学习(二)CSS
- 全国所有城市人均GDP排名(包含县级市 611 )
热门文章
- 基于UWB的高精度定位
- 【mysql】关于mysql中int(M)类型的具体含义以及tinyint/smallint/mediumint/int/bigint的区别是什么?
- 关于mqtt协议与终端监测设备相结合应用分析
- 国科大930计算机专业基础真题,国科大
- 局域网架设BT服务器
- resource xml/file_paths (aka com.example.rfidretrofit:xml/file_paths) not found.
- Github重磅教程,从0到1,边学边实战!
- DevExpress 第三方控件汉化
- Java面试接口以及接口调用超时解决方法
- 计算机专业大三上学期课程,武汉工程大学邮电与信息工程学院计算机专业大三下学期课程安排...