决策树2

1.信息熵的概念

某个离散随机变量的概率分布为

\[P(X=x_i)=p_i,i=1,2,...,n\tag{1.1} \]

则随机变量\(X\)的熵定义为

\[H(X)=-\sum\limits_{i=1}^{n}p_i\log p_i \tag{1.2} \]

点击查看代码

# 熵的计算
def cal_entropy(pk):
    '''
    the entropy is calculated as S = -sum(pk * log(pk), axis=axis).

    :math:`S=-\sum_{i=1}^{n}(p(x)\log p(x))`

    :param pk:概率分布
    :return:
    '''
    return entropy(pk, base=2)


pk = [1 / 2, 1 / 2]
print(cal_entropy(pk))

点击查看代码

def calc_entropy(sub_labels):
    """
    计算机信息熵
    :param sub_labels:当前选择的数据集对应的类别值,一列
    :return: 信息熵
    """
    x_label_array = np.unique(sub_labels)  # 获取不同类别值:好瓜、坏瓜
    entropy = 0.0  # 信息熵
    for x_label in x_label_array:
        sub_y = sub_labels[sub_labels == x_label]  # 布尔索引取每个类别的样本
        p = len(sub_y) / len(sub_labels)  # 各类别所占样本比例p
        entropy -= p * np.log2(p)  # 信息熵累加
    return entropy


2.条件熵的概念

条件熵\(H(Y|X)\)表示在已知随机变量\(X\)的条件下随机变量\(Y\)的不确定性
随机变量\(X\)在给定条件下随机变量\(Y\)的条件熵\(H(Y|X)\),定义为\(X\)在给定\(Y\)的条件概率分布的熵对\(X\)的数学期望

\[H(Y|X)=\sum\limits_{i=1}^{n}p_iH(Y|X=x_i),p_i=P(X=x_i),i=1,2,...,n \]


\(注意里面的H(Y|X=x_i)是熵,又是一个\sum符号,所以条件熵有两层\sum\)

3.信息增益

\[g(D,A)=H(D)-H(D|A) \]

4.信息增益算法

输入:训练数据集\(D\)和特征\(A\)
输出:特征\(A\)对训练数据集\(D\)的信息增益\(g(D,A)\)

  • 1.计算数据集\(D\)的信息熵\(H(D)\)

\[H(D)=-\sum\limits_{k=1}^{K}\frac{|C_k|}{|D|}\log_2\frac{|C_k|}{|D|} \]


\(注意如果有多个特征,则K=所有特征的离散值数的连乘积,比如有两个特征,特征A有3种可能值,特征B有4种取值,那么理论上最多K=12,绝对值计算代表某一类数据的数据量大小\)

  • 2.计算特征\(A\)对数据集\(D\)的条件熵\(H(D|A)\)

\[H(D|A)=\sum\limits_{i=1}^{n}\frac{|D_i|}{|D|}H(D_i)=-\sum\limits_{i=1}^{n}\frac{|D_i|}{|D|}\sum\limits_{k=1}^{K}\frac{|C_{ik}|}{|D_i|}\log_2\frac{|C_{ik}|}{|D_i|} \]

点击查看代码

def calc_condition_entropy(feature_data, y_labels):
    """
    计算以特征属性feature_data为划分节点的条件熵
    :param feature_data: 递归划分后的样本集,计算某个特征的条件熵,一列
    :param y_labels: 对应某个特征的类别值,一列
    :return: 条件熵
    """
    feature_label_array = np.unique(feature_data)  # 某特征不同的取值,[青绿,乌黑,浅白]
    cond_entropy = 0.0
    for feature_label in feature_label_array:
        sub_y = y_labels[feature_data == feature_label]  # 某特征某个取值所对应的类别值
        feature_ent = calc_entropy(sub_y)  # 某特征某个取值所对应的信息熵
        cond_entropy += len(sub_y) / len(y_labels) * feature_ent
    return cond_entropy

  • 3.计算信息增益

\[g(D,A)=H(D)-H(D|A) \]

5.信息增益比

\[g_R(D,A)=\frac{D,A}{H_A(D)} \]

