删除异常值方法总结

推荐资料:14种异常检测方法总结
前提:

import pandas as pd
import numpy as np
import os

import seaborn as sns
from pyod.models.mad import MAD
from pyod.models.knn import KNN
from pyod.models.lof import LOF
import matplotlib.pyplot as plt
from sklearn.ensemble import IsolationForest

1.IQR
在这里插入图片描述
python基于IQR删除异常值:

df = pd.read_excel('./7.xlsx')

def fit_model(model, data, column='Area'):
    # fit the model and predict it
    df = data.copy()
    data_to_predict = data[column].to_numpy().reshape(-1, 1)
    predictions = model.fit_predict(data_to_predict)
    df['Predictions'] = predictions
    
    return df

def plot_anomalies(df, x='Date', y='Area'):

    # categories will be having values from 0 to n
    # for each values in 0 to n it is mapped in colormap
    categories = df['Predictions'].to_numpy()
    colormap = np.array(['g', 'r'])

    f = plt.figure(figsize=(12/2.54, 6/2.54))
    f = plt.scatter(df[x], df[y], c=colormap[categories])
    f = plt.xlabel(x)
    f = plt.ylabel(y)
    f = plt.xticks(rotation=0)
    plt.show()
    
#IQR
def find_anomalies(value, lower_threshold, upper_threshold):
    
    if value < lower_threshold or value > upper_threshold:
        return 1
    else: return 0
    
def area_anomaly_detector(data, column='Area', threshold=1.1):
    
    df = data.copy()
    quartiles = dict(data[column].quantile([.25, .50, .75]))
    quartile_3, quartile_1 = quartiles[0.75], quartiles[0.25]
    area = quartile_3 - quartile_1

    lower_threshold = quartile_1 - (threshold * area)
    upper_threshold = quartile_3 + (threshold * area)

    print(f"Lower threshold: {lower_threshold}, \nUpper threshold: {upper_threshold}\n")
    
    df['Predictions'] = data[column].apply(find_anomalies, args=(lower_threshold, upper_threshold))
    return df

area_df = area_anomaly_detector(df)
plot_anomalies(area_df)

在这里插入图片描述
(红色为异常值)
2.Isolation Forest(隔离森林算法)

  • 孤立森林是基于决策树的算法。从给定的特征集合中随机选择特征,然后在特征的最大值和最小值间随机选择一个分割值,来隔离离群值。这种特征的随机划分会使异常数据点在树中生成的路径更短,从而将它们和其他数据分开。
  • 在高维数据集中执行离群值检测的一种有效方法是使用随机森林。
  • 属于无监督学习算法。
    在这里插入图片描述
    模型参数:
  • 评估器数量:n_estimators 表示集成的基评估器或树的数量,即孤立森林中树的数量。这是一个可调的整数参数,默认值是 100;
  • 最大样本:max_samples 是训练每个基评估器的样本的数量。如果 max_samples
    比样本量更大,那么会用所用样本训练所有树。max_samples 的默认值是『auto』。如果值为『auto』的话,那么
    max_samples=min(256, n_samples);
  • 数据污染问题:算法对这个参数非常敏感,它指的是数据集中离群值的期望比例,根据样本得分拟合定义阈值时使用。默认值是『auto』。如果取『auto』值,则根据孤立森林的原始论文定义阈值;
  • 最大特征:所有基评估器都不是用数据集中所有特征训练的。这是从所有特征中提出的、用于训练每个基评估器或树的特征数量。该参数的默认值是 1。
model=IsolationForest(n_estimators=50, max_samples='auto', contamination=float(0.1),max_features=1.0)
model.fit(df[['area']])

算法实现:
直接调用包: from sklearn.ensemble import IsolationForest

iso_forest = IsolationForest(n_estimators=125)
iso_df = fit_model(iso_forest, df)
iso_df['Predictions'] = iso_df['Predictions'].map(lambda x: 1 if x==-1 else 0)
plot_anomalies(iso_df)

在这里插入图片描述

3.MAD(Median Absolute Deviation)
中位数绝对偏差是每个观测值与这些观测值中位数之间的差值。
在这里插入图片描述
算法实现:调用from pyod.models.mad import MAD

#MAD
#threshold : float, optional (default=3.5)
       # The modified z-score to use as a threshold. Observations with
       # a modified z-score (based on the median absolute deviation) greater
       # than this value will be classified as outliers.
mad_model = MAD()
mad_df = fit_model(mad_model, df)
plot_anomalies(mad_df)

Z-score分布图
What is a Modified Z-Score? (Definition & Example):https://www.statology.org/modified-z-score/
(1) 在统计学中,z分数表示一个值离均值有多少个标准差。公式为:

Z-Score = (xi – μ) / σ

  • xi: A single data value;
  • μ: The mean of the dataset;
  • σ: The standard deviation of the dataset.

