异常值(异常值)是与其他数据值相距太远的数据值。数据异常值可能是自然的,也可能是测量不准确或系统故障造成的。与缺失值类似,异常值会破坏数据科学项目并返回错误的结果或预测。异常值也可能出现在偏斜数据中,这些类型的异常值被认为是自然异常值。异常值会影响数据的均值、标准差和四分位距。如果我们在移除异常值之前和之后计算这些统计数据,我们会得到不同的结果。异常值如何影响机器学习模型?如果我们的离群值是自然的而不是由于测量误差,我们应该将其保留在数据集中并执行数据转换以对其进行归一化。如果我们有一个大数据集,异常值很少,我们应该保留这些异常值,因为它们不会显着影响结果,并且可以为我们的模型带来泛化优势。如果我们非常确定异常值是由于测量误差引起的,我们应该将它们从数据集中删除。移除异常值将减小数据集的大小,并允许我们的模型扩展到包含的指标范围。但请记住,移除自然异常值会导致模型不准确。使用可视化工具检测离群值离群值不容易被“眼睛”发现,但有一些可视化工具可以帮助完成这项任务。最常见的是箱线图和直方图。像往常一样,我们的第一步是加载必要的库并导入/加载数据集。Insurance.csv(https://www.kaggle.com/datase...)将在此处使用。importnumpyasnpimportpandasaspdimportseabornassnsimportstatisticsdf=pd.read_csv('insurance.csv')df我们将检查异常值的年龄、bmi和费用。第一种方法是使用箱线图来表示数据分布:sns.boxplot(y="age",data=df)sns.boxplot(y="bmi",data=df)sns.boxplot(y="expenses",data=df)从箱线图中可以看出,age没有异常值,bmi在上界有一些异常值,expenses在上界有很多异常值,说明这是一个偏态分布。要检查这种偏斜分布的偏斜程度,我们将使用直方图。sns.histplot(df,x="age",kde=True)sns.histplot(df,x="bmi",kde=True)sns.histplot(df,x="expenses",kde=True)来自直方图从图中可以看出年龄变量呈均匀分布,bmi接近正态分布,费用呈偏态分布。通过分析这两个图形表示,我们可以决定排除哪些数据。年龄不排除任何值。对于bmi,我们将排除高于47的值,对于费用,我们将排除高于50000的值。df.drop(df[df['bmi']>=47].index,inplace=True)df.drop(df[df['expenses']>=50000].index,inplace=True)nowifcheckagainBoxplotsandHistograms:DetectingOutliersUsingStatisticalMethods检测异常值有两种主要的统计方法:使用z-scores和使用四分位数范围。1.使用Z-score检测异常值Z-score是一种数学变换,根据每个观察值与平均值的距离对每个观察值进行分类。与平均值的距离以标准差(SD)衡量。如果我们得到1.59的值,我们就知道观察值比均值高1.59个标准差。类似地,如果我们得到-2.4的Z分数,我们就知道观察值比均值低-2.4个标准差。高于3SD或低于-3SD的观察值通常被视为异常值。我们用代码实现一下,先看年龄:df=pd.read_csv('insurance.csv')mean_age=statistics.mean(df['age'])stdev_age=statistics.stdev(df['age'])age_z_score=(df['age']-mean_age)/stdev_agedf['age_z_score']=age_z_score.tolist()现在检查是否有低于-3SD的值:df.sort_values(by=['age_z_score'],ascending=True)看到没有低于-3SD的值。现在查看3SD以上的值:我们可以看到没有3SD以上的值。也就是说,年龄没有异常值。现在对变量bmi做同样的事情:mean_bmi=statistics.mean(df['bmi'])stdev_bmi=statistics.stdev(df['bmi'])bmi_z_score=(df['bmi']-mean_bmi)/stdev_bmidf['bmi_z_score']=bmi_z_score.tolist()df.sort_values(by=['bmi_z_score'],ascending=True)df.sort_values(by=['bmi_z_score'],ascending=False)检查3SD以上的值:将删除这些值:df.drop(df[df['bmi_z_score']>=3].index,inplace=True)接下来同样计算费用:mean_expenses=statistics.mean(df['费用'])stdev_expenses=statistics.stdev(df['expenses'])expenses_z_score=(df['expenses']-mean_expenses)/stdev_expensesdf['expenses_z_score']=expenses_z_score.tolist()df.sort_values(by=['expenses_z_score'],ascending=True)df.sort_values(by=['expenses_z_score'],ascending=False)df.drop(df[df['expenses_z_score']>=3].index,inplace=True)之后删除数据,我们再次将数据可视化:可以看到已经删除了一些值2.使用四分位数rangetodetectoutliersinterquartilerange将数据分成四个部分,从低到高排序,如下图所示,每个Section包含相同数量的样本。第一个四分位数(Q1)是边界上数据点的值。Q2和Q3也是如此。四分位距(IQR)是两者中间的数据点(代表50%的数据)。四分位数范围包括所有高于Q1和低于Q3的数据点。如果该点高于Q3+(1.5xIQR),则它包含较高的数值异常值,如果Q1?(1.5xIQR),则存在较低的数值异常值。代码如下:df=pd.read_csv('insurance.csv')q75_age,q25_age=np.percentile(df['age'],[75,25])iqr_age=q75_age-q25_ageiqr_ageage_h_bound=q75_age+(1.5*iqr_age)age_l_bound=q25_age-(1.5*iqr_age)print(age_h_bound)print(age_l_bound)这样我们就知道异常值在87以上或者-9以下:df.sort_values(by=['age'],ascending=True)可以看出没有下异常值,现在我们将检查上异常值:df.sort_values(by=['age'],ascending=False)也没有上异常值。对下面的bmi执行相同的操作:q75_bmi,q25_bmi=np.percentile(df['bmi'],[75,25])iqr_bmi=q75_bmi-q25_bmiiqr_bmibmi_h_bound=q75_bmi+(1.5*iqr_bmi)bmi_l_bound=q25_bmi-(1.5*iqr)打印(bmi_h_bound)打印(bmi_l_bound)df.sort_values(by=['bmi'],ascending=True)df.sort_values(by=['bmi'],ascending=False)df.drop(df[df['bmi']>=47.3].index,inplace=True)df.drop(df[df['bmi']<=13.7].index,inplace=True)expenses也是同理处理,我们将结果可视化:可以看到异常值也被去掉了https://avoid.overfit.cn/post/c55c9a078cf44e33912c6f98affdd7c4作者:CarlaMartins