\(其中H_A(D)=-\sum\limits_{k=1}^{K}\frac{|D_i|}{|D|}\log_2\frac{|D_i|}{|D|},n是特征A的离散值个数\)

6.连续值处理

二分法

将一连续值\(A\)从小到大排序好后进行二分法,比如序列\(\{A^1,A^2,...,A^n\}\),令切分点依次从小到大迭代

\[T_A=\{\frac{A^i+A^{i+1}}{2}|1\le i\le n-1\} \tag{6.1} \]

迭代计算信息增益,挑出信息增益最大的那个划分

\[g(D,A)=max_{t\in T_A}g(D,A,t)=max_{t\in T_A}\ H(D)-\sum\limits_{\lambda \in \{-,+\}}\frac{|D_t^{\lambda}|}{|D|}H(D_t^{\lambda})\tag{6.2} \]


\(注意与离散属性不同,若当前节点划分为连续属性,该属性还可以作为其后代节点的划分属性\)

7.ID3算法

ID3算法的核心是在决策树各个节点上应用信息增益准则选择特征
输入:训练数据集\(D\),特征集\(A\),阈值\(\epsilon\)
输出:决策树\(T\)

  • 1.按照公式1计算\(A\)中各特征对D的信息增益,选择信息增益最大的特征\(A_g\)
  • 2.若\(A_g\)的信息增益小于阈值\(\epsilon\),则返回\(T\),并将\(D\)中实例数最大的类\(C_k\)作为该节点的类标记
  • 3.否则,对\(A_g\)的每一可能值\(a_i\),依照\(A_g=a_i\)\(D\)分割为若干非空子集\(D_i\),将\(D_i\)中实例数最大的类作为标记,构建子节点,由节点及其子节点构成T
  • 4.对\(i\)个子节点,以\(D_i\)作为训练集,以\(A-{A_g}为特征集,递归调用上述步骤\)

案例

性别 学历 年龄 风险级别
M 本科 11
M 大专 29
F 本科 18
F 大专 34
M 大专 19
M 本科 25
F 大专 10
M 本科 33
M 大专 40
  • 1.按照公式1计算\(A\)中各特征对D的信息增益,选择信息增益最大的特征\(A_g\)

\(H(风险)=-\sum\limits_{i=1}^{n}p_i\log p_i=-\frac{4}{9}\log_2\frac{4}{9}-\frac{2}{9}\log_2\frac{2}{9}-\frac{3}{9}\log_2\frac{3}{9}=1.5304930567574826\)

\(H(风险|性别)=-[\frac{4}{9}(\frac{2}{4}\log_2\frac{2}{4}+\frac{2}{4}\log_2\frac{2}{4}) +\frac{2}{9}(\frac{1}{2}\log_2\frac{1}{2}+\frac{1}{2}\log_2\frac{1}{2}) +\frac{3}{9}(\frac{3}{3}\log_2\frac{3}{3})]=0.6666666666666666\)

\(H(风险|学历)=-[\frac{4}{9}(\frac{2}{4}\log_2\frac{2}{4}+\frac{2}{4}\log_2\frac{2}{4}) +\frac{2}{9}(\frac{1}{2}\log_2\frac{1}{2}+\frac{1}{2}\log_2\frac{1}{2}) +\frac{3}{9}(\frac{1}{3}\log_2\frac{1}{3}+\frac{2}{3}\log_2\frac{2}{3})]=0.9727652780181631\)

\(年龄是连续值,排序后为\{(10,高),(11,高),(18,中),(19,低),(25,低),(29,中),(33,高),(34,高),(40,低)\}\)

\(1,8划分\)

性别 学历 年龄 年龄分类 风险级别
M 本科 11 +
M 大专 29 +
F 本科 18 +
F 大专 34 +
M 大专 19 +
M 本科 25 +
F 大专 10 -
M 本科 33 +
M 大专 40 +

