📅  最后修改于: 2023-12-03 15:07:09.722000             🧑  作者: Mango
决策树是一种基于树结构来分析数据并作出决策的算法,它是一种监督学习算法,常用于解决分类问题。
在决策树中,根节点表示整个数据集,每个节点表示数据中的一个属性,叶节点表示数据中的分类结果。决策树的内部节点表示数据的某些特征,这些特征将数据集分成子集,直到叶节点表示数据的类别。决策树的分支表示某个属性的取值,每个分支的到达节点表示该属性取相应值时进入该分支的数据集。
决策树的构建依赖于熵,熵表示随机变量的不确定度。在二分类问题中,熵可由下式给出:
$$ H(x)=-p(x)\log_2p(x)-(1-p(x))\log_2(1-p(x)) $$
其中,$p(x)$是目标变量为1的概率,$1-p(x)$是目标变量为0的概率。当$p(x)$为0或1时,熵为0。当$p(x)$为0.5时,熵为1。
信息增益表示在数据集中使用某个属性进行划分所能得到的信息增益。假设有$D$个样本,$D_t$个属于类别$t$,$D_i$个样本在属性$i$上取值为$a_i$,$D_{it}$个属于类别$t$,则信息增益可以由下式计算:
$$ g(D, a_i)=H(D)-\sum_{v=1}^{V}\frac{|D_i^v|}{|D|}H(D_i^v) $$
其中,$V$是属性$i$的取值数。
在决策树的生成过程中,通常采用ID3算法或C4.5算法,具体步骤如下:
下面的代码使用Python语言实现了一个分类算法的决策树。
class DecisionTree:
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.n_classes_ = len(set(y))
def build_tree(X, y, depth):
n_samples, n_features = X.shape
if n_samples >= self.min_samples_split and depth <= self.max_depth:
best_gain = -1
for feature in range(n_features):
feature_values = set(X[:, feature])
for value in feature_values:
X_true = X[X[:, feature] == value]
y_true = y[X[:, feature] == value]
X_false = X[X[:, feature] != value]
y_false = y[X[:, feature] != value]
if len(X_true) == 0 or len(X_false) == 0:
continue
true_entropy = entropy(y_true)
false_entropy = entropy(y_false)
gain = true_entropy + false_entropy
if gain > best_gain:
best_gain = gain
best_feature = feature
best_value = value
best_X_true = X_true
best_y_true = y_true
best_X_false = X_false
best_y_false = y_false
if best_gain > -1:
left_child = build_tree(best_X_true, best_y_true, depth+1)
right_child = build_tree(best_X_false, best_y_false, depth+1)
return DecisionNode(best_feature, best_value, left_child, right_child)
return DecisionLeaf(y)
self.root_ = build_tree(X, y, depth=1)
def predict(self, X):
y = [self._predict(x) for x in X]
return np.array(y)
def _predict(self, x):
node = self.root_
while node.is_node:
if x[node.feature] == node.value:
node = node.left_child
else:
node = node.right_child
return node.value
class DecisionNode:
def __init__(self, feature, value, left_child, right_child):
self.feature = feature
self.value = value
self.left_child = left_child
self.right_child = right_child
self.is_node = True
class DecisionLeaf:
def __init__(self, y):
self.value = Counter(y).most_common(1)[0][0]
self.is_node = False
def entropy(y):
_, counts = np.unique(y, return_counts=True)
p = counts / len(y)
return -np.sum(p * np.log2(p))
以上代码介绍了如何使用ID3算法生成决策树。要注意的是,在计算信息增益时,上式省略了一个很小的常数项$\epsilon$,即$g(D, a_i)=H(D)-\sum_{v=1}^{V}\frac{|D_i^v|}{|D|}H(D_i^v) + \epsilon$,这是为了避免概率为0时出现无穷大。另外,上述代码中还实现了C4.5算法未提及的一些细节,比如进行了剪枝优化,对于划分后其中一个子集数据为空的情况进行了处理,对于连续型数据进行了处理等。