决策树的学习与总结

决策树的概念

废话不多说,决策树的三个问题分别是,特征选择,生成和剪枝问题。

  1. 特征选择
    选择某个特征之后划分样本集会带来信息增益,会使得确定类别的不确定性下降。
    g(D, A)=H(D)-H(D|A)
    信息熵计算公式:
    H(D)=k=1KCkDlog2CkDH(D)=-\sum_{k=1}^{K} \frac{\left|C_{k}\right|}{|D|} \log _{2} \frac{\left|C_{k}\right|}{|D|}
    条件信息熵公式:
    H(DA)=i=1nDiDH(Di)H(D | A)=\sum_{i=1}^{n} \frac{\left|D_{i}\right|}{|D|} H\left(D_{i}\right)
    两个做差就是信息增益。

ID3就采用这种生成的算法,而c4.5采用了信息增益比的方法,避免倾向选择过多属性的特征,从而提高整体的信息增益。

而另一个基尼指数也可以选择特征,用于cart决策与回归
Gini(D)=1k=1K(CkD)2\operatorname{Gini}(D)=1-\sum_{k=1}^{K}\left(\frac{\left|C_{k}\right|}{|D|}\right)^{2}

我的理解是,条件基尼系数作用是经过特征切割过后的基尼系数作用上等价于信息增益。

在回归树的生成过程中,寻找输入的切分变量和最优切分点,划分的依据因为是回归输出值连续,所以选择平方误差或绝对值误差来裁定所以是二叉树。

  1. 剪枝
    防止过拟合,相当于在损失函数上加一个正则项,从叶节点递归的向上对比损失函数,然后剪掉。

代码学习

计算熵的函数

def calc_ent(datasets):
    data_length = len(datasets)
    label_count = {}
    for i in range(data_length):
        label = datasets[i][-1]
        if label not in label_count:
            label_count[label] = 0
        label_count[label] += 1
    ent = -sum([(p / data_length) * log(p / data_length, 2)
                for p in label_count.values()])
    return ent

选择信息增益最大的作为根节点

def info_gain_train(datasets):
    count = len(datasets[0]) - 1
    ent = calc_ent(datasets)
#     ent = entropy(datasets)
    best_feature = []
    for c in range(count):
        c_info_gain = info_gain(ent, cond_ent(datasets, axis=c))
        best_feature.append((c, c_info_gain))
        print('特征({}) - info_gain - {:.3f}'.format(labels[c], c_info_gain))
    # 比较大小
    best_ = max(best_feature, key=lambda x: x[-1])
    return '特征({})的信息增益最大,选择为根节点特征'.format(labels[best_[0]])

递归的建立树

然后用sk-learn实现花分类

#data
def create_data():
    iris = load_iris()
    df = pd.DataFrame(iris.data, columns=iris.feature_names)
    df['label'] = iris.target    df.columns = [
        'sepal length', 'sepal width', 'petal length', 'petal width', 'label'
    ]
    data = np.array(df.iloc[:100, [0, 1, -1]])
    # print(data)
    return data[:, :2], data[:, -1]
    X, y = create_data()
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

导入数据
之后参考文档分类即可
sklearn_dtree

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章