\(H(风险|年龄_{1/8})=-[\frac{4}{9}(\frac{3}{4}\log_2\frac{3}{4}+\frac{1}{4}\log_2\frac{1}{4}) +\frac{2}{9}(\frac{2}{2}\log_2\frac{2}{2}) +\frac{3}{9}(\frac{3}{3}\log_2\frac{3}{3})]=0.3605680553151701\)

以此类推

\(H(风险|年龄_{2/7})=-[\frac{4}{9}(\frac{2}{4}\log_2\frac{2}{4}+\frac{2}{4}\log_2\frac{2}{4}) +\frac{2}{9}(\frac{2}{2}\log_2\frac{2}{2}) +\frac{3}{9}(\frac{3}{3}\log_2\frac{3}{3})]=0.4444444444444444\)

\(H(风险|年龄_{3/6})=-[\frac{4}{9}(\frac{2}{4}\log_2\frac{2}{4}+\frac{2}{4}\log_2\frac{2}{4}) +\frac{2}{9}(\frac{1}{2}\log_2\frac{1}{2}+\frac{1}{2}\log_2\frac{1}{2}) +\frac{3}{9}(\frac{3}{3}\log_2\frac{3}{3})]=0.6666666666666666\)

\(H(风险|年龄_{4/5})=-[\frac{4}{9}(\frac{2}{4}\log_2\frac{2}{4}+\frac{2}{4}\log_2\frac{2}{4}) +\frac{2}{9}(\frac{1}{2}\log_2\frac{1}{2}+\frac{1}{2}\log_2\frac{1}{2}) +\frac{3}{9}(\frac{2}{3}\log_2\frac{2}{3}+\frac{1}{3}\log_2\frac{1}{3})]=0.9727652780181631\)

\(H(年龄_{5/4}|风险)=-[\frac{4}{9}(\frac{2}{4}\log_2\frac{2}{4}+\frac{2}{4}\log_2\frac{2}{4}) +\frac{2}{9}(\frac{1}{2}\log_2\frac{1}{2}+\frac{1}{2}\log_2\frac{1}{2}) +\frac{3}{9}(\frac{2}{3}\log_2\frac{2}{3}+\frac{1}{3}\log_2\frac{1}{3})]=0.9727652780181631\)

\(H(风险|年龄_{6/3})=-[\frac{4}{9}(\frac{2}{4}\log_2\frac{2}{4}+\frac{2}{4}\log_2\frac{2}{4}) +\frac{2}{9}(\frac{2}{2}\log_2\frac{2}{2}) +\frac{3}{9}(\frac{2}{3}\log_2\frac{2}{3}+\frac{1}{3}\log_2\frac{1}{3})]=0.7505430557959409\)

\(H(风险|年龄_{7/2})=-[\frac{4}{9}(\frac{3}{4}\log_2\frac{3}{4}+\frac{1}{4}\log_2\frac{1}{4}) +\frac{2}{9}(\frac{2}{2}\log_2\frac{2}{2}) +\frac{3}{9}(\frac{2}{3}\log_2\frac{2}{3}+\frac{1}{3}\log_2\frac{1}{3})]=0.6666666666666666\)

\(H(风险|年龄_{8/1})=-[\frac{4}{9}(\frac{4}{4}\log_2\frac{4}{4}) +\frac{2}{9}(\frac{2}{2}\log_2\frac{2}{2}) +\frac{3}{9}(\frac{2}{3}\log_2\frac{2}{3}+\frac{1}{3}\log_2\frac{1}{3})]=0.3060986113514965\)

即最优划分是\(H(年龄_{8/1}|风险)=0.3060986113514965\)

综上3个维度,信息熵增益最大的是\(H(年龄_{8/1}|风险)\)

\(年龄维度产生两个分支,年龄\ge \frac{40+34}{2}=37的,都是低风险,年龄<37 的继续迭代\)

\( 年龄\begin{cases} \ge 37 & 低风险 \\ <37 & 继续迭代\\ \end{cases} \)

继续迭代第二个维度

性别 学历 风险级别
M 本科
M 大专
F 本科
F 大专
M 大专
M 本科
F 大专
M 本科

注意这里连续值是还可以继续迭代的,这里为了演示方便,不做深入迭代了

