决策树(Decision Tree)

决策树就是一系列的if-then语句

决策树的学习包括三个步骤:特征选择,决策树的生成和决策树的修剪

特征选择:主要看用该特征进行分类的结果与随机分类的结果有没有很大差距

常见方法:信息增益,信息增益比,基尼指数

基尼指数:来自集合中的某种结果随机应用于集合中某一数据项的预期误差率
在分类问题中,假设有k个类,样本点属于第k类的概率为Pk,则概率分布的基尼指数定义为Gini(k)=sum(Pk * (1 - Pk)) = 1 - sum(Pk * Pk) (k=1,2,3,,,,K)
对于给定的样本集合D,则基尼指数为 Gini(D) = 1 - sum(Ck/D)*(Ck/D)(k=1,2,3,,,,K)
Ck是D中属于第K类的样本子集,K是类的个数
基尼指数值越大,样本集合的不确定性也就越大

熵:代表的是集合的混杂程度
H(x)=-sum(Pi * log(Pi)) (i=1,2,,,n)
熵越大,随机变量的不确定性也就越大

两者的区别:熵达到峰值的过程要缓慢一些,因此,对于混乱集合的“惩罚”更重一些
实际中多使用熵

决策树的生成:

采用递归方式构造树
为了判断一个属性的好坏,首先算出整个群主的熵,然后 尝试利用每个属性的可能取值对群组进行划分,求出两个新组的熵,为了确定最佳的属性,引入**信息增益**,就是当前熵与两个新组的加权平均之后的熵之间的差值,算法针对每个属性计算相应的信息增益,然后选择最大的属性。对于每个分支,算法需要判断是否需要进一步的划分,

决策树的剪枝

考虑到可能出现“过拟合”,需要对决策树进行修剪,剪枝的过程,对具有相同父节点的一组节点进行分析,判断如果将其合并,熵的增加量是否会小于指定的阈值,如果是这样,则进行合并,合并后的新节点包括了所有可能的值
在根节点调用剪枝函数,沿着树的所有路径向下遍历到只含叶节点的节点处,函数会将两个叶节点的合起来形成一个新的列表,同时,对熵进行测试,如果熵的变化小于阈值,叶节点会被删除,并且相应的结果值会被移到父节点。之后,合并而成的新节点也可能成为删除对象,以及与其他节点的合并对象。

决策树具有处理缺失数据的能力

对于数值型结果,使用方差作为评价函数取代熵 ,若方差较小,代表数字彼此很接近,偏高的方差意味数字分散的很开,在选择节点判断条件的依据就变成了:数字较大的位于树的一侧,数字较小的位于树的另一侧

决策树的目标:以损失函数为目标函数的最小化

一旦有了决策树,只要沿着树的路径一直向下,正确的回答每个问题,就会得到答案。

决策树的实例应用:

预测注册用户
为了预测一位用户成为付费顾客的可能性有多大,可以利用贝叶斯分类器或者神经网络完成这一功能(待学习)
这里强调的是清晰直观,如果知道哪些元素可以表明用户将会成为付费顾客,就可以利用这些元素指导广告策略工作,让网站的某些功能有更好的可用性,或者采取其他措施增加付费用户顾客数量。
为了减少用户的工作量,使其能够尽快的注册账号,网站不会过多的询问用户的个人信息,相反,它从服务器的日志中收集这些信息,比如:用户来自哪个网站,所在的地理位置,以及他们在注册之前曾经浏览过哪些网页等等

# -*- coding: utf-8 -*- 
"""
Created on Fri Apr 22 15:10:32 2016
"""
my_data=[['slashdot','USA','yes',18,'None'],
['google','France','yes',23,'Premium'],
['digg','USA','yes',24,'Basic'],
['kiwitobes','France','yes',23,'Basic'],
['google','UK','no',21,'Premium'],
['(direct)','New Zealand','no',12,'None'],
['(direct)','UK','no',21,'Basic'],
['google','USA','no',24,'Premium'],
['slashdot','France','yes',19,'None'],
['digg','USA','no',18,'None'],
['google','UK','no',18,'None'],
['kiwitobes','UK','no',19,'None'],
['digg','New Zealand','yes',12,'Basic'],
['slashdot','UK','no',21,'None'],
['google','UK','yes',18,'Basic'],
['kiwitobes','France','yes',19,'Basic']]
#define the treenode
class decisionnode:
def __init__(self, col = -1 ,value=None,results=None,tb=None,fb=None):
self.col=col
self.value=value
self.results=results
self.tb=tb
self.fb=fb
def dividset(rows,column,value):
split_function=None
if isinstance(value,int) or isinstance(value,float):
split_function=lambda row:row[column]>=value
else:
split_function=lambda row:row[column]==value
set1=[row for row in rows if split_function(row)]
set2=[row for row in rows if not split_function(row)]
return set1,set2
set1,set2=dividset(my_data,2,'yes')
for row in set1:
print row[-1]
print "-----------"
def uniquecounts(rows):
results={}
for row in rows:
r=row[-1]
if r in results:
results[r]+=1
else:
results[r]=1
return results
res=uniquecounts(set1)
for key,value in res.items():
print key,value
print "--------------------------"
def giniimpurity(rows):
total = len(rows)
imp=0
res=uniquecounts(rows)
for k1 in res:
p1=res[k1]*1.0/total
for k2 in res:
if k1==k2: continue
p2=res[k2]*1.0/total
imp+=p1*p2
return imp
print giniimpurity(my_data)
def entropy(rows):
from math import log
log2=lambda x:log(x)/log(2)
res=uniquecounts(rows)
total=len(rows)
entro=0.0
for k in res:
p=res[k]*1.0/total
entro=entro-p*log2(p)
return entro
print entropy(my_data)
def buildtree(rows,scoref=entropy):
if len(rows)==0: return decisionnode()
current_score=scoref(rows)
# Set up some variables to track the best criteria
best_gain=0.0
best_criteria=None
best_sets=None
column_count=len(rows[0])-1
for col in range(0,column_count):
# Generate the list of different values in
# this column
column_values={}
for row in rows:
column_values[row[col]]=1
# Now try dividing the rows up for each value
# in this column
for value in column_values.keys():
(set1,set2)=dividset(rows,col,value)
# Information gain
p=float(len(set1))/len(rows)
gain=current_score-p*scoref(set1)-(1-p)*scoref(set2)
if gain>best_gain and len(set1)>0 and len(set2)>0:
best_gain=gain
best_criteria=(col,value)
best_sets=(set1,set2)
# Create the sub branches
if best_gain>0:
trueBranch=buildtree(best_sets[0])
falseBranch=buildtree(best_sets[1])
return decisionnode(col=best_criteria[0],value=best_criteria[1],
tb=trueBranch,fb=falseBranch)
else:
return decisionnode(results=uniquecounts(rows))
tree=buildtree(my_data)
def classify(observation,tree):
if tree.results!=None:
return tree.results
else:
v=observation[tree.col]
branch=None
if isinstance(v,int) or isinstance(v,float):
if v>=tree.value: branch=tree.tb
else: branch=tree.fb
else:
if v==tree.value: branch=tree.tb
else: branch=tree.fb
return classify(observation,branch)
print classify(['(direct)','USA','yes',5],tree)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值