决策树算法中如何处理缺失值和异常值?
介绍
决策树是一种常用的监督学习算法,可以用于解决分类和回归问题。在实际应用中,经常会遇到数据集中存在缺失值和异常值的情况。这些问题会对决策树算法的性能和准确性产生重要影响。因此,如何处理缺失值和异常值是一个非常关键的问题。
算法原理
决策树构建算法
决策树的构建过程可以分为三个步骤:特征选择、决策树生成和决策树剪枝。特征选择通过计算特征的信息增益或信息增益率,选择最优的划分特征。决策树生成通过将训练样本递归地划分为不同的子集,直到达到停止条件为止。决策树剪枝是为了防止过拟合,通过删除一些子树或将其叶子节点替换为树叶节点。
处理缺失值的方法
在处理缺失值时,决策树算法常常采用以下两种方法:
-
删除缺失值:如果某个特征在样本中具有缺失值,可以选择删除这些样本。这种方法可能导致丢失有效信息,尤其是当缺失值的比例较高时。
-
填充缺失值:在决策树中,有多种方法可以填充缺失值,如使用特征的平均值、中值或众数填充缺失值。填充缺失值后,可以继续使用决策树算法进行建模。
处理异常值的方法
处理异常值的方法主要有以下几种:
-
删除异常值:可以选择直接删除包含异常值的样本。这种方法可能导致丢失有效信息,特别是当异常值的比例较高时。
-
替换异常值:可以将异常值替换为缺失值,然后使用填充缺失值的方法进行处理。这种方法可以保留异常样本的信息,并且不会直接影响决策树生成过程。
-
将异常值视为单独的类别:可以将异常值视为单独的类别,将其作为特征的一个取值。这种方法可以保留异常样本的信息,并且不会对决策树的构建过程产生负面影响。
公式推导
信息熵
信息熵是衡量样本的不确定性的指标。对于二分类问题,信息熵的计算公式为:
E
n
t
r
o
p
y
(
x
)
=
−
∑
i
=
1
n
p
i
log
2
(
p
i
)
Entropy(x) = - \sum_{i=1}^{n} p_i \log_2(p_i)
Entropy(x)=−i=1∑npilog2(pi)
其中,
p
i
p_i
pi表示类别
i
i
i所占样本的比例。
信息增益
信息增益表示在特征
A
A
A给定的条件下,熵的减少程度。对于二分类问题,信息增益的计算公式为:
G
a
i
n
(
A
)
=
E
n
t
r
o
p
y
(
D
)
−
∑
v
=
1
V
∣
D
v
∣
∣
D
∣
E
n
t
r
o
p
y
(
D
v
)
Gain(A) = Entropy(D) - \sum_{v=1}^{V} \frac{|D_v|}{|D|} Entropy(D_v)
Gain(A)=Entropy(D)−v=1∑V∣D∣∣Dv∣Entropy(Dv)
其中,
E
n
t
r
o
p
y
(
D
)
Entropy(D)
Entropy(D)表示原始数据集
D
D
D的熵,
D
v
D_v
Dv表示特征
A
A
A的第
v
v
v个取值所对应的数据子集,
V
V
V表示特征
A
A
A的取值个数。
计算步骤
1.加载数据集,处理缺失值和异常值。
2.选择最优划分特征,计算信息增益。
3.如果所选特征的信息增益小于阈值或达到叶子节点的条件,停止划分,生成叶子节点。
4.否则,根据所选特征的取值将数据集划分为多个子集。
5.递归地对每个子集进行上述步骤,生成决策树。
6.对决策树进行剪枝,防止过拟合。
Python代码示例
import numpy as np
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 创建虚拟数据集
data = np.array([[1, 2, 3, 'A'],
[4, np.nan, 6, 'B'],
[7, 8, 9, 'B'],
[10, 11, np.nan, 'A'],
[13, 14, 15, np.nan]])
# 处理缺失值
data_df = pd.DataFrame(data, columns=['X1', 'X2', 'X3', 'Y'])
data_df['X2'] = data_df['X2'].fillna(data_df['X2'].median())
data_df['X3'] = data_df['X3'].fillna(data_df['X3'].mean())
data_df['Y'] = data_df['Y'].fillna(data_df['Y'].mode()[0])
# 处理异常值
data_df['X2'] = np.where((data_df['X2'] < 0) | (data_df['X2'] > 100), np.nan, data_df['X2'])
data_df['X3'] = np.where((data_df['X3'] < data_df['X3'].mean() - 3 * data_df['X3'].std()) | (data_df['X3'] > data_df['X3'].mean() + 3 * data_df['X3'].std()), np.nan, data_df['X3'])
data_df['Y'] = np.where(data_df['Y'].isnull(), 'C', data_df['Y'])
# 划分特征和标签
X = data_df[['X1', 'X2', 'X3']]
y = data_df['Y']
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
# 创建决策树模型
dt = DecisionTreeClassifier()
# 训练模型
dt.fit(X_train, y_train)
# 预测
y_pred = dt.predict(X_test)
# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print('准确率:', accuracy)
代码细节解释
-
我们首先创建了一个虚拟数据集,其中包含了缺失值和异常值。
-
然后,我们使用
fillna
函数填充缺失值。对于X2
特征,我们使用中值进行填充;对于X3
特征,我们使用平均值进行填充;对于Y
特征,我们使用众数进行填充。 -
接下来,我们使用
np.where
函数将异常值替换为缺失值。对于X2
特征,我们将小于0或大于100的值替换为缺失值;对于X3
特征,我们将小于平均值减去3倍标准差或大于平均值加上3倍标准差的值替换为缺失值;对于Y
特征,我们将缺失值替换为新的类别C
。 -
然后,我们将数据集划分为特征矩阵和标签向量。
-
接下来,我们使用
train_test_split
函数将数据集划分为训练集和测试集。 -
然后,我们使用
DecisionTreeClassifier
类创建决策树模型。 -
接着,我们使用
fit
函数训练模型。 -
最后,我们使用
predict
函数进行预测,并使用accuracy_score
函数计算准确率。