\(H(性别|风险)=-[\frac{4}{8}(\frac{2}{4}\log_2\frac{2}{4}+\frac{2}{4}\log_2\frac{2}{4}) +\frac{2}{8}(\frac{1}{2}\log_2\frac{1}{2}+\frac{1}{2}\log_2\frac{1}{2}) +\frac{2}{8}(\frac{2}{2}\log_2\frac{2}{2})]=0.75\)

\(H(风险|学历)=-[\frac{4}{8}(\frac{2}{4}\log_2\frac{2}{4}+\frac{2}{4}\log_2\frac{2}{4}) +\frac{2}{8}(\frac{1}{2}\log_2\frac{1}{2}+\frac{1}{2}\log_2\frac{1}{2}) +\frac{2}{8}(\frac{1}{2}\log_2\frac{1}{2}+\frac{1}{2}\log_2\frac{1}{2})]=1\)

所以选择性别维度,分支1 性别M 迭代,分支2 性别 F 迭代

\( 年龄\begin{cases} \ge 37 & 低风险 \\ <37 & 性别 \begin{cases} M & 继续迭代 \\ F & 继续迭代\\ \end{cases} \end{cases} \)

性别 学历 风险级别
M 本科
M 大专
M 大专
M 本科
M 本科

\(看M这个分支,只有学历这个维度了,计算各自概率\)
\(本科分支,67\%高,33\%低,大专分支,50\%中,50\%低,\)

性别 学历 风险级别
F 本科
F 大专
F 大专

\(看F这个分支,只有学历这个维度了,计算各自概率\)
\(本科分支,中,大专分支,高,\)

\(最后模型如下\)
\( \begin{cases} \ge 37 & 低风险 \\ <37 & \begin{cases} M & \begin{cases} 本科 & 67\%高,33\%低 \\ 大专 & 50\%中,50\%低\\ \end{cases} \\ F & \begin{cases} 本科 & 中 \\ 大专 & 高\\ \end{cases}\\ \end{cases} \end{cases} \)

\(预测数据\)

性别 学历 年龄 风险                 
M 本科 16 \(67\%高,33\%低\)

点击查看代码


每个target_label 对应的样本数量
class_len [(0, 3024), (1, 2831), (2, 230), (3, 2986), (4, 1)]

# 按照数量排序,取含数据量最大的那个类别
max_class, max_len = max(class_len, key=lambda x: x[1])


If # 特征集为空
	投票法,取样本量最大所对应的类别,即叶子节点取  max_class
	Node(LEAF, Class=max_class)
	# 叶子节点,return
Else 特征集不为空
	计算每个特征的信息增益,并选择信息增益最大的特征作为划分节点依据
	if max_gain < epsilon  收益太低
		还是按照投票法,即叶子节点取  max_class
		Node(LEAF, Class=max_class)
		# 叶子节点,return
	else 按照信息增益生成叶子节点
		max_feature, max_gain = 0, 0s
		for feature in features:  # 循环每个特征
			feature_data = train_set.iloc[:, feature] # t
			feature_gain = calc_ent_gain(feature_data, train_lable)
		        if feature_gain > max_gain:
            			max_feature, max_gain = feature, feature_gain
		Node(INTERNAL, best_feature=max_feature)
		# 内部节点,继续递归迭代
		# 递归前先除去已经被选择的特征属性
    		sub_features = list(filter(lambda x: x != max_feature, features)) # 原来可能有n个特征,现在是n-1个特征
		max_feature_col = train_set.iloc[:, max_feature]  # 取出最优特征那一列的所有数据	
		max_feature_unique_values = np.unique(max_feature_col)  # 取出特征所有的离散特征值
		
		#继续循环所有的特征值,添加到当前节点的dict中
		for feature_value in max_feature_unique_values:
        		sub_train_set = train_set[train_set.iloc[:, max_feature] == feature_value]
        		sub_train_label = train_lable[train_set.iloc[:, max_feature] == feature_value]
        		sub_tree = id3_tree_fit(sub_train_set, sub_train_label, sub_features, class_num)
        		tree.add_tree(feature_value, sub_tree)



