数据集处理
数据获取
使用sklearn的dataset获取数据
from sklearn import datasets
from sklearn.model_selection import train_test_split
iris = datasets.load_iris()
iris_feature = iris['data']
iris_target = iris['target']
iris_target_name = iris['target_names']
数据划分
使用sklearn自带的函数将其分割为训练集和测试集
训练集和测试集比例为2:1
为方便比较不同方法的优劣,我们固定随机数种子为10
feature_train, feature_test, target_train, target_test = train_test_split(iris_feature, iris_target, test_size=0.33,random_state=10)
可视化
使用plt对数据进行可视化,数据集展示如下
def show():
t0 = [index for index in range(len(iris_target)) if iris_target[index] == 0]
t1 = [index for index in range(len(iris_target)) if iris_target[index] == 1]
t2 = [index for index in range(len(iris_target)) if iris_target[index] == 2]
plt.rcParams['font.sans-serif'] = ['SimHei'] # 显示中文标签
# plt.rcParams['axes.unicode_minus'] = False
plt.scatter(x=iris_feature[t0, 0], y=iris_feature[t0, 1], color='r', label='Iris-virginica')
plt.scatter(x=iris_feature[t1, 0], y=iris_feature[t1, 1], color='g', label='Iris-setosa')
plt.scatter(x=iris_feature[t2, 0], y=iris_feature[t2, 1], color='b', label='Iris-versicolor')
plt.xlabel("花萼长度")
plt.ylabel("花瓣长度")
plt.title("数据集展示")
plt.show()
方法1 DecisionTree
类定义
为了构建决策树,需要先定义节点类
class Node:
def __init__(self, dimension, threshold, isLeaf, left, right, species):
self.dimension = dimension # 划分维度
self.threshold = threshold # 划分阈值
self.isLeaf = isLeaf # 是否是叶节点
self.left = left # 左支(叶节点时为None)
self.right = right # 右支(叶节点时为None)
self.species = species # 分类(如果是叶节点)
构建决策树
决策树部分,采用CART算法构建决策树,下面将按照依赖关系自底向上介绍结构化方法
基尼值
计算公式为
基尼值越小说明该数据集中不同类的数据越少
pv代表了v类数据在总类中的频率
代码实现如下
def get_gini(label):
"""
计算GINI值
:param label: 数组,里面存的是分类
:return: 返回Gini值
"""
gini = 1
dic = {}
for target in label:
if target in dic.keys():
dic[target] += 1
else:
dic[target] = 1
for value in dic.values():
tmp = value / len(label)
gini -= tmp * tmp
return gini
基尼系数
计算公式如下
因为鸢尾花数据集的属性都是浮点数,为了二分化,我们需要寻找一个阈值,这里采用的方法是枚举所有的划分情况,因此需要做:
排序给定维度下的属性
选取相邻属性值的平均值作为候选阈值,并去重
遍历所有可能的阈值,选取基尼系数最小的划分阈值,返回基尼系数和划分阈值
代码实现如下
def get_gini_index_min(feature, label, dimension):
"""
获取某个维度的最小GiniIndex
:param feature: 所有属性list
:param label: 标记list
:param dimension: 维度(从0开始)
:return: gini_index(最小GiniIndex) threshold(对应阈值)
"""
attr = feature[:, dimension]
gini_index = 1
threshold = 0
attr_sort = sorted(attr)
candicate_thre = []
# 寻找候选阈值
for i in range(len(attr_sort) - 1):
tmp = (attr_sort[i] + attr_sort[i + 1]) / 2
if tmp not in candicate_thre:
candicate_thre.append(tmp)