(2) z分数通常用于检测数据集中的异常值。例如,z分数小于-3或大于3的观察结果通常被认为是离群值。然而,z分数可能会受到异常大或小的数据值的影响,所以需要修正的Z值:

Modified z-score = 0.6745(xi – x̃) / MAD

  • x̃: The median of the dataset;
  • MAD: The median absolute deviation of the dataset;

Iglewicz和Hoaglin建议,修改后的z值小于-3.5或大于3.5的值被标记为潜在的离群值。
修改后的z-score更稳健,因为它使用中值来计算z-score,而不是已知的受异常值影响的平均值。
在这里插入图片描述
(转载自wikipedia)

在这里插入图片描述
更新:整体代码

#test
df = pd.read_excel(r'./1.xlsx')

filter_data = df[(df['1']==0)]
# print(filter_data)

#filter data by MAD
#threshold : float, optional (default=3.5)
       # The modified z-score to use as a threshold. Observations with
       # a modified z-score (based on the median absolute deviation) greater
       # than this value will be classified as outliers.
def fit_model(model, data, column='Area'):
    # fit the model and predict it
    df = data.copy()
    data_to_predict = data[column].to_numpy().reshape(-1, 1)
    predictions = model.fit_predict(data_to_predict)
    df['Predictions1'] = predictions
    
    return df

def plot_anomalies(df, x='Date', y='Area'):

    # categories will be having values from 0 to n
    # for each values in 0 to n it is mapped in colormap
    categories = df['Predictions1'].to_numpy()
    colormap = np.array(['g', 'r'])

    f = plt.figure(figsize=(12/2.54, 6/2.54))
    f = plt.scatter(df[x], df[y], c=colormap[categories])
    f = plt.xlabel(x)
    f = plt.ylabel(y)
    f = plt.xticks(rotation=0)
    plt.show()

mad_model = MAD()
mad_df = fit_model(mad_model, df)
plot_anomalies(mad_df)

MAD算法:

def _mad(self, X):
        """
        Apply the robust median absolute deviation (MAD)
        to measure the distances of data points from the median.

        Returns
        -------
        numpy array containing modified Z-scores of the observations.
        The greater the score, the greater the outlierness.
        """
        obs = np.reshape(X, (-1, 1))
        # `self.median` will be None only before `fit()` is called
        self.median = np.nanmedian(obs) if self.median is None else self.median
        diff = np.abs(obs - self.median)
        self.median_diff = np.median(diff) if self.median_diff is None else self.median_diff
        return np.nan_to_num(np.ravel(0.6745 * diff / self.median_diff))

R语言中实现MAD算法:

mad(x, center = median(x), constant = 1.4826, na.rm = FALSE,
    low = FALSE, high = FALSE)

参数说明:https://www.math.ucla.edu/~anderson/rw1001/library/base/html/mad.html
在这里插入图片描述

总结:
PyOD是一个全面的、可扩展的Python工具包,可以用来检测异常值。可以直接调用里面的模型。
PyOD网址:https://github.com/yzhao062/pyod

使用方法:如调用MAD模型

# train the MAD detector
from pyod.models.mad import MAD
clf = MAD()
clf.fit(X_train)

# get outlier scores
y_train_scores = clf.decision_scores_  # raw outlier scores on the train data
y_test_scores = clf.decision_function(X_test)  # predict raw outlier scores on test

参考资料:
A walkthrough of Univariate Anomaly Detection in Python(很好学习资料):https://www.analyticsvidhya.com/blog/2021/06/univariate-anomaly-detection-a-walkthrough-in-python/

隔离森林算法:https://blog.csdn.net/ChenVast/article/details/82863750

异常值检测总结pyod包:https://blog.csdn.net/weixin_43822124/article/details/112523303

pyod包:https://blog.csdn.net/weixin_41697507/article/details/89408236?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2.pc_relevant_default&utm_relevant_index=2

更新20220729
1.参考资料:异常检测专题(2)- 统计学方法 https://zhuanlan.zhihu.com/p/343748853
这里提到一种非参数方法,基于直方图的算法,Histogram-based Outlier Score (HBOS)。

它的思路是假定每个维度之间相互独立,分别计算每个维度的概率密度,最后合并成总体的概率密度,再根据概率密度计算异常分数值。

优点:HBOS方法的优势是计算速度较快,对大数据集友好。
缺点:但是异常识别的效果一般,且针对特征间比较独立的场景。

总之,HBOS在全局异常检测问题上表现良好,但不能检测局部异常值。但是HBOS比标准算法快得多,尤其是在大数据集上。

公式:
在这里插入图片描述
2.几种过滤数据的方法:http://cms.dt.uh.edu/faculty/delavinae/F03/3309/Ch03bHandout.PDF
在这里插入图片描述
图片截取自:http://cms.dt.uh.edu/faculty/delavinae/F03/3309/Ch03bHandout.PDF

在这里插入图片描述

