首页 > 编程知识 正文

python 异常值,Python处理异常

时间:2023-05-04 09:52:33 阅读:273048 作者:4420

背景:

不论是在机器/深度学习还是普通的业务场景的描述性统计分析等,我们首先要做的就是了解拿到的基础数据,观察数据结构,类型,缺失值,异常值等情况。其中,异常值是指数据集中存在的不合理的点,这些异常点如果不加以剔除或者修正而错误的包括进数据的计算分析过程中,那么会对结果产生非常不好的影响,导致结果偏差。因此,重视异常值的出现,分析其产生原因,并对异常值进行剔除或者修正就显得尤其重要。本篇幅主要列举了本人遇到的一些异常值的处理方法,如有更好的,欢迎指正!

1. 如何发现异常值?

异常值的方法想法有很多种,基于业务的认知,简单的确定某个指标的阈值,进行判断,也可以基于统计学方法,同时还有基于机器学习的离群点检测方法,今天主要介绍统计学方法和机器学习的方法。
1.1 3∂原则
在统计学中,如果一个数据分布近似正态,那么大约 68% 的数据值会在均值的一个标准差范围内,大约 95% 会在两个标准差范围内,大约 99.7% 会在三个标准差范围内。但是,当数据不服从正态分布,可以通过远离平均距离多少倍的标准差来判定,多少倍的取值需要根据经验和实际情况来决定。

###正态分布标准差import numpy as npimport matplotlib.pyplot as pltdef find_outliter_std(random_data,c): anomalies = [] random_data_std = np.std(random_data) random_data_mean = np.mean(random_data) anomaly_cut_off = random_data_std * c lower_limit = random_data_mean - anomaly_cut_off upper_limit = random_data_mean + anomaly_cut_off #print(lower_limit) for outlier in random_data: if outlier > upper_limit or outlier < lower_limit: anomalies.append(1) else: anomalies.append(0) res4=pd.merge(pd.DataFrame(random_data),pd.DataFrame(anomalies),left_index=True,right_index=True) res4.columns=['values','is_outliter'] return res4

1.2 箱线图
箱线图是通过数据集的四分位数形成的图形化描述。这是一种非常简单但有效的可视化离群点的方法。考虑把上下触须作为数据分布的边界。任何高于上触须或低于下触须的数据点都可以认为是离群点或异常值。箱型图依据实际数据绘制,没有对数据作任何限制性要求(如服从某种特定的分布形式),它只是真实直观地表现数据分布的本来面貌;另一方面,箱型图判断异常值的标准以四分位数和四分位距为基础,四分位数具有一定的鲁棒性:多达25%的数据可以变得任意远而不会很大地扰动四分位数,所以异常值不能对这个标准施加影响。由此可见,箱型图识别异常值的结果比较客观,在识别异常值方面有一定的优越性

如下是绘制箱形图的代码:

import numpy as npimport pandas as pdimport scipydef find_outliter_quantile(random_data,c): anomalies = [] random_data_q1 = np.quantile(random_data,0.25) random_data_q3 = np.quantile(random_data,0.75) anomaly_cut_off = (random_data_q3-random_data_q1) * c #c一般为1.5或者3,但是个人认为可以根据实际业务情况进行更改,比如涨幅超过1倍的情况就是极端异常的情况,那我们可以c取值为1 lower_limit = random_data_q1 - anomaly_cut_off upper_limit = random_data_q3 + anomaly_cut_off for outlier in random_data: if outlier > upper_limit or outlier < lower_limit: anomalies.append(1) else: anomalies.append(0) res5=pd.merge(pd.DataFrame(random_data),pd.DataFrame(anomalies),left_index=True,right_index=True) res5.columns=['values','is_outliter'] return res5if __name__=='__main__':data=np.array([1338,1338,2,1047,688,520,1408,225,206,280])outliers=find_outliter_quantile(random_data,c)

1.3 DBSCAN
从基于密度的观点来说,离群点是在低密度区域中的对象。基于密度的离群点检测与基于邻近度的离群点检测密切相关,因为密度通常用邻近度定义,DBSCAN就是一种使用密度的聚类算法,具体算法原理可以查阅:https://baike.baidu.com/item/DBSCAN/4864716?fr=aladdin