点击查看代码

import numpy as np
import scipy as sp
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report

epsilon = 1e-3  # 信息增益阀值,小于该阀值,即为叶子节点


def calc_entropy(sub_labels):
    """
    计算机信息熵
    :param sub_labels:当前选择的数据集对应的类别值,一列
    :return: 信息熵
    """
    x_label_array = np.unique(sub_labels)  # 获取不同类别值:好瓜、坏瓜
    entropy = 0.0  # 信息熵
    for x_label in x_label_array:
        sub_y = sub_labels[sub_labels == x_label]  # 布尔索引取每个类别的样本
        p = len(sub_y) / len(sub_labels)  # 各类别所占样本比例p
        entropy -= p * np.log2(p)  # 信息熵累加
    return entropy


def calc_condition_entropy(feature_data, y_labels):
    """
    计算以特征属性feature_data为划分节点的条件熵
    :param feature_data: 递归划分后的样本集,计算某个特征的条件熵,一列
    :param y_labels: 对应某个特征的类别值,一列
    :return: 条件熵
    """
    feature_label_array = np.unique(feature_data)  # 某特征不同的取值,[青绿,乌黑,浅白]
    cond_entropy = 0.0
    for feature_label in feature_label_array:
        sub_y = y_labels[feature_data == feature_label]  # 某特征某个取值所对应的类别值
        feature_ent = calc_entropy(sub_y)  # 某特征某个取值所对应的信息熵
        cond_entropy += len(sub_y) / len(y_labels) * feature_ent
    return cond_entropy


def calc_ent_gain(feature_data, y_labels):
    # 计算某个特征作为划分节点的信息增益
    return calc_entropy(y_labels) - calc_condition_entropy(feature_data, y_labels)


class Node:
    def __init__(self, node_type, Class=None, best_feature=None):
        self.node_type = node_type  # 决策树节点类型(内部节点,叶子节点)
        # 键:最佳信息增益所对应的特征,值:以最佳特征的某个取值为根节点的子树
        self.child_node_dict = dict()
        self.Class = Class  # 叶子节点所对应的列表值,若内部节点则值为None
        self.best_feature = best_feature  # 最佳划分特征

    def add_node(self, key, tree):
        """
        键:最佳信息增益所对应的特征,值:以最佳特征的某个取值为根节点的子树
        :param key: 最佳划分特征 特征值 feature_value
        :param tree: 决策子树
        :return:
        """
        self.child_node_dict[key] = tree

    def predict(self, test_sample):
        """
        递归,根据构建的决策树进行预测
        :param test_sample: 测试样本,单个
        :return: 类别
        """
        if self.node_type == "leaf" or (test_sample[self.best_feature] not in self.child_node_dict):
            return self.Class
        tree = self.child_node_dict.get(test_sample[self.best_feature])
        return tree.predict(test_sample)


def target_encode(y_target):
    """
    对非数值类别进行数值化,不是one-hot编码
    :param y_target: n*1 矩阵,内容是类别值
    :return: n*1 矩阵,类别值对应的数字编码,如5类,则0-4编码
    """
    y_labels = list(set(y_target))
    y_labels_dict = dict()
    for i, label in enumerate(y_labels):
        y_labels_dict[str(float(i))] = label
    y_encode = np.zeros(len(y_target))
    for i, y in enumerate(y_target):
        y_encode[i] = y_labels.index(y)
    return y_encode, len(y_labels), y_labels_dict


