CART决策树Python代码详细实现

Python实现CART决策树:基于基尼指数的数据集划分

CART决策树Python代码实现

CART决策树:使用”基尼指数“来选择划分特征。数据集的纯度可用基尼值(Gini)来度量。Gini(D)反映了从数据集D中随机抽取两个样本,其类别标记不一致的概率,Gini值越小,则数据集的纯度越高。

图片


特征的“基尼指数”(Gini index)定义如下,选择使得划分后基尼指数最小的特征作为最优划分特征。

图片

计算每个特征的基尼指数前,先计算下该节点的基尼值,若基尼值为0,则表示该节点下的数据集已完全分类。

接下来让我们大致复习一下Gini指数的计算:

根节点包含D中所有数据,数据总数为17,可用特征{色泽,根蒂,敲声,纹理,脐部,触感}:

★特征“色泽”:

1. 青绿:{1,4,6,10,13,17},数据总计:6,正例p1= 3/6,反例p2= 3/6
Gin(青绿)=1−(3/6×3/6+3/6×3/6)=0.5

2. 乌黑:{2,3,7,8,9,15},数据总计:6,正例p1= 4/6,反例p2= 2/6
Gini(乌黑)=1−(4/6×4/6+2/6×2/6)=0.444

3. 浅白:{5,11,12,14,16},数据总计:5,正例p1= 1/5,反例p2= 4/5
Gini(浅白)=1−(1/5×1/5+4/5×4/5)=0.32

下面是一个简单的 CART 决策树Python 实现: ```python import numpy as np class CARTDecisionTree: def __init__(self, max_depth=10, min_samples_split=2): self.max_depth = max_depth self.min_samples_split = min_samples_split def fit(self, X, y): self.tree = self.build_tree(X, y) def build_tree(self, X, y, depth=0): n_samples, n_features = X.shape n_labels = len(np.unique(y)) # 检查是否应该停止分裂 if (depth >= self.max_depth or n_labels == 1 or n_samples < self.min_samples_split): return np.argmax(np.bincount(y)) # 寻找最佳分割特征和阈值 best_feature, best_threshold = self.get_best_split(X, y, n_samples, n_features) # 分割样本集并递归构建子树 left_indices = X[:, best_feature] < best_threshold right_indices = X[:, best_feature] >= best_threshold left_subtree = self.build_tree(X[left_indices], y[left_indices], depth+1) right_subtree = self.build_tree(X[right_indices], y[right_indices], depth+1) return {'feature': best_feature, 'threshold': best_threshold, 'left': left_subtree, 'right': right_subtree} def get_best_split(self, X, y, n_samples, n_features): best_gini = float('inf') best_feature, best_threshold = None, None # 遍历所有特征和阈值,找到最佳分割 for feature in range(n_features): thresholds = np.unique(X[:, feature]) for threshold in thresholds: left_indices = X[:, feature] < threshold right_indices = X[:, feature] >= threshold if (len(left_indices) == 0 or len(right_indices) == 0): continue gini = self.gini_index(y, left_indices, right_indices) if gini < best_gini: best_gini = gini best_feature = feature best_threshold = threshold return best_feature, best_threshold def gini_index(self, y, left_indices, right_indices): n_left, n_right = len(left_indices), len(right_indices) gini_left, gini_right = 0, 0 if n_left > 0: labels_left, counts_left = np.unique(y[left_indices], return_counts=True) gini_left = 1 - np.sum((counts_left / n_left) ** 2) if n_right > 0: labels_right, counts_right = np.unique(y[right_indices], return_counts=True) gini_right = 1 - np.sum((counts_right / n_right) ** 2) gini = (n_left * gini_left + n_right * gini_right) / (n_left + n_right) return gini def predict(self, X): return np.array([self.predict_sample(x, self.tree) for x in X]) def predict_sample(self, x, tree): if isinstance(tree, int): return tree feature, threshold = tree['feature'], tree['threshold'] if x[feature] < threshold: return self.predict_sample(x, tree['left']) else: return self.predict_sample(x, tree['right']) ``` 需要注意的是,上述代码实现CART 决策树仅支持分类问题。如果要用于回归问题,需要对 `gini_index` 方法进行修改,使用其他的评估指标(如 MSE)。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值