如果删除异常值后准确性和交叉验证分数下降,我应该删除它们吗?

数据挖掘 机器学习 随机森林 数据清理 机器学习模型 离群值
2021-10-09 08:23:34

我有一个二进制分类问题,我正在使用 Scikit 的 RandomForestClassifier 解决这个问题。当我绘制(到目前为止)最重要的特征(如箱线图)以查看其中是否有异常值时,我发现了许多异常值。所以我试图从数据集中删除它们。

准确率和交叉验证下降了大约 5%。我有 80% 的准确率和 0.8 的 Cross-Val-Score

从 3 个最重要的特征(RF 的特征重要性)中去除异常值后,准确率和 Cross-Val-Score 分别下降到 76% 和 77%。

这是我的数据集描述的一部分:

数据框描述

这是我的数据的概述: 在此处输入图像描述

在此处输入图像描述

以下是去除异常值之前的箱线图: 去除异常值之前的箱线图

以下是去除异常值之前的特征重要性: 删除异常值之前的 feature_importances

这是准确性和 Cross-Val-Score:

Accuracy score:  0.808388941849
Average Cross-Val-Score:  0.80710845698

这是我删除异常值的方法:

clean_model = basic_df.copy()
print('Clean model shape (before clearing out outliers): ', clean_model.shape)

# Drop 'num_likes' outliers 
clean_model.drop(clean_model[clean_model.num_likes > (1938 + (1.5* (1938-125)))].index, inplace=True)
print('Clean model shape (after clearing out "num_likes" outliers): ', clean_model.shape)

# Drop 'num_shares' outliers
clean_model.drop(clean_model[clean_model.num_shares > (102 + (1.5* (102-6)))].index, inplace=True)
print('Clean model shape (after clearing out "num_shares" outliers): ', clean_model.shape)

# Drop 'num_comments' outliers
clean_model.drop(clean_model[clean_model.num_comments > (54 + (1.5* (54-6)))].index, inplace=True)
print('Clean model shape (after clearing out "num_comments" outliers): ', clean_model.shape)

以下是去除异常值后的形状:

Clean model shape (before clearing out outliers):  (6992, 20)
Clean model shape (after clearing out "num_likes" outliers):  (6282, 20)
Clean model shape (after clearing out "num_shares" outliers):  (6024, 20)
Clean model shape (after clearing out "num_comments" outliers):  (5744, 20)

这是删除异常值后的箱线图(仍然有异常值..如果我也删除这些,我将只有很少的数据点): 去除异常值后的箱线图

这是去除异常值并使用相同模型后的准确率和 Cross-Val-Score:

Accuracy score:  0.767981438515
Average Cross-Val-Score:  0.779092230906

为什么去除异常值会降低准确性和 F1 分数?我应该把它们留在数据集中吗?或者删除要在第二个箱线图中看到的异常值(在删除第一个异常值之后,如上所示)?

这是我的模型:

model= RandomForestClassifier(n_estimators=120, criterion='entropy', 
                              max_depth=7, min_samples_split=2, 
                              #max_depth=None, min_samples_split=2, 
                              min_samples_leaf=1, min_weight_fraction_leaf=0.0,
                              max_features=8, max_leaf_nodes=None, 
                              min_impurity_decrease=0.0, min_impurity_split=None,
                              bootstrap=True, oob_score=False, n_jobs=1,
                              verbose=0, warm_start=False,
                              class_weight=None, 
                              random_state=23)
model.fit(x_train, y_train)
print('Accuracy score: ', model.score(x_test,y_test))
print('Average Cross-Validation-Score: ', np.mean(cross_val_score(model, x_train, y_train, cv=5))) # 5-Fold Cross validation
3个回答

根据经验,在没有充分理由删除异常值的情况下删除异常值很少对任何人有任何好处。如果对每个特征中可能存在的范围没有深入和既得的理解,那么去除异常值就变得很棘手。很多时候,我看到学生/新员工绘制箱线图或检查平均值和标准差以确定异常值,如果它在胡须之外,他们会删除数据点。然而,世界上有无数的分布,如果你这样做,你将删除完​​全有效的数据点。

在您的示例中,您似乎在处理社交媒体数据。如果我从社交媒体数据库中抽取 1000 个用户样本,然后绘制一个箱线图来查找帖子获得的点赞数的“异常值”,我可以想象可能会有一些所谓的异常值。例如,我希望我的 Facebook 帖子在任何一天都能获得少量的点赞,但当我女儿出生时,与此相关的帖子就达到了数百个。这是一个个体异常值。此外,在我的 1000 个用户样本中,假设我设法获得了用户 Justin Bieber,并且简单地喜欢他的平均点赞数。我会说他是一个异常值,因为他可能会进入数千人。

异常值的真正含义是您需要更多地调查数据并集成更多特征来帮助解释它们。例如,整合对我的帖子的感伤和上下文理解可以解释为什么在我女儿的生日那天,我收到了数百个针对该特定帖子的点赞。类似地,结合 Justin Bieber 验证状态,大量关注可能有助于解释为什么像他这样的用户会收到大量喜欢。

从那里您可以继续为不同的人口统计数据(像我这样的普通人与像贾斯汀比伯这样的人)构建单独的模型,或者尝试合并更多功能。

TL;博士。不要仅仅因为异常值而删除异常值。调查他们。

Tophat提出了一些重要的观点。要考虑的另一件事是,您通过删除“异常值”删除了近 20% 的数据,这使我相信它们确实不是异常值,而只是极端值。当然,您应该查看一个维度上的异常值,但是对于如此丰富的数据集,一个维度上的极值可能不足以说它是异常值。就个人而言,我会尝试对数据进行聚类以找到异常值(如果有)。它们会以只有一两个成分的集群出现。

要考虑的另一点是异常值并不总是必须解决的问题。的好处之一decision trees是,即使有异常值,它们也能表现良好。random forest因此,在您的情况下,我会保留所有记录,因为任何真正的异常值可能对您的模型的功效影响不大。

除了现有的优秀答案之外,删除异常值的需要(或不需要)也高度依赖于模型。

异常值会对线性或多项式回归产生巨大影响。另一方面,决策树/随机森林可以很好地处理它们,因为它们可以用一个简单的分支来处理。