numpy实现决策树
决策树的原理就是找到易于区分类的特征值进行空间划分,得到最终的分类空间。
import numpy as np
import matplotlib.pyplot as plt
def mid(node):
print(node.index,node.value,node.lay_num,node.att)
if node.flag==0:
mid(node.left)
mid(node.right)
def predict(data,node):
if node.flag==1:
return node.clas
if data[node.index]<=node.value:
return predict(data,node.left)
else:
return predict(data,node.right)
class tree:
def __init__(self,lay_num=0,str="gen"):
self.flag=0
self.index=0
self.value=0
self.clas=0
self.lay_num=lay_num
self.att=str
self.left=None
self.right=None
def ginic(data):
sum=len(data)
sum1=0
sum2=0
for i in range(len(data)):
if data[i,4]==1:
sum1+=1
else:
sum2+=1
p1=0
p2=0
if sum==0:
return 0
if sum1==0:
p1=0
else:
p1=sum1/sum
if sum2==0:
p2=0
else:
p2=sum2/sum
return 1-p1**2-p2**2
def compute(feature,value,data):
d1=[]
d2=[]
for i in range(len(data)):
if data[i,feature]<=value[feature]:
d1.append(data[i])
else:
d2.append(data[i])
d1=np.array(d1)
d2=np.array(d2)
sum1=len(d1)
sum2=len(d2)
sum11=0
sum12=0
sum21=0
sum22=0
for i in range(sum1):
if d1[i,4]==1:
sum11+=1
else:
sum12+=1
for i in range(sum2):
if d2[i,4]==1:
sum21+=1
else:
sum22+=1
p1=0
p2=0
if sum1==0:
p1=0
else:
p1=sum1/len(data)
if sum2==0:
p2=0
else:
p2=sum2/len(data)
gi=p1*ginic(d1)+p2*ginic(d2)
return gi,value[feature]
def gini(index,data):
length=len(data)
min=1000
in_value=0
for i in range(length):
if data[i,index]!=data[0:length,index].max():
gi,da=compute(index,data[i],data)
if min>gi:
min=gi
in_value=da
return min,in_value
def create(data,i,str):
node=tree(lay_num=i,str=str)
node.lay_num=i
k=i
att=np.zeros((4,2))
min=2
flag=0
for i in range(len(data)-1):
if data[i,4]!=data[i+1,4]:
flag=1
if flag==0:
node.flag=1
node.att="leaf"
node.clas=data[0,4]
print(node.clas)
return node
index=0
value=0
for i in range(4):
att[i,0],att[i,1]=gini(i,data)
if min>att[i,0]:
min=att[i,0]
value=att[i,1]
index=i
w1=[]
w2=[]
node.index=index
node.value=value
for i in range(len(data)):
if data[i,index]<=value:
w1.append(data[i])
else:
w2.append(data[i])
w1=np.array(w1)
w2=np.array(w2)
node.left=create(w1,k+1,"left")
node.right=create(w2,k+1,"right")
return node
w=20
train=np.random.randint(-300,300,(w,4))
train=train.astype(float)
train_lable=np.zeros((w,1))
test=np.random.randint(-300,300,(w,4))
traint=train.astype(float)
test_lable=np.zeros((w,1))
for i in range(w):
if 1*train[i,0]+2*train[i,1]+3*train[i,2]+4*train[i,3]-1>0:
train_lable[i]=1
else:
train_lable[i]=-1
if 1*test[i,0]+2*test[i,1]+3*test[i,2]+4*test[i,3]-1>0:
test_lable[i]=1
else:
test_lable[i]=-1
train=np.concatenate((train,train_lable),axis=1)
train=np.array([[1,1,-1,1,1],[2,1,-1,1,1],[3,1,-1,1,1],[4,1,-1,1,1],[5,1,-1,1,1],[-1,-2,-1,1,1],[-1,-3,-1,1,1],[-1,-1,1,1,1],[-1,-1,-1,2,-1],[-1,-1,-1,1,-1]])
test=np.concatenate((test,test_lable),axis=1)
node1=create(train,0,"gen")
acc=0
for i in range(250):
w=predict(test[i],node1)
if w==test[i,4]:
acc+=1
print(acc/250)
print(train)
mid(node1)

浙公网安备 33010602011771号