def id3_tree_fit(train_set, train_lable, features, class_num):
    """
    递归实现ID3算法,以特征最大的信息增益为划分节点的标准
    1、递归出口是什么?
    2、递归T是什么?
    :param train_set: 递归产生的样本数据集
    :param train_lable: 递归产生的,对应样本数据的类别标签值
    :param features: 特征索引列表
    :return:
    """
    LEAF = "leaf"  # 叶子节点类型
    INTERNAL = "internal"  # 内部节点类型

    label_unique = np.unique(train_lable)  # 当前类别不同的取值
    # 当前节点包含的样本全属于同一类别,无需划分
    if len(label_unique) == 1:
        print("类别:", y_target_dict[str(label_unique[0])])
        return Node(LEAF, Class=label_unique[0])

    # (是,)、(否,) =  (0,9)、(1,8)
    class_len = [(i, len(list(filter(lambda x: x == i, train_lable)))) for i in range(class_num)]
    max_class, max_len = max(class_len, key=lambda x: x[1])
    # 特征集为空,投票法,取样本量最大所对应的类别
    if len(features) == 0:
        print("类别:", y_target_dict[str(max_class)])
        return Node(LEAF, Class=max_class)

    # 计算每个特征的信息增益,并选择信息增益最大的特征作为划分节点依据
    max_feature, max_gain = 0, 0  # 定义最佳划分节点的特征索引和最大信息增益
    for feature in features:  # 针对每个特征计算信息增益
        feature_data = train_set.iloc[:, feature]
        feature_gain = calc_ent_gain(feature_data, train_lable)  # 信息增益
        print("特征:%s,信息增益是:%f" % (feature_names[feature], feature_gain))
        if feature_gain > max_gain:
            max_feature, max_gain = feature, feature_gain

    if max_gain < epsilon:
        print("类别:", y_target_dict[str(max_class)])
        return Node(LEAF, Class=max_class)

    tree = Node(INTERNAL, best_feature=max_feature)  # 构造决策树内部节点

    print("-" * 60)
    print("最佳划分特征:%s,最大信息增益:%f" % (feature_names[max_feature], max_gain))
    print("=" * 60)

    # 递归时,除去已经被选择的特征属性
    sub_features = list(filter(lambda x: x != max_feature, features))
    max_feature_col = train_set.iloc[:, max_feature]  # 当前最佳划分节点的样本值
    max_feature_unique_values = np.unique(max_feature_col)  # [清晰,稍糊,模糊]

    # 递归循环
    for feature_value in max_feature_unique_values:
        print("当特征【%s】,值为【%s】时:" % (feature_names[max_feature], feature_value))
        sub_train_set = train_set[train_set.iloc[:, max_feature] == feature_value]
        sub_train_label = train_lable[train_set.iloc[:, max_feature] == feature_value]
        sub_tree = id3_tree_fit(sub_train_set, sub_train_label, sub_features, class_num)
        tree.add_node(feature_value, sub_tree)

    return tree


def predict(test_set, tree):
    """
    循环对每个测试样本进行预测
    :param test_set: 测试集
    :param tree: 已构建的决策树
    :return:
    """
    predict_result = []  # 预测结果列表
    for features_value in test_set.values:
        y_pred = tree.predict(features_value)
        predict_result.append(y_pred)
    return np.array(predict_result)


if __name__ == "__main__":
    # 读取数据
    raw_data = pd.read_csv('./datasets/nursery.csv').dropna()  # 读取csv数据

    # 数据预处理
    feature_names = raw_data.columns
    X_sample_data = raw_data.iloc[:, :-1]  # 特征样本数据
    y_target = raw_data.iloc[:, -1]  # 目标值
    target_names = np.unique(y_target)
    y_target, class_num, y_target_dict = target_encode(y_target)  # 对非数值类别进行数值化编码,数据集类别数
    feature_len = X_sample_data.shape[1]  # 数据集特征数
    X_train, X_test, y_train, y_test = train_test_split(X_sample_data, y_target, train_size=0.7,
                                                        random_state=0, stratify=y_target)

    print('Start training...')
    tree = id3_tree_fit(X_train, y_train, list(range(feature_len)), class_num)
    print('End training...')

    test_predict = predict(X_test, tree)
    # 效果比对
    for i in range(len(test_predict)):
        if test_predict[i] is None:
            test_predict[i] = epsilon
    y_pred = [int(y) for y in test_predict]  # 类别整数,防止float类别数值
    score = accuracy_score(y_test, y_pred)
    print("The accuracy score is %f\n" % score)
    print(classification_report(y_test, y_pred, target_names=target_names))


8.C4.5算法