<think>嗯,用户问怎么删除异常,这个问题在数据处理中挺常见的。首先,我需要回忆一下处理异常的基本步骤,确保自己理解正确。然后,得想想用户可能的背景,可能是学生或者刚接触数据分析的人,需要比较基础的解释,但也不能太简单,可能他们需要实际操作的方法。 首先,得明确什么是异常。异常就是明显偏离其他数据点的观测,可能由测量误差、录入错误或者真实但极端的情况引起。用户可能想知道怎么识别和删除这些,所以需要分步骤讲解。 接下来,识别异常方法有很多,常用的有Z-score、IQR、可视化方法如箱线图。这些方法各有优缺点,得逐一解释清楚。比如Z-score适用于正态分布的数据,而IQR对非正态分布更稳健。可能用户的数据分布不同,需要选择合适的方法。 然后,删除异常的步骤。首先需要检测,然后根据情况处理,比如删除、替换或者保留。这里用户明确说“删除”,所以重点讲删除的步骤。但也要提醒用户谨慎,不能盲目删除,可能有些异常是有意义的。 还要考虑不同数据类型的处理,比如单变量和多变量情况。用户可能只考虑单变量,但多变量方法如DBSCAN或者孤立森林也应该提一下,扩展他们的知识面。 另外,要注意LaTeX格式的问题,用户给的系统指令要求数学公式用$...$和$$...$$。在解释Z-score和IQR时,公式要正确使用语法,比如Z = (X - μ)/σ,还有IQR的计算公式。这部分要检查是否正确,避免格式错误。 可能用户需要具体的例子或者代码,比如用Python的pandas或numpy实现。虽然用户没有明确要求代码,但提供示例代码会更有帮助,尤其是实际应用部分。不过根据用户的指令,结构要清晰,分步骤讲解,所以可能需要将代码放在最后作为补充。 还要注意提醒用户处理后的验证,比如删除后再次检查数据分布,或者重新建模查看效果。这也是处理异常的重要步骤,避免误删有效数据。 最后,注意事项部分需要强调不要过度删除,结合业务背景判断,以及处理后的影响分析。用户可能没有考虑到这些方面,需要给出建议,确保他们正确应用方法。 总结一下,回答的结构应该是:先定义异常,再讲识别方法,然后处理步骤,接着实际应用示例,最后注意事项。这样用户能一步步跟着操作,同时理解背后的原理。同时,注意用中文,LaTeX格式正确,分点清晰,帮助用户真正解决问题。</think>删除异常需要根据数据特征选择合适的方法,并谨慎处理以避免信息损失。以下是分步骤操作指南: ++++ 一、异常定义与识别 1. 定义:异常指明显偏离数据集主体分布的观测,常见产生原因: • 测量误差(如传感器故障) • 录入错误(如小数点错位) • 真实但极端事件(如天文观测中的超新星爆发) 2. 常用识别方法: (1)Z-score法(适合正态分布数据) $$ z = \frac{x - \mu}{\sigma} $$ 当$|z| > 3$时视为异常(99.7%数据在$3\sigma$内) (2)IQR法(适合非正态分布) $$ \text{IQR} = Q3 - Q1 $$ 异常范围:$ < Q1 - 1.5\text{IQR}$ 或 $> Q3 + 1.5\text{IQR}$ (3)可视化检测: - 箱线图:直观显示IQR范围 - 散点图:观察数据点分布形态 - 直方图:识别分布尾部极端 ++++ 二、删除操作步骤 1. 单变量处理: (1) 计算数据描述统计量: ```python import pandas as pd df.describe() ``` (2) 使用IQR过滤: ```python Q1 = df['col'].quantile(0.25) Q3 = df['col'].quantile(0.75) IQR = Q3 - Q1 df_clean = df[~((df['col'] < (Q1 - 1.5*IQR)) | (df['col'] > (Q3 + 1.5*IQR)))] ``` 2. 多变量处理: - 聚类分析(如DBSCAN) - 孤立森林(Isolation Forest) ```python from sklearn.ensemble import IsolationForest clf = IsolationForest(contamination=0.05) outliers = clf.fit_predict(X) df_clean = df[outliers == 1] ``` ++++ 三、注意事项 1. 保留原始数据副本:建议新建DataFrame进行操作 2. 验证处理效果: - 处理后重新绘制分布图 - 对比处理前后描述统计量变化 3. 特殊情形处理: - 时间序列数据:需考虑季节性因素 - 空间数据:使用地理加权方法 - 高维数据:采用马氏距离法 ++++ 四、替代方案(当不宜直接删除时) 1. 数据替换: - 用上下限替换:`np.clip()` - 用中位数/均填充 2. 分箱处理: ```python pd.cut(df['col'], bins=5) ``` 3. 保留标记:新增异常标识列 建议先通过可视化确认异常性质,结合业务背景判断是否为真实异常。处理前后应记录操作日志,确保分析过程可追溯。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值