在任何数据科学项目中,异常值的处理都是一个关键步骤,因为异常值的存在可能会导致机器学习模型的性能下降。以线性回归问题为例,假设需要根据身高预测人的体重。通常情况下,身高较高的人体重也较重(正线性趋势),但如果极少数人的身高较高而体重却较轻,这些数据点就会被视为异常值,不适合回归模型。
处理异常值有多种方法,本文将重点介绍Z-Score方法。将讨论这种方法的局限性,何时使用其他方法,以及如何使用Python完整实现。
Z-Score是一种高效的异常值检测和移除方法,但它并不适用于所有类型的数据。它只适用于完全或接近正态分布的数据,这意味着对于偏斜数据(无论是左偏还是右偏),这种方法并不适用。对于其他类型的数据,可以使用四分位数范围(IQR)方法,这将在下一篇文章中详细讨论。
现在,让跳过理论部分,直接进入实际的实现过程,看看如何从数据集中检测和移除不良数据以提高模型的准确性。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
通过导入Python支持包中的所有必需库来准备工具。这里导入了四个主要库,它们将在执行部分使用:Numpy用于执行数学计算,Pandas用于数据操作,Matplotlib用于可视化,Seaborn是基于Matplotlib的另一个可视化库,具有更好的表示、外观和感觉。
df_org = pd.read_csv('placement.csv')
df_org.head()
输出:使用简单的就业数据集来撰写本文,将选取GPA和就业考试成绩作为两列,并选择一列显示正态分布,然后进一步从该特征中移除异常值。使用head函数显示前5行。
df_org.shape
输出:(shape函数显示)有1000行数据,3列 -> (1000,3)。
df_org.sample(5)
输出:类似于head函数默认返回前5行,sample函数根据在参数中给出的值返回随机样本的'n'行。
选择了直方图和核密度作为CGPA和就业考试成绩列的图形,以便可以清楚地了解它们中哪一个具有正态分布?从图中可以看到,CGPA几乎适合正态分布,或者说它形成了正确的钟形曲线。与此同时,另一个稍微向右偏斜。因此,将对CGPA进行进一步分析。
df_org['placement_exam_marks'].skew()
输出:0.8356419499466834
df_org['cgpa'].skew()
输出:-0.014529938929314918
从上面的图中,很幸运地发现了正态分布和偏斜分布之间的区别,但有时图表可能无法清晰地理解拥有的偏斜函数,如果分布看起来偏斜(就业考试成绩),否则它会返回一个相当低的值,甚至是负值,如果它根本不偏斜(CGPA)。
打印出CGPA的一些不同的统计度量,以便将原始值(来自原始数据)与数据无异常值时进行比较。分析也将是显而易见的。
从这里开始,主要任务开始了,但在实现之前,让首先讨论游戏计划以及将如何处理使用Z-Score的不良数据。
第一步是设置上限和下限。这个范围意味着每个数据点都将被视为这个范围之外的异常值。让看看上限和下限的公式。
上限:均值 + 3 * 标准差。下限:均值 - 3 * 标准差。
打印("上限", df_org['cgpa'].mean() + 3*df_org['cgpa'].std())
打印("下限", df_org['cgpa'].mean() - 3*df_org['cgpa'].std())
输出:看到最高值是8.80,而最低值是5.11。因此,任何超出这个范围的值都是不良数据点。
第二步是检测数据集中有多少异常值,基于刚刚设置的上限和下限。
df_org[(df_org['cgpa'] > 8.80) | (df_org['cgpa'] < 5.11)]
输出:现在,使用pandas进行过滤,传递了两个条件,记住如果任一条件为True,那么目标就会实现。在输出中,可以看到它返回了5行,即数据集中有5个异常值。
现在,将开始第三步,也是最后一步,将最终在第二步中检测到的异常值,使用两种技术;可以选择修剪或封顶,将分别更详细地讨论这两种技术。
修剪异常值:处理异常值的第一个技术是修剪,无论正在处理哪种数据分布,修剪都是适用于大多数数据类型的经过验证的技术。在这种技术中使用过滤条件剔除所有异常值。
new_df_org = df_org[(df_org['cgpa'] > 5.11)]
new_df_org
输出:因此,正如所看到的,应用了条件,所有数据都应该在上限和下限范围内。结果,它返回了995行,而不是1000行,这表明已经成功地移除了5个异常值。