赞
踩
什么是决策树?
分类决策树模型是一种描述对实例进行分类的树形结构。决策树由结点和有向边组成。结点有两种类型:内部结点和叶节点。内部结点表示一个特征或属性,叶节点表示一个类
特征选择
特征选择决定了使用哪些特征来做判断。在训练数据集中,每个样本的属性可能有很多个,不同属性的作用有大有小。因而特征选择的作用就是筛选出跟分类结果相关性较高的特征,也就是分类能力较强的特征。
在特征选择中通常使用的准则是:信息增益。
决策树生成
选择好特征后,就从根节点触发,对节点计算所有特征的信息增益,选择信息增益最大的特征作为节点特征,根据该特征的不同取值建立子节点;对每个子节点使用相同的方式生成新的子节点,直到信息增益很小或者没有特征可以选择为止。
决策树剪枝
剪枝的主要目的是对抗「过拟合」,通过主动去掉部分分支来降低过拟合的风险。
ID3 算法
ID3 是最早提出的决策树算法,他就是利用信息增益来选择特征的。
C4.5 算法
他是 ID3 的改进版,他不是直接使用信息增益,而是引入“信息增益比”指标作为特征的选择依据。
CART(Classification and Regression Tree)
这种算法即可以用于分类,也可以用于回归问题。CART 算法使用了基尼系数取代了信息熵模型。
1.信息熵
Ent(D)的值越小,则D的纯度越高
计算信息熵时约定:若p = 0,则plog2p=0
Ent(D)的最小值为0,最大值为log2|y|
2.信息增益
离散属性a有V个可能的取值{a1, a2, ..., aV},用a来进行划分,则会产生V个分支结点,其中第v个分支结点包含了D中所有在属性a上取值为av的样本,记为Dv。则可计算出用属性a对样本集D进行划分所获得的“信息增益”:
1.增益率
信息增益的缺点在于对取值数目较多的属性有所偏好
C4.5决策树算法不直接使用信息增益,而是使用增益率(gain ratio)来选择最优划分属性,用公式表述为:
其中,G a i n ( D , a ) 同上文中的信息增益,
被称为特征a的固有值,属性a的取值越多 IV(a)的值越大,Gain_ration越小
CART决策树与前面两个都不同,它采用基尼指数划分属性,计算公式如下
∣y∣表示类别个数
当做二分类时,公式可以简化为:
数据集使用西瓜数据集2.0
数据集链接
链接:https://pan.baidu.com/s/1trGDz9M1BT6reFzfXeEzkQ
提取码:6666
ID3决策树基础代码实现
根据决策树算法,可知I3D决策树的算法流程如下:
先根据最大信息增益选取一个特征作为根节点
以根节点特征的取值作为分支递归生成节点,在递归中注意:
每次取特征值时需要删除之前取过的数据
当当前样本只有一类时,返回该类别作叶子结点,即分类结果
当当前所有样本的特征值都一样时,选样本最多的类作为叶子结点
使用测试特征测试决策树预测能力
- import pandas as pd
- import numpy as np
-
- #计算信息熵
- def cal_information_entropy(data):
- data_label = data.iloc[:,-1]
- label_class =data_label.value_counts() #总共有多少类
- Ent = 0
- for k in label_class.keys():
- p_k = label_class[k]/len(data_label)
- Ent += -p_k*np.log2(p_k)
- return Ent
-
- #计算给定数据属性a的信息增益
- def cal_information_gain(data, a):
- Ent = cal_information_entropy(data)
- feature_class = data[a].value_counts() #特征有多少种可能
- gain = 0
- for v in feature_class.keys():
- weight = feature_class[v]/data.shape[0]
- Ent_v = cal_information_entropy(data.loc[data[a] == v])
- gain += weight*Ent_v
- return Ent - gain
-
- #获取标签最多的那一类
- def get_most_label(data):
- data_label = data.iloc[:,-1]
- label_sort = data_label.value_counts(sort=True)
- return label_sort.keys()[0]
-
- #挑选最优特征,即信息增益最大的特征
- def get_best_feature(data):
- features = data.columns[:-1]
- res = {}
- for a in features:
- temp = cal_information_gain(data, a)
- res[a] = temp
- res = sorted(res.items(),key=lambda x:x[1],reverse=True)
- return res[0][0]
-
- ##将数据转化为(属性值:数据)的元组形式返回,并删除之前的特征列
- def drop_exist_feature(data, best_feature):
- attr = pd.unique(data[best_feature])
- new_data = [(nd, data[data[best_feature] == nd]) for nd in attr]
- new_data = [(n[0], n[1].drop([best_feature], axis=1)) for n in new_data]
- return new_data
-
- #创建决策树
- def create_tree(data):
- data_label = data.iloc[:,-1]
- if len(data_label.value_counts()) == 1: #只有一类
- return data_label.values[0]
- if all(len(data[i].value_counts()) == 1 for i in data.iloc[:,:-1].columns): #所有数据的特征值一样,选样本最多的类作为分类结果
- return get_most_label(data)
- best_feature = get_best_feature(data) #根据信息增益得到的最优划分特征
- Tree = {best_feature:{}} #用字典形式存储决策树
- exist_vals = pd.unique(data[best_feature]) #当前数据下最佳特征的取值
- if len(exist_vals) != len(column_count[best_feature]): #如果特征的取值相比于原来的少了
- no_exist_attr = set(column_count[best_feature]) - set(exist_vals) #少的那些特征
- for no_feat in no_exist_attr:
- Tree[best_feature][no_feat] = get_most_label(data) #缺失的特征分类为当前类别最多的
-
- for item in drop_exist_feature(data,best_feature): #根据特征值的不同递归创建决策树
- Tree[best_feature][item[0]] = create_tree(item[1])
- return Tree
-
- #{'纹理': {'清晰': {'根蒂': {'蜷缩': 1, '稍蜷': {'色泽': {'青绿': 1, '乌黑': {'触感': {'硬滑': 1, '软粘': 0}}}}, '硬挺': 0}}, '稍糊': {'触感': {'软粘': 1, '硬滑': 0}}, '模糊': 0}}
-
- def predict(Tree, test_data):
- first_feature = next(iter(Tree))
- second_dict = Tree[first_feature]
- input_first = test_data.get(first_feature)
- if input_first is None:
- return None # 返回一个适当的默认值,表示无法进行分类
- input_value = second_dict.get(input_first)
- if input_value is None:
- return None # 返回一个适当的默认值,表示无法进行分类
- if isinstance(input_value, dict): #判断分支还是不是字典
- class_label = predict(input_value, test_data)
- else:
- class_label = input_value
- return class_label
-
- if __name__ == '__main__':
- #读取数据
- data = pd.read_csv(r'C:\Users\zhoutao\Desktop\data_word.csv')
-
- #统计每个特征的取值情况作为全局变量
- column_count = dict([(ds, list(pd.unique(data[ds]))) for ds in data.iloc[:, :-1].columns])
-
- #创建决策树
- dicision_Tree = create_tree(data)
- print(dicision_Tree)
- #测试数据
- test_data_1 = {'色泽': '青绿', '根蒂': '蜷缩', '敲声': '浊响', '纹理': '稍糊', '脐部': '凹陷', '触感': '硬滑'}
- test_data_2 = {'色泽': '乌黑', '根蒂': '稍蜷', '敲声': '浊响', '纹理': '清晰', '脐部': '凹陷', '触感': '硬滑'}
-
- result = predict(dicision_Tree, test_data_2)
- if result is None:
- print('无法分类')
- else:
- print('分类结果为' + '好瓜' if result == 1 else '坏瓜')
c4.5决策树基础代码实现
基本上和ID3一样只是特征选取部分需要修改
原先的代码(将以下的代码修改即可)
- #获取标签最多的那一类
- def get_most_label(data):
- data_label = data.iloc[:,-1]
- label_sort = data_label.value_counts(sort=True)
- return label_sort.keys()[0]
-
- #挑选最优特征,即信息增益最大的特征
- def get_best_feature(data):
- features = data.columns[:-1]
- res = {}
- for a in features:
- temp = cal_information_gain(data, a)
- res[a] = temp
- res = sorted(res.items(),key=lambda x:x[1],reverse=True)
- return res[0][0]
-
-
这是修改好的代码
- def cal_gain_ratio(data , a):
- #先计算固有值intrinsic_value
- IV_a = 0
- feature_class = data[a].value_counts() # 特征有多少种可能
- for v in feature_class.keys():
- weight = feature_class[v]/data.shape[0]
- IV_a += -weight*np.log2(weight)
- gain_ration = cal_information_gain(data,a)/IV_a
- return gain_ration
-
- #获取标签最多的那一类
- def get_most_label(data):
- data_label = data.iloc[:,-1]
- label_sort = data_label.value_counts(sort=True)
- return label_sort.keys()[0]
-
- #挑选最优特征,即在信息增益大于平均水平的特征中选取增益率最高的特征
- def get_best_feature(data):
- features = data.columns[:-1]
- res = {}
- for a in features:
- temp = cal_information_gain(data, a)
- gain_ration = cal_gain_ratio(data,a)
- res[a] = (temp,gain_ration)
- res = sorted(res.items(),key=lambda x:x[1][0],reverse=True) #按信息增益排名
- res_avg = sum([x[1][0] for x in res])/len(res) #信息增益平均水平
- good_res = [x for x in res if x[1][0] >= res_avg] #选取信息增益高于平均水平的特征
- result =sorted(good_res,key=lambda x:x[1][1],reverse=True) #将信息增益高的特征按照增益率进行排名
- return result[0][0] #返回高信息增益中增益率最大的特征
增益率会对可取值数目较小的特征有偏好,为了避免这个问题,C4.5并不是直接使用增益率的大小进行划分特征,而是先从候选划分特征中找出信息增益高于平均水平的属性,再从中选择增益率最高的那个特征
周志华《机器学习》
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。