C4.5与ID3算法相似,C4.5在生成过程中,用信息增益比来选择特征,其他一样

案例

性别 学历 年龄 风险级别
M 本科 11
M 大专 29
F 本科 18
F 大专 34
M 大专 19
M 本科 25
F 大专 10
M 本科 33
M 大专 40
  • 1.按照公式1计算\(A\)中各特征对D的信息增益,选择信息增益最大的特征\(A_g\)

\(H(风险)=-\sum\limits_{i=1}^{n}p_i\log p_i=-\frac{4}{9}\log_2\frac{4}{9}-\frac{2}{9}\log_2\frac{2}{9}-\frac{3}{9}\log_2\frac{3}{9}=1.5304930567574826\)

\(H(性别)=-\sum\limits_{i=1}^{n}p_i\log p_i=-\frac{3}{9}\log_2\frac{3}{9}-\frac{6}{9}\log_2\frac{6}{9}=0.9182958340544896\)

\(H(学历)=-\sum\limits_{i=1}^{n}p_i\log p_i=-\frac{4}{9}\log_2\frac{4}{9}-\frac{5}{9}\log_2\frac{5}{9}=0.9910760598382222\)

\(H(风险|性别)=-[\frac{4}{9}(\frac{2}{4}\log_2\frac{2}{4}+\frac{2}{4}\log_2\frac{2}{4}) +\frac{2}{9}(\frac{1}{2}\log_2\frac{1}{2}+\frac{1}{2}\log_2\frac{1}{2}) +\frac{3}{9}(\frac{3}{3}\log_2\frac{3}{3})]=0.6666666666666666\)

\(g_R(风险|性别)=\frac{1.5304930567574826-0.6666666666666666}{0.9182958340544896}=0.9406842087879477\)

\(H(风险|学历)=-[\frac{4}{9}(\frac{2}{4}\log_2\frac{2}{4}+\frac{2}{4}\log_2\frac{2}{4}) +\frac{2}{9}(\frac{1}{2}\log_2\frac{1}{2}+\frac{1}{2}\log_2\frac{1}{2}) +\frac{3}{9}(\frac{1}{3}\log_2\frac{1}{3}+\frac{2}{3}\log_2\frac{2}{3})]=0.9727652780181631\)

\(g_R(风险|学历)=\frac{1.5304930567574826-0.9727652780181631}{0.9910760598382222}=0.5627497235987718\)

\(年龄是连续值,排序后为\{(10,高),(11,高),(18,中),(19,低),(25,低),(29,中),(33,高),(34,高),(40,低)\}\)

\(1,8划分\)

性别 学历 年龄 年龄分类 风险级别
M 本科 11 +
M 大专 29 +
F 本科 18 +
F 大专 34 +
M 大专 19 +
M 本科 25 +
F 大专 10 -
M 本科 33 +
M 大专 40 +

\(H(风险|年龄_{1/8})=0.3605680553151701\)

\(H(年龄_{1/8})=-(\frac{1}{9}\log_2\frac{1}{9}+\frac{8}{9}\log_2\frac{8}{9})=0.5032583347756457\)

\(g_R(年龄_{1/8})=\frac{1.5304930567574826-0.3605680553151701}{0.5032583347756457}=2.324700696638972\)

\(H(风险|年龄_{2/7})=0.4444444444444444\)

\(H(年龄_{2/7})=0.7642045065086203\)

\(g_R(年龄_{2/7})=\frac{1.5304930567574826-0.4444444444444444}{0.7642045065086203}=1.4211491859355943\)

\(H(风险|年龄_{3/6})=0.6666666666666666\)

\(H(年龄_{3/6})=0.9182958340544896\)

\(g_R(年龄_{3/6})=\frac{1.5304930567574826-0.6666666666666666}{0.9182958340544896}=0.9406842087879477\)

\(H(风险|年龄_{4/5})=0.9727652780181631\)

\(H(年龄_{4/5})=0.9910760598382222\)

\(g_R(年龄_{4/5})=\frac{1.5304930567574826-0.9727652780181631}{0.9910760598382222}=0.5627497235987718\)

