如何构造决策树?
-
通过对不同特征的优先选择
-
通过信息增益来量化评价一个信息的好坏
什么是信息增益?
-
在信息学里面,熵是对不确定性的度量。1948年,香农引入了信息熵,将其定义为离散随机事件出现的概率,一个系统越是有序,信息熵就越低,反之一个系统越是混乱,它的信息熵就越高。所以信息熵可以被认为是系统有序化程度的一个度量。
-
信息增益:选择某个特征作为决策标准,整个信息系统熵值的减少量。系统划分前后熵值之差。
信息熵如何计算?
-
假设一个随机变量的频率为
那么,系统的熵定义为
-
计算得信息熵:
-
划分后,数据被分成三部分,那么各个分支的信息熵计算如下:
-
划分后的整体信息熵:
具体算法
-
计算信息熵
-
计算未被使用过的特征的信息增益
-
选取最大的信息增益的特征进行划分
-
从特征集合中删去该特征
-
根据3中的划分构造子树
-
判断每一个子树中的每个例子结果是否一致或者只有一个结果,是则构造完成,不是则递归构造子树。
具体代码
from math import log
import copy
#data_input
def input_Data():
init_data=[
[0,0,0,'no'],[0,0,1,'yes'],[0,1,0,'yes'],[0,1,1,'yes'],[1,0,0,'yes'],[1,0,1,'yes'],[1,1,0,'yes'],[1,1,1,'no']
]
data_labels=['feature_A','feature_B','feature_C']
return init_data,data_labels
Mydata,labels=input_Data()
print(Mydata)
print(labels)
data_len=len(init_data)
result_list=[rows[-1] for rows in init_data]
result_new_list=list(set(result_list))
entropy=0
for x in result_new_list:
pi=float(result_list.count(x))/data_len
entropy-=pi*log(pi,2)
return entropy
Mydata,labels=input_Data()
c=calc_Entropy(Mydata)
print(c)
result_list=[rows[-1] for rows in Mydata]
print(result_list)
init_data_copy=copy.deepcopy(init_data)
new_data=[]
for rows in init_data_copy:
if rows[feature_num]==feature_value:
del rows[feature_num]
new_data.append(rows)
return new_data
Mydata,labels=input_Data()
print(split_Data(Mydata,1,0))
def choose_Feature(init_data):
total_feature_num = len(init_data[1]) - 1
best_info_gain = 0
best_feature_axis = 0
for t in range(total_feature_num):
sub_entropy = 0
featValue_list = []
for q in init_data:
featValue_list.append(q[t]) # featValue_list = [q[t] for q in init_data]
uni_featValue_list = set(featValue_list)
for r in uni_featValue_list: # 计算当前特征下的信息增益
sub_data = split_Data(init_data,t,r)
sub_entropy += (len(sub_data) / float(len(init_data))) * calc_Entropy(sub_data)
info_gain = calc_Entropy(init_data) - sub_entropy
if info_gain > best_info_gain: # 比较不同特征下的信息增益,选出最佳特征位置值
best_info_gain = info_gain
best_feature_axis = t
return best_feature_axis
# test choose_Feature()-----------------------
Mydata,lables = input_Data()
a = choose_Feature(Mydata)
print('best_feature_axis = ',a)
result_list = [x[-1] for x in data] # 递归终止标准
if result_list.count(result_list[-1]) == len(result_list):
return result_list[-1]
best_feature_axis = choose_Feature(data)
best_feature = lables[best_feature_axis]
tree = {best_feature:{}} # 构建树,字典的value作为下次递归的树
lables.remove(best_feature) # 删除已经构建过树的特征
feature_value = [n[best_feature_axis] for n in data]
uni_feature_value = set(feature_value)
for value in uni_feature_value:
sub_lables = lables[:]
tree[best_feature][value] = creat_tree(split_Data(data,best_feature_axis,value),sub_lables)
return tree
Mydata,labels=input_Data()
creat_tree(Mydata,lables)