from sklearn.cluster import DBSCANimport numpy as npdef dbscan(random_data):outlier_detection = DBSCAN(min_samples = 2, eps = 3)clusters = outlier_detection.fit_predict(random_data)print (list(clusters).count(-1))res2=pd.DataFrame(random_data,list(clusters)).reset_index()res2.columns=['is_outliter','values']return res2

1.4 k-means
k-means方法是基于聚类的离群点识别方法,k-means的主要思想是一个对象是基于聚类的离群点,如果该对象不强属于任何簇,那么该对象属于离群点。
离群点对初始聚类的影响:如果通过聚类检测离群点,则由于离群点影响聚类,存在一个问题:结构是否有效。这也是k-means算法的缺点,对离群点敏感。为了处理该问题,可以使用如下方法:对象聚类,删除离群点,对象再次聚类(这个不能保证产生最优结果)。
优缺点:(1)基于线性和接近线性复杂度(k均值)的聚类技术来发现离群点可能是高度有效的;(2)簇的定义通常是离群点的补,因此可能同时发现簇和离群点;(3)产生的离群点集和它们的得分可能非常依赖所用的簇的个数和数据中离群点的存在性;(4)聚类算法产生的簇的质量对该算法产生的离群点的质量影响非常大。

####k-means方法异常点检测#####from sklearn import preprocessingfrom sklearn.cluster import KMeansimport numpy as npimport pandas as pdimport matplotlib.pyplot as pltdef kmeans(data):data_scale = preprocessing.scale(data)#处理后需要转为dataframe,或者直接手动求均值、方差转换model = KMeans(n_clusters = 2,max_iter = 1000) # k=2,一类认为是异常的,一类是不异常的,最大迭代次数可以根据实际情况进行修改model.fit(data_scale)data_scale = pd.DataFrame(data_scale)#data_scale = pd.DataFrame(data_scale,index = data.index)data_scale['labels'] = model.labels_res3=pd.merge(data_scale,pd.DataFrame(data),left_index=True,right_index=True) res3.columns=['distance','labels','values']#print (res3)return res3

1.5 孤立森林
孤立森林是一种无监督学习算法,属于组合决策树家族。这种方法和以上所有方法都不同。之前的所有方法都在试图寻找数据的常规区域,然后将任何在此定义区域之外的点都视为离群点或异常值。
这种方法的工作方式不同。它明确地隔离异常值, 而不是通过给每个数据点分配一个分数来分析和构造正常的点和区域。它利用了这样一个事实:异常值只是少数,并且它们具有与正常实例非常不同的属性值。该算法适用于高维数据集,并且被证明是一种非常有效的异常检测方法。

#孤立森林#最好对数据集去重,在确定孤立点,因为如果多个异常点聚集,那么就不孤立了from sklearn.ensemble import IsolationForestimport numpy as npdef isolationforest(random_data):clf = IsolationForest(behaviour = 'new',max_samples='auto', random_state = 1, contamination= 'auto')preds = clf.fit_predict(random_data)print (list(preds).count(-1))res1=pd.DataFrame(random_data,list(preds)).reset_index()res1.columns=['is_outliter','values']return res1 2. 异常值如何处理?

检测到了异常值,我们需要对其进行一定的处理。而一般异常值的处理方法可大致分为以下几种:
首先、如果模型或者分析对异常值比较敏感,如果不处理会极大的影响模型效果或者业务分析结果,那么则需要进行如下几种方式的处理:
(1)删除含有异常值的记录:直接将含有异常值的记录删除;

(2)视为缺失值:将异常值视为缺失值,利用缺失值处理的方法进行处理;

(3)平均值修正:可用前后两个观测值的平均值修正该异常值;

其次、如果使用的模型对异常值不是很敏感,那么建议直接在具有异常值的数据集上进行数据挖掘;

参考文献:

【1】python-异常值分析
【2】数据预处理之异常值处理
【3】机器学习中的异常值检测和处理

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。