from math import log
import numpy as np
import pandas as pd
import collections
file_name=("D:\\python_text\\edit.csv")
#加载数据集
def loadDataSet(file_name):
data_x = pd.read_csv(file_name,encoding='gbk',usecols=[0,1,2,3]) #只读取前四列,最后一列是因变量
data_y = pd.read_csv(file_name,encoding='gbk',usecols=[4]) #打印最后一行作为因变量
X_array=np.mat(data_x) #将csv中的数据读成一个矩阵,且第一行的标签也没有打印,有点神奇
y_array=np.mat(data_y)
return X_array,y_array
#######为了使矩阵转换成数组############
def flatten(x):
result = []
for el in x:
if isinstance(x, collections.Iterable) and not isinstance(el, str):
result.extend(flatten(el))
else:
result.append(el)
return result
#定义熵函数
def entropy(predict):
size=len(predict)
entropy_H=0 #用来存储熵值
key={} #存储其概率
for x in predict:
if x not in key.keys():
key[x]=0 #创建key值
key[x]+=1 #进行计数
for K in key:
prob=float(key[K])/float(size)
entropy_H+=prob*log(prob,2)
return -entropy_H
data_x,data_y=loadDataSet(file_name)
Data=np.c_[data_x,data_y] #合并之后的数据
def condition_entropy(predict,response):
size=len(predict)
con_H=0 #条件熵
key={} #存储其概率
num={} #计算predict每个类别的数量
for pre_x,y_resp in zip(predict,response):
key_resp={}
if pre_x not in key.keys():
key[pre_x]=key_resp
num[pre_x]=0
num[pre_x]+=1
if y_resp not in key[pre_x].keys():
key[pre_x][y_resp]=0
key[pre_x][y_resp]+=1
for x in key:
entropy_H=0 #用来存储条件熵值
for y in key[x]:
prob=float(key[x][y])/float(num[x])
entropy_H+=prob*log(prob,2) #计算response在predict中的总数
con_H+=(float(num[x])/float(size))*entropy_H
return -con_H
#信息增益
def grow_entropy(predict,response):
x=entropy(response)
y=condition_entropy(predict,response)
return x-y
#################分离数据集###################
def split_DataSet(col,_data): #_data是引用
key={} #每一列的类别
split_set=[]
for x in range(_data.shape[0]):
label=_data[x,col]
if label not in key.keys():
row_list=[]
key[label]=row_list
key[label].append(x) #把该类标签的某一行添加进去
for K in key:
for row in key[K]:
split_set.append(flatten(_data[row,:].tolist()))
po1=np.delete(_data,key[K],axis=0)
break #每次只删除一个类别
return np.mat(split_set),po1
###########构建决策树#############
def BuildTree(data):
key={}
for label in flatten(data[:,-1].tolist()):
if label not in key.keys():
key[label]=0
if(len(key)==1):
return key.keys()
elif(data.shape[1]==1):
col_key={}
for label in data[:,0]:
if label not in col_key.keys():
col_key[label]=0
col_key[label]+=1
HAHA=max(zip(col_key.values(),col_key.keys()))
return HAHA
else:
print(data)
entropy_list={} #用来存储每一次的信息增益
for col in range(data.shape[1]-1): #表示每次需要计算几个预测变量
entropy_list[col]=grow_entropy(flatten(data[:,col].tolist()),flatten(data[:,-1].tolist()))
max_col=max(zip(entropy_list.values(),entropy_list.keys())) #一个元组
print("dagdg",max_col)
if(max_col[0]<0.1): #如果信息增益小于阈值,则返回最大类
T_key={}
for label in data[:,max_col[1]]:
if label not in T_key.keys():
T_key[label]=0
T_key[label]+=1
print(len(T_key))
HAHA=max(zip(T_key.values(),T_key.keys()))
return HAHA
else:
po,po1=split_DataSet(max_col[1],data)
po1=np.delete(po1,max_col[1],axis=1)
po=np.delete(po,max_col[1],axis=1) #删除那一列,递归进行下一次
print("######")
print("po",po)
print("po1",po1)
BuildTree(po)
BuildTree(po1)
BuildTree(Data)
统计学习方法中给的例子可以正确编译,没有试过其他的例子,也没有可视化,python刚用