数据异常值检测方法汇总and异常值处理
ztj100 2025-01-05 01:00 13 浏览 0 评论
昨天介绍了数据的标准化处理方法《数据标准化(归一化)》,里面介绍了常见的方法。而且数据里面有异常值的情况下不同方法的作用性也不一样。今天就来详细介绍一下数据异常值的检测方法,以及如何处理异常值。
异常值检测与处理是数据清洗过程中的一个关键步骤,它涉及到识别和处理那些与大多数数据显著不同的数据点。异常值可能是由于数据录入错误、测量误差、数据损坏或其他原因造成的。处理异常值的目的是提高数据的质量,避免它们对分析结果产生不利影响。以下是异常值检测与处理的详细介绍。
【异常值检测】
整体分成6类13中方法来进行异常值的检测,目录如下↓
下面分别介绍一下每一种方法,然后通过正态分布和非正态分布两种数据进行演示,先把数据生成一下,代码和结果如下↓
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import LocalOutlierFactor
from sklearn.cluster import DBSCAN
from sklearn.ensemble import IsolationForest
from sklearn.svm import OneClassSVM
from sklearn.decomposition import PCA
from scipy import stats
from sklearn.mixture import GaussianMixture
# 生成正态分布和非正态分布数据集
np.random.seed(21)
X_normal = np.random.normal(loc=0, scale=3, size=100)
X_uniform = np.random.uniform(low=-5, high=5, size=100)
# 添加异常值
X_normal_with_outliers = np.append(X_normal, [10, 15, -10, -15])
X_uniform_with_outliers = np.append(X_uniform, [10, 15, -10, -15])
# 可视化函数
def plot_data(X, outliers, title):
plt.figure(figsize=(10, 6))
plt.scatter(range(len(X)), X, edgecolor='k', s=20, label='Data')
plt.scatter(outliers, X[outliers], color='red', edgecolor='k', s=50, label='Outliers')
plt.title(title)
plt.legend()
plt.show()
绘制图形↓
plt.hist(X_normal_with_outliers.flatten(), bins=50, color='blue', alpha=0.7)
plt.hist(X_uniform_with_outliers.flatten(), bins=30, color='green', alpha=0.7)
【统计方法-标准差法】
也称3σ准则,假设数据符合正态分布,通过计算均值和标准差,将超过均值±3倍标准差的值视为异常值。优点是简单易行,适用于正态分布的数据。缺点是对非正态分布的数据效果较差,对极端值敏感。
def detect_outliers_std(X):
mean = np.mean(X)
std = np.std(X)
outliers = np.where((X > mean + 3 * std) | (X < mean - 3 * std))
return outliers
outliers_std_normal = detect_outliers_std(X_normal_with_outliers)
outliers_std_uniform = detect_outliers_std(X_uniform_with_outliers)
plot_data(X_normal_with_outliers, outliers_std_normal[0], 'Standard Deviation Method -正态分布+异常值')
plot_data(X_uniform_with_outliers, outliers_std_uniform[0], 'Standard Deviation Method -非正态分布+异常值')
【统计方法-Z-Score法】
标准化数据,根据Z值(通常±3)来检测异常值。优点是与标准差法类似,适用于正态分布的数据。缺点是同样对非正态分布的数据效果较差。
def detect_outliers_zscore(X):
z_scores = np.abs(stats.zscore(X))
outliers = np.where(z_scores > 3)
return outliers
outliers_zscore_normal = detect_outliers_zscore(X_normal_with_outliers)
outliers_zscore_uniform = detect_outliers_zscore(X_uniform_with_outliers)
plot_data(X_normal_with_outliers, outliers_zscore_normal[0], 'Z-Score Method - 正态分布+异常值')
plot_data(X_uniform_with_outliers, outliers_zscore_uniform[0], 'Z-Score Method - 非正态分布+异常值')
【统计方法-箱线图法】
使用四分位数(Q1和Q3)和四分位距(IQR),超过Q1-1.5倍IQR或Q3+1.5倍IQR的值视为异常值。优点是适用于任何分布的数据,对数据分布的要求较低。缺点是对异常值比例较高的数据效果不佳。
def detect_outliers_iqr(X):
Q1 = np.percentile(X, 25)
Q3 = np.percentile(X, 75)
IQR = Q3 - Q1
outliers = np.where((X < Q1 - 1.5 * IQR) | (X > Q3 + 1.5 * IQR))
return outliers
outliers_iqr_normal = detect_outliers_iqr(X_normal_with_outliers)
outliers_iqr_uniform = detect_outliers_iqr(X_uniform_with_outliers)
plot_data(X_normal_with_outliers, outliers_iqr_normal[0], 'IQR Method - 正态分布+异常值')
plot_data(X_uniform_with_outliers, outliers_iqr_uniform[0], 'IQR Method - 非正态分布+异常值')
【基于距离的方法-K-最近邻】
KNN,计算每个数据点与其最近的k个邻居的距离,显著大于其他点的距离则为异常值。优点是无需对数据分布有假设,适用于多维数据。缺点是计算复杂度较高,参数k的选择较敏感。
def detect_outliers_knn(X, k=3):
clf = LocalOutlierFactor(n_neighbors=k)
y_pred = clf.fit_predict(X.reshape(-1, 1))
outliers = np.where(y_pred == -1)
return outliers
outliers_knn_normal = detect_outliers_knn(X_normal_with_outliers)
outliers_knn_uniform = detect_outliers_knn(X_uniform_with_outliers)
plot_data(X_normal_with_outliers, outliers_knn_normal[0], 'KNN Method - 正态分布+异常值')
plot_data(X_uniform_with_outliers, outliers_knn_uniform[0], 'KNN Method - 非正态分布+异常值')
【基于距离的方法-局部离群因子】
LOF,比较一个点与其邻居的局部密度,检测局部异常值。优点是能够检测局部异常值,适用于多维数据。缺点是参数选择较为复杂,计算复杂度较高。
def detect_outliers_lof(X, n_neighbors=20):
clf = LocalOutlierFactor(n_neighbors=n_neighbors)
y_pred = clf.fit_predict(X.reshape(-1, 1))
outliers = np.where(y_pred == -1)
return outliers
outliers_lof_normal = detect_outliers_lof(X_normal_with_outliers)
outliers_lof_uniform = detect_outliers_lof(X_uniform_with_outliers)
plot_data(X_normal_with_outliers, outliers_lof_normal[0], 'LOF Method - 正态分布+异常值')
plot_data(X_uniform_with_outliers, outliers_lof_uniform[0], 'LOF Method - 非正态分布+异常值')
【基于密度的方法-DBSCAN】
基于密度的聚类方法,找到密度较低的区域来识别异常值。优点是能找到任意形状的聚类,适用于空间密度不均匀的数据。缺点是参数选择较为复杂,对高维数据效果较差。
def detect_outliers_dbscan(X, eps=0.5, min_samples=5):
clf = DBSCAN(eps=eps, min_samples=min_samples)
y_pred = clf.fit_predict(X.reshape(-1, 1))
outliers = np.where(y_pred == -1)
return outliers
outliers_dbscan_normal = detect_outliers_dbscan(X_normal_with_outliers)
outliers_dbscan_uniform = detect_outliers_dbscan(X_uniform_with_outliers)
plot_data(X_normal_with_outliers, outliers_dbscan_normal[0], 'DBSCAN Method - 正态分布+异常值')
plot_data(X_uniform_with_outliers, outliers_dbscan_uniform[0], 'DBSCAN Method - 非正态分布+异常值')
【基于模型的方法-孤立森林】
Isolation Forest,基于随机森林的思想,构建多棵树,通过分裂的次数来衡量异常值。优点是适用于大数据集,对数据分布无假设。缺点是参数调优复杂,对小数据集效果不佳。
def detect_outliers_isolation_forest(X):
clf = IsolationForest(contamination=0.05)
y_pred = clf.fit_predict(X.reshape(-1, 1))
outliers = np.where(y_pred == -1)
return outliers
outliers_isolation_normal = detect_outliers_isolation_forest(X_normal_with_outliers)
outliers_isolation_uniform = detect_outliers_isolation_forest(X_uniform_with_outliers)
plot_data(X_normal_with_outliers, outliers_isolation_normal[0], 'Isolation Forest Method - 正态分布+异常值')
plot_data(X_uniform_with_outliers, outliers_isolation_uniform[0], 'Isolation Forest Method - 非正态分布+异常值')
【基于模型的方法-一类支持向量机】
One-Class SVM,构建一个边界来识别异常值。优点是适用于高维数据,对数据分布无假设。缺点是计算复杂度高,对参数敏感。
def detect_outliers_one_class_svm(X):
clf = OneClassSVM(nu=0.05, kernel='rbf', gamma=0.1)
y_pred = clf.fit_predict(X.reshape(-1, 1))
outliers = np.where(y_pred == -1)
return outliers
outliers_one_class_svm_normal = detect_outliers_one_class_svm(X_normal_with_outliers)
outliers_one_class_svm_uniform = detect_outliers_one_class_svm(X_uniform_with_outliers)
plot_data(X_normal_with_outliers, outliers_one_class_svm_normal[0], 'One-Class SVM Method - 正态分布+异常值')
plot_data(X_uniform_with_outliers, outliers_one_class_svm_uniform[0], 'One-Class SVM Method - 非正态分布+异常值')
【基于回归的方法-残差分析】
利用回归模型,分析残差,如果残差值过大,则可能是异常值。优点是结合了回归分析,适用于时间序列数据。缺点是依赖于模型的准确性,适用于线性关系的数据。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
# 生成线性数据集
np.random.seed(42)
X = np.arange(100)
y = 3 * X + 7 + np.random.normal(0, 10, size=X.shape)
# 添加异常值
X_with_outliers = np.append(X, [20, 50, 80])
y_with_outliers = np.append(y, [1000, -1000, 500])
# 基于回归方法的异常值检测 - 残差分析
def detect_outliers_residual_analysis(X, y):
X = X.reshape(-1, 1)
model = LinearRegression()
model.fit(X, y)
predictions = model.predict(X)
residuals = y - predictions
residual_std = np.std(residuals)
residual_mean = np.mean(residuals)
outliers = np.where(np.abs(residuals) > 3 * residual_std)
return outliers
# 检测数据集中的异常值
outliers_residual = detect_outliers_residual_analysis(X_with_outliers, y_with_outliers)
# 可视化原始数据和异常值
plt.figure(figsize=(10, 6))
plt.scatter(X_with_outliers, y_with_outliers, edgecolor='k', s=20, label='Data')
plt.scatter(X_with_outliers[outliers_residual], y_with_outliers[outliers_residual], color='red', edgecolor='k', s=50, label='Outliers')
plt.plot(X, 3 * X + 7, color='blue', linewidth=2, label='True Function')
plt.title('Residual Analysis Method (with Outliers)')
plt.legend()
plt.show()
【其他方法-主成分分析】
PCA,通过降维,分析主成分,找出在主成分空间中偏离较远的数据点。优点是降维后检测异常值,适用于多维数据。缺点是解释性较差,适用于线性关系的数据。
def detect_outliers_pca(X, n_components=1):
pca = PCA(n_components=n_components)
X_pca = pca.fit_transform(X.reshape(-1, 1))
outliers = detect_outliers_zscore(X_pca)
return outliers
outliers_pca_normal = detect_outliers_pca(X_normal_with_outliers)
outliers_pca_uniform = detect_outliers_pca(X_uniform_with_outliers)
plot_data(X_normal_with_outliers, outliers_pca_normal[0], 'PCA Method - 正态分布+异常值')
plot_data(X_uniform_with_outliers, outliers_pca_uniform[0], 'PCA Method - 非正态分布+异常值')
【其他方法-高斯混合模型】
GMM,假设数据由多个高斯分布组成,找出概率较低的点。优点是适用于复杂分布的数据。缺点是计算复杂度较高,需选择适当的分布数量。
def detect_outliers_gmm(X, n_components=1):
gmm = GaussianMixture(n_components=n_components, covariance_type='full')
gmm.fit(X.reshape(-1, 1))
scores = gmm.score_samples(X.reshape(-1, 1))
threshold = np.percentile(scores, 5)
outliers = np.where(scores < threshold)
return outliers
outliers_gmm_normal = detect_outliers_gmm(X_normal_with_outliers, n_components=1)
outliers_gmm_uniform = detect_outliers_gmm(X_uniform_with_outliers, n_components=1)
plot_data(X_normal_with_outliers, outliers_gmm_normal[0], 'GMM Method - 正态分布+异常值')
plot_data(X_uniform_with_outliers, outliers_gmm_uniform[0], 'GMM Method - 非正态分布+异常值')
下面是一些建议,根据需要检测数据的维度不同,可以选择不同的检验方法。
一维数据建议:标准差法,箱线图法(IQR法),Z-Score法;
二维数据建议:残差分析,K-最近邻(KNN),局部离群因子(LOF),DBSCAN;
多维数据建议:孤立森林(Isolation Forest),一类支持向量机(One-Class SVM),主成分分析(PCA),高斯混合模型(GMM)。
【异常值处理】
【删除异常值数据】
直接删除检测到的异常值。优点:简单直接,能有效去除异常值。缺点:可能丢失重要信息,尤其在数据量较小的情况下。
def remove_outliers(X, outliers):
return np.delete(X, outliers, axis=0)
X_normal_no_outliers = remove_outliers(X_normal_with_outliers, outliers_gmm_normal)
X_uniform_no_outliers = remove_outliers(X_uniform_with_outliers, outliers_gmm_uniform)
plot_data(X_normal_no_outliers, [], 'Removed Outliers - Normal')
plot_data(X_uniform_no_outliers, [], 'Removed Outliers - Uniform')
【均值/中位数替换】
将异常值替换为数据的均值或中位数。优点:能保持数据规模,对大多数情况适用。缺点:可能掩盖数据的真实波动。
def replace_with_mean(X, outliers):
mean = np.mean(X, axis=0)
X[outliers] = mean
return X
X_normal_mean_replaced = replace_with_mean(X_normal_with_outliers.copy(), outliers_std_normal)
X_uniform_mean_replaced = replace_with_mean(X_uniform_with_outliers.copy(), outliers_std_uniform)
【前/后值替换】
在时间序列数据中,使用前一个或后一个值替换异常值。优点:简单直接,适用于时间序列数据。缺点:可能引入滞后效应,影响数据的真实性。
def replace_with_previous(X, outliers):
for outlier in outliers[0]:
if outlier == 0:
X[outlier] = X[outlier + 1]
else:
X[outlier] = X[outlier - 1]
return X
X_normal_prev_replaced = replace_with_previous(X_normal_with_outliers.copy(), outliers_std_normal)
X_uniform_prev_replaced = replace_with_previous(X_uniform_with_outliers.copy(), outliers_std_uniform)
【插值法】
利用线性插值或其他插值方法替换异常值。优点:能保持数据的连续性和趋势。缺点:对插值方法的选择较为敏感。
def interpolate_outliers(X, outliers):
for outlier in outliers[0]:
if outlier == 0:
X[outlier] = X[outlier + 1]
elif outlier == len(X) - 1:
X[outlier] = X[outlier - 1]
else:
X[outlier] = (X[outlier - 1] + X[outlier + 1]) / 2
return X
X_normal_interpolated = interpolate_outliers(X_normal_with_outliers.copy(), outliers_std_normal)
X_uniform_interpolated = interpolate_outliers(X_uniform_with_outliers.copy(), outliers_std_uniform)
【对数变换】
对数据进行对数变换,可以减小异常值的影响。优点:适用于具有指数分布的数据。缺点:不能处理负值和零值,适用范围有限。
def log_transform(X):
return np.log1p(X) # log1p能处理X中的0值
X_normal_log_transformed = log_transform(X_normal_with_outliers)
X_uniform_log_transformed = log_transform(X_uniform_with_outliers)
【平方根变换】
通过平方根变换减少异常值的影响。优点:适用于具有正偏态分布的数据。缺点:对负值和零值不适用。
def sqrt_transform(X):
return np.sqrt(X)
X_normal_sqrt_transformed = sqrt_transform(X_normal_with_outliers)
X_uniform_sqrt_transformed = sqrt_transform(X_uniform_with_outliers)
【标准化】
将数据缩放到一个标准正态分布。优点:消除量纲影响,适用于多种分析方法。缺点:对非正态分布的数据效果一般。
def standardize(X):
return (X - np.mean(X, axis=0)) / np.std(X, axis=0)
X_normal_standardized = standardize(X_normal_with_outliers)
X_uniform_standardized = standardize(X_uniform_with_outliers)
【归一化】
将数据缩放到[0, 1]的范围内。优点:适用于范围差异较大的数据。缺点:对异常值敏感,可能被极端值影响。
def normalize(X):
min_val = np.min(X, axis=0)
max_val = np.max(X, axis=0)
return (X - min_val) / (max_val - min_val)
X_normal_normalized = normalize(X_normal_with_outliers)
X_uniform_normalized = normalize(X_uniform_with_outliers)
【鲁棒统计量】
使用中位数和四分位数等对异常值不敏感的统计量。优点:对异常值不敏感,适用于非正态分布的数据。缺点:不能完全消除异常值的影响。
def robust_standardize(X):
median = np.median(X, axis=0)
IQR = np.percentile(X, 75, axis=0) - np.percentile(X, 25, axis=0)
return (X - median) / IQR
X_normal_robust_standardized = robust_standardize(X_normal_with_outliers)
X_uniform_robust_standardized = robust_standardize(X_uniform_with_outliers)
通过这些示例,我们可以看到各种异常值处理方法在处理数据异常值时的效果。不同的方法适用于不同类型的数据和场景,选择合适的方法可以有效提高数据分析的准确性和可靠性。
链接是我使用PowerBI整合的历史文章,按类型分类,可以根据需求查询:Microsoft Power BI↓
https://app.powerbi.com/view?r=eyJrIjoiNjI2NWQ3NjktYjU0ZC00ZWZhLTgzMDgtMGI4ZTk1ZDlkODM3IiwidCI6IjI3NDQ3MWQ0LTM4ZDQtNDVlZS1hMmJkLWU1NTVhOTBkYzM4NiJ9
End
- 上一篇:21数据预处理:标准化
- 下一篇:一文搞懂 NumPy 统计函数
相关推荐
- Vue 技术栈(全家桶)(vue technology)
-
Vue技术栈(全家桶)尚硅谷前端研究院第1章:Vue核心Vue简介官网英文官网:https://vuejs.org/中文官网:https://cn.vuejs.org/...
- vue 基础- nextTick 的使用场景(vue的nexttick这个方法有什么用)
-
前言《vue基础》系列是再次回炉vue记的笔记,除了官网那部分知识点外,还会加入自己的一些理解。(里面会有部分和官网相同的文案,有经验的同学择感兴趣的阅读)在开发时,是不是遇到过这样的场景,响应...
- vue3 组件初始化流程(vue组件初始化顺序)
-
学习完成响应式系统后,咋们来看看vue3组件的初始化流程既然是看vue组件的初始化流程,咋们先来创建基本的代码,跑跑流程(在app.vue中写入以下内容,来跑流程)...
- vue3优雅的设置element-plus的table自动滚动到底部
-
场景我是需要在table最后添加一行数据,然后把滚动条滚动到最后。查网上的解决方案都是读取html结构,暴力的去获取,虽能解决问题,但是不喜欢这种打补丁的解决方案,我想着官方应该有相关的定义,于是就去...
- Vue3为什么推荐使用ref而不是reactive
-
为什么推荐使用ref而不是reactivereactive本身具有很大局限性导致使用过程需要额外注意,如果忽视这些问题将对开发造成不小的麻烦;ref更像是vue2时代optionapi的data的替...
- 9、echarts 在 vue 中怎么引用?(必会)
-
首先我们初始化一个vue项目,执行vueinitwebpackechart,接着我们进入初始化的项目下。安装echarts,npminstallecharts-S//或...
- 无所不能,将 Vue 渲染到嵌入式液晶屏
-
该文章转载自公众号@前端时刻,https://mp.weixin.qq.com/s/WDHW36zhfNFVFVv4jO2vrA前言...
- vue-element-admin 增删改查(五)(vue-element-admin怎么用)
-
此篇幅比较长,涉及到的小知识点也比较多,一定要耐心看完,记住学东西没有耐心可不行!!!一、添加和修改注:添加和编辑用到了同一个组件,也就是此篇文章你能学会如何封装组件及引用组件;第二能学会async和...
- 最全的 Vue 面试题+详解答案(vue面试题知识点大全)
-
前言本文整理了...
- 基于 vue3.0 桌面端朋友圈/登录验证+60s倒计时
-
今天给大家分享的是Vue3聊天实例中的朋友圈的实现及登录验证和倒计时操作。先上效果图这个是最新开发的vue3.x网页端聊天项目中的朋友圈模块。用到了ElementPlus...
- 不来看看这些 VUE 的生命周期钩子函数?| 原力计划
-
作者|huangfuyk责编|王晓曼出品|CSDN博客VUE的生命周期钩子函数:就是指在一个组件从创建到销毁的过程自动执行的函数,包含组件的变化。可以分为:创建、挂载、更新、销毁四个模块...
- Vue3.5正式上线,父传子props用法更丝滑简洁
-
前言Vue3.5在2024-09-03正式上线,目前在Vue官网显最新版本已经是Vue3.5,其中主要包含了几个小改动,我留意到日常最常用的改动就是props了,肯定是用Vue3的人必用的,所以针对性...
- Vue 3 生命周期完整指南(vue生命周期及使用)
-
Vue2和Vue3中的生命周期钩子的工作方式非常相似,我们仍然可以访问相同的钩子,也希望将它们能用于相同的场景。...
- 救命!这 10 个 Vue3 技巧藏太深了!性能翻倍 + 摸鱼神器全揭秘
-
前端打工人集合!是不是经常遇到这些崩溃瞬间:Vue3项目越写越卡,组件通信像走迷宫,复杂逻辑写得脑壳疼?别慌!作为在一线摸爬滚打多年的老前端,今天直接甩出10个超实用的Vue3实战技巧,手把...
- 怎么在 vue 中使用 form 清除校验状态?
-
在Vue中使用表单验证时,经常需要清除表单的校验状态。下面我将介绍一些方法来清除表单的校验状态。1.使用this.$refs...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- Vue 技术栈(全家桶)(vue technology)
- vue 基础- nextTick 的使用场景(vue的nexttick这个方法有什么用)
- vue3 组件初始化流程(vue组件初始化顺序)
- vue3优雅的设置element-plus的table自动滚动到底部
- Vue3为什么推荐使用ref而不是reactive
- 9、echarts 在 vue 中怎么引用?(必会)
- 无所不能,将 Vue 渲染到嵌入式液晶屏
- vue-element-admin 增删改查(五)(vue-element-admin怎么用)
- 最全的 Vue 面试题+详解答案(vue面试题知识点大全)
- 基于 vue3.0 桌面端朋友圈/登录验证+60s倒计时
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- node卸载 (33)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- exceptionininitializererror (33)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)