\(H(风险|年龄_{5/4})=0.9727652780181631\)

\(H(年龄_{5/4})=0.9910760598382222\)

\(g_R(年龄_{5/4})=\frac{1.5304930567574826-0.9727652780181631}{0.9910760598382222}=0.5627497235987718\)

\(H(风险|年龄_{6/3})=0.7505430557959409\)

\(H(年龄_{6/3})=0.9182958340544896\)

\(g_R(年龄_{6/3})=\frac{1.5304930567574826-0.7505430557959409}{0.9182958340544896}=0.849345028080854\)

\(H(风险|年龄_{7/2})=0.6666666666666666\)

\(H(年龄_{7/2})=0.7642045065086203\)

\(g_R(年龄_{7/2})=\frac{1.5304930567574826-0.6666666666666666}{0.7642045065086203}=1.1303602409220705\)

\(H(风险|年龄_{8/1})=0.3060986113514965\)

\(H(年龄_{8/1})=0.5032583347756457\)

\(g_R(年龄_{8/1})=\frac{1.5304930567574826-0.3060986113514965}{0.5032583347756457}=2.4329342621852956\)

\(选择g_R(年龄_{8/1})\)

\( 年龄\begin{cases} \ge 37 & 低风险 \\ <37 & 继续迭代\\ \end{cases} \)

继续迭代第二个维度

性别 学历 风险级别
M 本科
M 大专
F 本科
F 大专
M 大专
M 本科
F 大专
M 本科

\(H(风险)=-\sum\limits_{i=1}^{n}p_i\log p_i=-\frac{4}{8}\log_2\frac{4}{8}-\frac{2}{8}\log_2\frac{2}{8}-\frac{2}{8}\log_2\frac{2}{8}=1.4843777790598331\)

\(H(性别)=-\sum\limits_{i=1}^{n}p_i\log p_i=-\frac{3}{8}\log_2\frac{3}{8}-\frac{5}{8}\log_2\frac{5}{8}=0.954434002924965\)

\(H(风险|性别)=-[\frac{4}{8}(\frac{2}{4}\log_2\frac{2}{4}+\frac{2}{4}\log_2\frac{2}{4}) +\frac{2}{8}(\frac{1}{2}\log_2\frac{1}{2}+\frac{1}{2}\log_2\frac{1}{2}) +\frac{2}{8}(\frac{2}{2}\log_2\frac{2}{2})]=0.75\)

\(g_R(风险|性别)=\frac{1.4843777790598331-0.75}{0.954434002924965}=0.7694379881786\)

\(H(学历)=-\sum\limits_{i=1}^{n}p_i\log p_i=-\frac{4}{8}\log_2\frac{4}{8}-\frac{4}{8}\log_2\frac{4}{8}=1\)

\(H(风险|学历)=-[\frac{4}{8}(\frac{2}{4}\log_2\frac{2}{4}+\frac{2}{4}\log_2\frac{2}{4}) +\frac{2}{8}(\frac{1}{2}\log_2\frac{1}{2}+\frac{1}{2}\log_2\frac{1}{2}) +\frac{3}{8}(\frac{1}{2}\log_2\frac{1}{2}+\frac{1}{2}\log_2\frac{1}{2})]=1\)

\(g_R(风险|学历)=\frac{1.4843777790598331-1}{1}=0.48437777905983315\)

\(所以还是选择性别维度,接下来的决策和上面的ID3算法相同\)

\( 年龄\begin{cases} \ge 37 & 低风险 \\ <37 & 继续迭代\\ \end{cases} \)

\(最后模型如下\)
\( \begin{cases} \ge 37 & 低风险 \\ <37 & \begin{cases} M & \begin{cases} 本科 & 67\%高,33\%低 \\ 大专 & 50\%中,50\%低\\ \end{cases} \\ F & \begin{cases} 本科 & 中 \\ 大专 & 高\\ \end{cases}\\ \end{cases} \end{cases} \)

posted @ 2022-04-15 20:47  筷点雪糕侠  阅读(45)  评论(0编辑  收藏  举报