Numpy 实现基尼指数算法的决策树

基尼系数实现决策树

基尼指数

Gini ⁡ ( D ) = 1 − ∑ k = 1 K ( ∣ C k ∣ ∣ D ∣ ) 2 \operatorname{Gini}(D)=1-\sum_{k=1}^{K}\left(\frac{\left|C_{k}\right|}{|D|}\right)^{2} Gini(D)=1−k=1∑K(∣D∣∣Ck∣)2

特征 A A A条件下集合 D D D的基尼指数:

Gini ⁡ ( D , A ) = ∣ D 1 ∣ ∣ D ∣ Gini ⁡ ( D 1 ) + ∣ D 2 ∣ ∣ D ∣ Gini ⁡ ( D 2 ) \operatorname{Gini}(D, A)=\frac{\left|D_{1}\right|}{|D|} \operatorname{Gini}\left(D_{1}\right)+\frac{\left|D_{2}\right|}{|D|} \operatorname{Gini}\left(D_{2}\right) Gini(D,A)=∣D∣∣D1∣Gini(D1)+∣D∣∣D2∣Gini(D2)

python 复制代码
import numpy as np

def calculate_gini(labels):
    # 计算标签的基尼系数
    _, counts = np.unique(labels, return_counts=True)
    probabilities = counts / len(labels)
    gini = 1 - np.sum(probabilities ** 2)
    return gini

def calculate_gini_index(data, labels, feature_index, threshold):
    # 根据给定的特征和阈值划分数据
    left_mask = data[:, feature_index] <= threshold
    right_mask = data[:, feature_index] > threshold
    left_labels = labels[left_mask]
    right_labels = labels[right_mask]

    # 计算左右子集的基尼系数
    left_gini = calculate_gini(left_labels)
    right_gini = calculate_gini(right_labels)

    # 计算基尼指数
    total_gini = calculate_gini(labels)
    left_weight = len(left_labels) / len(labels)
    right_weight = len(right_labels) / len(labels)
    gini_index = (left_weight * left_gini) + (right_weight * right_gini)
    return gini_index

def find_best_split(data, labels):
    num_features = data.shape[1]
    best_gini_index = float('inf')
    best_feature_index = -1
    best_threshold = None

    for feature_index in range(num_features):
        feature_values = data[:, feature_index]
        unique_values = np.unique(feature_values)

        for threshold in unique_values:
            gini_index = calculate_gini_index(data, labels, feature_index, threshold)
            if gini_index < best_gini_index:
                best_gini_index = gini_index
                best_feature_index = feature_index
                best_threshold = threshold

    return best_feature_index, best_threshold

def create_decision_tree(data, labels):
    # 基本情况:如果所有标签都相同,则返回一个叶节点,其中包含该标签
    if len(np.unique(labels)) == 1:
        return {'label': labels[0]}

    # 找到最佳的划分特征
    best_feature_index, best_threshold = find_best_split(data, labels)

    # 创建一个新的内部节点,其中包含最佳特征和阈值
    node = {
        'feature_index': best_feature_index,
        'threshold': best_threshold,
        'left': None,
        'right': None
    }

    # 根据最佳特征和阈值划分数据
    left_mask = data[:, best_feature_index] <= best_threshold
    right_mask = data[:, best_feature_index] > best_threshold
    left_data = data[left_mask]
    left_labels = labels[left_mask]
    right_data = data[right_mask]
    right_labels = labels[right_mask]

    # 递归创建左右子树
    node['left'] = create_decision_tree(left_data, left_labels)
    node['right'] = create_decision_tree(right_data, right_labels)

    return node

def predict(node, sample):
    if 'label' in node:
        return node['label']

    feature_value = sample[node['feature_index']]
    if feature_value <= node['threshold']:
        return predict(node['left'], sample)
    else:
        return predict(node['right'], sample)

# 示例数据集
data = np.array([
    [1, 2, 0],
    [1, 2, 1],
    [1, 3, 1],
    [2, 3, 1],
    [2, 3, 0],
    [2, 2, 0],
    [1, 1, 0],
    [1, 1, 1],
    [2, 1, 1],
    [1, 3, 0]
])

labels = np.array([0, 1, 1, 1, 0, 0, 0, 1, 1, 1])

# 创建决策树
decision_tree = create_decision_tree(data, labels)

# 测试数据
test_data = np.array([
    [1, 2, 0],
    [2, 1, 1],
    [1, 3, 1],
    [2, 3, 0]
])

# 预测结果
for sample in test_data:
    prediction = predict(decision_tree, sample)
    print(f"样本: {sample}, 预测标签: {prediction}")
相关推荐
天才测试猿8 分钟前
实例介绍:Unittest框架及自动化测试实现流程
自动化测试·软件测试·python·selenium·测试工具·职场和发展·测试用例
veminhe1 小时前
元数据索引有关的错
人工智能·python
一次旅行1 小时前
AutoAWQ完整实战:MIT激活感知AWQ量化,模型显存减半、推理提速且精度无损
人工智能·python·算法
ask_baidu1 小时前
python实现Doris的streamLoad
开发语言·python
GrowthDiary0071 小时前
算法题:寻找二维数组top k问题
数据结构·python·算法
可编程芯片开发1 小时前
基于全阶观测器的三自由度运动系统状态反馈控制simulink建模与仿真
算法
kobesdu1 小时前
从零推导FAST-LIO的观测雅可比矩阵
人工智能·算法·矩阵
乐思智能科技有限公司2 小时前
PLECS软件学习使用(二)直流电机基本系统模型
人工智能·算法·机器学习·面试·职场和发展
随意起个昵称2 小时前
贪心模型-Johnson法则
c++·算法
丙氨酸長鏈2 小时前
[Bukkit插件开发]手持发射器箭矢机枪 教学文档 面向Python/C#开发者入门Java与Bukkit API
java·python·c#