# 决策树--从原理到实现

================================================================================

================================================================================

# 一.引入

(不同特征的决策，图片来自【1】)

## O-信息论的一些point：

然后加入一个叫信息增益的东西：
□.信息增益：(information gain)
g(D,A) = H(D)-H(D|A)
表示了特征A使得数据集D的分类不确定性减少的程度
□.信息增益比：(information gain ratio)
g‘(D,A)=g(D,A) / H(D)
□.基尼指数：

# 二.各种算法

## 1.ID3

ID3算法就是对各个feature信息计算信息增益，然后选择信息增益最大的feature作为决策点将数据分成两部分

然后再对这两部分分别生成决策树。

图自【1】

## 2.C4.5

C4.5与ID3相比其实就是用信息增益比代替信息增益，应为信息增益有一个缺点：

信息增益选择属性时偏向选择取值多的属性

算法的整体过程其实与ID3差异不大：图自【2】

## 3.CART

CART(classification and regression tree)的算法整体过程和上面的差异不大，然是CART的决策是二叉树的

# 三.代码及实现

好吧，其实我就想贴贴代码而已……本代码在https://github.com/justdark/dml/tree/master/dml/DT

纯属toy~~~~~实现的CART算法：

from __future__ import division
import numpy as np
import scipy as sp
import pylab as py
def pGini(y):
ty=y.reshape(-1,).tolist()
label = set(ty)
sum=0
num_case=y.shape[0]
#print y
for i in label:
sum+=(np.count_nonzero(y==i)/num_case)**2
return 1-sum

class DTC:
def __init__(self,X,y,property=None):
'''
this is the class of Decision Tree
X is a M*N array where M stands for the training case number
N is the number of features
y is a M*1 vector
property is a binary vector of size N
property[i]==0 means the the i-th feature is discrete feature,otherwise it's continuous
in default,all feature is discrete

'''
'''
I meet some problem here,because the ndarry can only have one type
so If your X have some string parameter,all thing will translate to string
in this situation,you can't have continuous parameter
so remember:
if you have continous parameter,DON'T PUT any STRING IN X  !!!!!!!!
'''
self.X=np.array(X)
self.y=np.array(y)
self.feature_dict={}
self.labels,self.y=np.unique(y,return_inverse=True)
self.DT=list()
if (property==None):
self.property=np.zeros((self.X.shape[1],1))
else:
self.property=property

for i in range(self.X.shape[1]):
self.feature_dict.setdefault(i)
self.feature_dict[i]=np.unique(X[:,i])

if (X.shape[0] != y.shape[0] ):
print "the shape of X and y is not right"

for i in range(self.X.shape[1]):
for j in self.feature_dict[i]:
pass#print self.Gini(X,y,i,j)
pass

def Gini(self,X,y,k,k_v):
if (self.property[k]==0):
#print X[X[:,k]==k_v],'dasasdasdasd'
#print X[:,k]!=k_v
c1 = (X[X[:,k]==k_v]).shape[0]
c2 = (X[X[:,k]!=k_v]).shape[0]
D = y.shape[0]
return c1*pGini(y[X[:,k]==k_v])/D+c2*pGini(y[X[:,k]!=k_v])/D
else:
c1 = (X[X[:,k]>=k_v]).shape[0]
c2 = (X[X[:,k]<k_v]).shape[0]
D = y.shape[0]
#print c1,c2,D
return c1*pGini(y[X[:,k]>=k_v])/D+c2*pGini(y[X[:,k]<k_v])/D
pass
def makeTree(self,X,y):
min=10000.0
m_i,m_j=0,0
if (np.unique(y).size<=1):

return (self.labels[y[0]])
for i in range(self.X.shape[1]):
for j in self.feature_dict[i]:
p=self.Gini(X,y,i,j)
if (p<min):
min=p
m_i,m_j=i,j

if (min==1):
return (y[0])
left=[]
righy=[]
if (self.property[m_i]==0):
left = self.makeTree(X[X[:,m_i]==m_j],y[X[:,m_i]==m_j])
right = self.makeTree(X[X[:,m_i]!=m_j],y[X[:,m_i]!=m_j])
else :
left = self.makeTree(X[X[:,m_i]>=m_j],y[X[:,m_i]>=m_j])
right = self.makeTree(X[X[:,m_i]<m_j],y[X[:,m_i]<m_j])
return [(m_i,m_j),left,right]
def train(self):
self.DT=self.makeTree(self.X,self.y)
print self.DT

def pred(self,X):
X=np.array(X)

result = np.zeros((X.shape[0],1))
for i in range(X.shape[0]):
tp=self.DT
while ( type(tp) is  list):
a,b=tp[0]

if (self.property[a]==0):
if (X[i][a]==b):
tp=tp[1]
else:
tp=tp[2]
else:
if (X[i][a]>=b):
tp=tp[1]
else:
tp=tp[2]
result[i]=self.labels[tp]
return result
pass


这个maketree让我想起了线段树………………代码里的变量基本都有说明

from __future__ import division
import numpy as np
import scipy as sp
from dml.DT import DTC
X=np.array([
[0,0,0,0,8],
[0,0,0,1,3.5],
[0,1,0,1,3.5],
[0,1,1,0,3.5],
[0,0,0,0,3.5],
[1,0,0,0,3.5],
[1,0,0,1,3.5],
[1,1,1,1,2],
[1,0,1,2,3.5],
[1,0,1,2,3.5],
[2,0,1,2,3.5],
[2,0,1,1,3.5],
[2,1,0,1,3.5],
[2,1,0,2,3.5],
[2,0,0,0,10],
])

y=np.array([
[1],
[0],
[1],
[1],
[0],
[0],
[0],
[1],
[1],
[1],
[1],
[1],
[1],
[1],
[1],
])
prop=np.zeros((5,1))
prop[4]=1
a=DTC(X,y,prop)
a.train()
print a.pred([[0,0,0,0,3.0],[2,1,0,1,2]])


# 四.reference

【1】：《机器学习》 -mitchell，卡耐基梅龙大学
【2】：《统计学习方法》-李航

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客