网易首页 > 网易号 > 正文 申请入驻

代码详解:适用20种算法的PyOD库,检测异常值如此优秀

0
分享至

全文共4001字,预计学习时长8分钟

数据探索没有捷径可走。如果你跳过数据科学项目阶段,直接进入到构建模型的阶段,经过一段时间后,你会发现准确度会达到上限——模型的性能不会提高。

这是因为异常值(也称为“离散值”)这个经常被我们忽略的问题。诱因就在于根据给定的数据开始建立模型——但这实际上是有问题的。

数据探索包括许多因素,例如变量识别、缺失值处理、特征工程等。检测和处理异常值也是数据探索阶段的主要因素。输入的质量决定了输出的质量,所以我们应该首先消除数据中的杂质,以便构建更好的模型。

PyOD是一个用于检测数据中异常值的库,它能对20多种不同的算法进行访问,以检测异常值,并能够与Python 2和3兼容。

本文将带你了解异常值以及如何使用Python中的PyOD检测异常值(假设你已经具有机器学习算法和Python语言的基本知识)。

目录

1. 什么是异常值?

2. 为什么需要检测异常值?

3. 为什么使用PyOD检测异常值?

4. PyOD库的特征

5. 使用Python安装PyOD

6. PyOD库中使用的部分异常值检测算法

7. PyOD提供的额外工具

8. PyoD在Python中的运用

1. 什么是异常值?

异常值是任何与数据集中其余观察值不同的数据点。让我们看一些真实的例子来理解异常值检测:

· 一名学生的平均成绩超过90%而班上其余学生的平均成绩达到70%时——这就是一个明确的异常值。

· 在分析某个客户的购买模式时,突然出现了非常高的值。虽然他/她的大部分交易金额都低于10,000卢比,但是这个交易的金额是100,000卢比。这可能是购买了一个电子产品——无论什么原因,它是整体数据的异常值。

· 尤塞恩·博尔特怎么样?当你考虑到大多数运动员的成绩时,那些破纪录的短跑绝对是异常值。

存在异常值的原因有很多。也许是分析师在数据输入中出错,或者机器在测量中引起错误,或者是故意出现异常值。有些人不想透露他们的信息,因此在表格中输入虚假信息。

异常值有两种类型:单变量和多变量。单变量异常值是仅由一个变量中的极值组成的数据点,而多变量异常值是至少两个变量的组合异常分数。假设有三个不同的变量——X,Y,Z。如果在三维空间中绘制这些变量的图形,它们应该形成一种云。位于此云之外的所有数据点都将是多变量异常值。

异常值可以极大地影响分析和统计建模的结果。下面的图像,将出现异常值时模型发生的情况与处理异常值时的情况可视化出来:

但这里有一点需要注意——离散值并不总是坏事。了解这一点非常重要,简单地从数据中删除异常值而不考虑它们如何影响结果是一种灾难。

异常值不一定是坏事。这些离散值只是与其他模式不一致。但事实上异常值非常有趣。例如,如果在生物实验中,一只老鼠安然无恙而其他老鼠都死了,找到其中的原因会非常有趣。这可能会带来新的科学发现。因此,检测异常值非常重要。

——麦考斯,作家和统计学家

我们倾向于使用简单的方法,如箱形图、直方图和散点图来检测异常值。但是,专用异常值检测算法在处理大量数据并需要在较大数据集中执行模式识别的领域中非常有价值。

金融中的欺诈检测和网络安全中的入侵检测等应用需要密集而准确的技术来检测离散值。你能想象如果发现一个异常值并且结果是真的,那会有多尴尬吗?

而PyOD库可以弥补这一差距。

许多异常检测包存在于各种编程语言中。这些语言在R中尤其有用,但是当切换到Python时,显然缺少异常值检测库。这是为什么呢?

像PyNomaly这样已经存在的应用并不是专门为异常值检测而设计的(虽然它仍然值得一试)。为填补这一空白,Yue Zhao,Zain Nasrullah和Zheng Li设计并实施了PyOD库。

PyOD是一个可扩展的Python工具包,用于检测多变量数据中的异常值。它可以在记录良好的API下访问大约20个异常值检测算法。

4. PyOD库的特征

PyOD有很多优点和有用的功能,以下是其中的一部分:

· 开放源代码,包含各种算法的详细文档和示例

· 支持高级模型,包括神经网络,深度学习和异常集合

· 使用Numba和joblib优化JIT(即时)和并行化的性能

· 与Python 2和3都兼容

是时候开启Python notebooks了!

首先在机器上安装PyOD:

pip install pyod

pip install --upgrade pyod # to make sure that the latest version is installed!

这很简单!

请注意,PyOD还包含一些基于神经网络的模型,这些模型在Keras中实现。PyOD不会自动安装Keras或TensorFlow,如果要使用基于神经网络的模型,则需要手动安装Keras和其他库。

让我们看看为PyOD提供动力的异常值检测算法。

注意:我们将在本节中使用术语“外围评分(Outlying score)”。这意味着每个模型以某种方式对数据点进行评分,而不是使用阈值来确定该点是否是异常值。

基于角度的异常值检测(ABOD)

· 它考虑到每个点与其相邻点之间的关系,没有考虑这些邻居之间的关系。其加权余弦分数与所有相邻点的方差可视为偏离分数。

· ABOD在多维数据上表现良好。

· PyOD提供两种不同版本的ABOD:

· 快速ABOD:根据k最邻近的值进行估计

· 原始ABOD:考虑所有具有高时间复杂性的训练点

k-Nearest Neighbors检测器

· 对于任何数据点,与其第k个最近邻居的距离可视为远离分数。

· PyOD支持三个kNN检测器:

· 最大:以第k个临近点的距离作为离群值得分。

· 均值:以所有k个临近点平均值作为离群值得分。

· 中位数:以与临近点的距离的中位数作为离群值得分。

孤立森林

· 它在内部使用scikit-learn库。在此方法中,使用一组树完成数据分区。孤立森林提供了一个异常分数,用于查看结构中点的孤立程度。然后使用异常分数来识别来自正常观察的异常值。

· 孤立森林在多维数据上表现良好。

基于直方图的异常值检测

· 这是一种有效的无监督方法,它假设特征独立并通过构建直方图来计算异常值。

· 它比多变量方法快得多,但代价是精度较低。

局部相关积分(LOCI)

· LOCI对于检测异常值和异常值组非常有效。它为每个点提供LOCI图,总结了该点周围区域内数据的大量信息,确定了簇、微簇、它们的直径以及簇间距离。

· 现有的异常检测方法都不能与此功能匹配,因为它们对每个点只输出一个数字。

Feature bagging

· Feature bagging检测器可在数据集的各个子样本上安装多个基本检测器。它使用平均或其他组合方法来提高预测精度。

· 默认情况下,LOF用作基本估算器。但是,任何估计器都可以用作基本估计器,例如kNN和ABOD。

· Feature bagging首先通过随机选择特征子集来构建n个子样本。这使得基本估计更加多样化。最后,通过平均或取所有基本检测器的最大值来生成预测分数。

基于聚类的局部异常因素

· 它将数据分为小型集群和大型集群。然后根据点所属的簇的大小以及到最近的大簇的距离来计算异常分数。

· 函数generate_data可用于生成具有异常值的随机数据。内部数据由多元高斯分布生成,异常值由均匀分布生成。

· 我们可以提供自己的异常值分数值和在数据集中想要的样本总数。将使用此实用程序函数在实现部分中创建数据。

8. PyOD在Python中的运用

本文中,我们将使用两种不同的方法来演示PyOD:

· 使用模拟数据集

· 使用真实世界的数据集——大市场销售挑战

(https://datahack.analyticsvidhya.com/contest/practice-problem-big-mart-sales-iii/?utm_source=outlierdetectionpyod&utm_medium=blog)

模拟数据集中的PyOD

首先,让我们来输入必要的库:

import numpy as np

from scipy import stats

import matplotlib.pyplot as plt

%matplotlib inline

import matplotlib.font_manager

现在,我们将导入想要用来检测数据集中异常值的模型。使用ABOD和KNN:

from pyod.models.abod import ABOD

from pyod.models.knn import KNN

现在,我们将创建一个带有异常值的随机数据集并绘制它。

from pyod.utils.data import generate_data, get_outliers_inliers

#generate random data with two features

X_train, Y_train = generate_data(n_train=200,train_only=True, n_features=2)

# by default the outlier fraction is 0.1 in generate data function

outlier_fraction = 0.1

# store outliers and inliers in different numpy arrays

x_outliers, x_inliers = get_outliers_inliers(X_train,Y_train)

n_inliers = len(x_inliers)

n_outliers = len(x_outliers)

#separate the two features and use it to plot the data

F1 = X_train[:,[0]].reshape(-1,1)

F2 = X_train[:,[1]].reshape(-1,1)

# create a meshgrid

xx , yy = np.meshgrid(np.linspace(-10, 10, 200), np.linspace(-10, 10, 200))

# scatter plot

plt.scatter(F1,F2)

plt.xlabel('F1')

plt.ylabel('F2')

创建一个dictionary并添加要用于检测异常值的所有模型:

classifiers = {

'Angle-based Outlier Detector (ABOD)' : ABOD(contamination=outlier_fraction),

'K Nearest Neighbors (KNN)' : KNN(contamination=outlier_fraction)

}

将数据拟合到我们在dictionary中添加的每个模型,然后,查看每个模型如何检测异常值:

#set the figure size

plt.figure(figsize=(10, 10))

for i, (clf_name,clf) in enumerate(classifiers.items()) :

# fit the dataset to the model

clf.fit(X_train)

# predict raw anomaly score

scores_pred = clf.decision_function(X_train)*-1

# prediction of a datapoint category outlier or inlier

y_pred = clf.predict(X_train)

# no of errors in prediction

n_errors = (y_pred != Y_train).sum()

print('No of Errors : ',clf_name, n_errors)

# rest of the code is to create the visualization

# threshold value to consider a datapoint inlier or outlier

threshold = stats.scoreatpercentile(scores_pred,100 *outlier_fraction)

# decision function calculates the raw anomaly score for every point

Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()]) * -1

Z = Z.reshape(xx.shape)

subplot = plt.subplot(1, 2, i + 1)

# fill blue colormap from minimum anomaly score to threshold value

subplot.contourf(xx, yy, Z, levels = np.linspace(Z.min(), threshold, 10),cmap=plt.cm.Blues_r)

# draw red contour line where anomaly score is equal to threshold

a = subplot.contour(xx, yy, Z, levels=[threshold],linewidths=2, colors='red')

# fill orange contour lines where range of anomaly score is from threshold to maximum anomaly score

subplot.contourf(xx, yy, Z, levels=[threshold, Z.max()],colors='orange')

# scatter plot of inliers with white dots

b = subplot.scatter(X_train[:-n_outliers, 0], X_train[:-n_outliers, 1], c='white',s=20, edgecolor='k')

# scatter plot of outliers with black dots

c = subplot.scatter(X_train[-n_outliers:, 0], X_train[-n_outliers:, 1], c='black',s=20, edgecolor='k')

subplot.axis('tight')

subplot.legend(

[a.collections[0], b, c],

['learned decision function', 'true inliers', 'true outliers'],

prop=matplotlib.font_manager.FontProperties(size=10),

loc='lower right')

subplot.set_title(clf_name)

subplot.set_xlim((-10, 10))

subplot.set_ylim((-10, 10))

plt.show()

看起来很不错!

关于大市场销售问题的PyOD

现在,让我们看看PyOD是如何在著名的大型超市销售问题上进行运用的。

继续从上面的链接下载数据集。从导入所需的库并加载数据开始:

import pandas as pd

# Import models

from pyod.models.cblof import CBLOF

from pyod.models.feature_bagging import FeatureBagging

from pyod.models.hbos import HBOS

from pyod.models.iforest import IForest

# reading the big mart sales training data

df = pd.read_csv("train.csv")

让我们绘制Item MRP vs Item Outlet Sales以了解数据:

df.plot.scatter('Item_MRP','Item_Outlet_Sales')

Item Outlet Sales的范围是0到12000,Item MRP是0到250。我们将这两个功能缩小到0到1之间的范围。这是创建可解释的可视化所必需的(否则,它将变得太紧张)。对于此数据,使用相同的方法将花费更多时间来创建可视化。

注意:如果你不想可视化,则可以使用相同的比例来预测某个点是否为异常值。

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler(feature_range=(0, 1))

df[['Item_MRP','Item_Outlet_Sales']] = scaler.fit_transform(df[['Item_MRP','Item_Outlet_Sales']])

df[['Item_MRP','Item_Outlet_Sales']].head()

将这些值存储在NumPy数组中,以便以后在模型中使用:

X1 = df['Item_MRP'].reshape(-1,1)

X2 = df['Item_Outlet_Sales'].reshape(-1,1)

X = np.concatenate((X1,X2),axis=1)

我们要再次创建一个dictionary。但这一次,我们将添加更多模型,并了解每个模型如何预测异常值。

你可以根据问题和对数据的理解来设置异常值分数的值。在示例中,如果我们想检测5%与其他数据不相似的观察结果,那么需要将异常分数的值设置为0.05。

random_state = np.random.RandomState(42)

outliers_fraction = 0.05

# Define seven outlier detection tools to be compared

'Cluster-based Local Outlier Factor (CBLOF)':CBLOF(contamination=outliers_fraction,check_estimator=False, random_state=random_state),

'Feature Bagging':FeatureBagging(LOF(n_neighbors=35),contamination=outliers_fraction,check_estimator=False,random_state=random_state),

'Histogram-base Outlier Detection (HBOS)': HBOS(contamination=outliers_fraction),

'Isolation Forest': IForest(contamination=outliers_fraction,random_state=random_state),

'K Nearest Neighbors (KNN)': KNN(contamination=outliers_fraction),

'Average KNN': KNN(method='mean',contamination=outliers_fraction)

}

现在,我们将逐个拟合每个模型的数据,看看每个模型预测异常值的方式有多么不同。

xx , yy = np.meshgrid(np.linspace(0,1 , 200), np.linspace(0, 1, 200))

clf.fit(X)

scores_pred = clf.decision_function(X) * -1

y_pred = clf.predict(X)

n_inliers = len(y_pred) - np.count_nonzero(y_pred)

n_outliers = np.count_nonzero(y_pred == 1)

# copy of dataframe

dfx = df

dfx['outlier'] = y_pred.tolist()

# IX1 - inlier feature 1, IX2 - inlier feature 2

IX1 = np.array(dfx['Item_MRP'][dfx['outlier'] == 0]).reshape(-1,1)

IX2 = np.array(dfx['Item_Outlet_Sales'][dfx['outlier'] == 0]).reshape(-1,1)

# OX1 - outlier feature 1, OX2 - outlier feature 2

OX1 = dfx['Item_MRP'][dfx['outlier'] == 1].values.reshape(-1,1)

OX2 = dfx['Item_Outlet_Sales'][dfx['outlier'] == 1].values.reshape(-1,1)

print('OUTLIERS : ',n_outliers,'INLIERS : ',n_inliers, clf_name)

# fill blue map colormap from minimum anomaly score to threshold value

plt.contourf(xx, yy, Z, levels=np.linspace(Z.min(), threshold, 7),cmap=plt.cm.Blues_r)

a = plt.contour(xx, yy, Z, levels=[threshold],linewidths=2, colors='red')

plt.contourf(xx, yy, Z, levels=[threshold, Z.max()],colors='orange')

b = plt.scatter(IX1,IX2, c='white',s=20, edgecolor='k')

c = plt.scatter(OX1,OX2, c='black',s=20, edgecolor='k')

plt.axis('tight')

# loc=2 is used for the top left corner

plt.legend(

['learned decision function', 'inliers','outliers'],

loc=2)

plt.xlim((0, 1))

plt.ylim((0, 1))

plt.title(clf_name)

plt.show()

输出结果:

OUTLIERS : 447 INLIERS : 8076 Angle-based Outlier Detector (ABOD)

OUTLIERS : 427 INLIERS : 8096 Cluster-based Local Outlier Factor (CBLOF)

OUTLIERS : 386 INLIERS : 8137 Feature Bagging

OUTLIERS : 501 INLIERS : 8022 Histogram-base Outlier Detection (HBOS)

OUTLIERS : 427 INLIERS : 8096 Isolation Forest

OUTLIERS : 311 INLIERS : 8212 K Nearest Neighbors (KNN)

OUTLIERS : 176 INLIERS : 8347 Average KNN

在上图中,白点是由红线包围的内点,黑点是蓝色区域中的异常值。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
女人的欲望比男人更强烈,甚至强烈到10倍以上

女人的欲望比男人更强烈,甚至强烈到10倍以上

加油丁小文
2026-03-17 07:45:16
恩爱剧本不演了?奚梦瑶提离婚,何猷君掀桌子私生子传闻真相大白

恩爱剧本不演了?奚梦瑶提离婚,何猷君掀桌子私生子传闻真相大白

秋姐居
2026-04-04 22:23:29
六年六场官司:许敏又输了 郭威送养父保温杯 亲妈说儿子不属于我

六年六场官司:许敏又输了 郭威送养父保温杯 亲妈说儿子不属于我

离离言几许
2026-04-11 17:04:01
回到台湾就被抓?郑丽文和大陆谈完,临走前达成共识,赖清德急了

回到台湾就被抓?郑丽文和大陆谈完,临走前达成共识,赖清德急了

无处遁形
2026-04-12 16:35:52
阿司匹林天天吃,牢记五点降低出血风险!

阿司匹林天天吃,牢记五点降低出血风险!

药师方健
2026-04-05 22:53:22
库里教妹观战湖人大胜太阳!与詹姆斯合影 一双大长腿太绝了

库里教妹观战湖人大胜太阳!与詹姆斯合影 一双大长腿太绝了

Emily说个球
2026-04-11 19:37:04
今年以来先后发生多起事故,内蒙古包头市、阿拉善盟、呼伦贝尔市、赤峰市等四地主要负责人被约谈

今年以来先后发生多起事故,内蒙古包头市、阿拉善盟、呼伦贝尔市、赤峰市等四地主要负责人被约谈

大风新闻
2026-04-12 13:29:06
上海二手房单日成交1632套:连续打破5年峰值纪录,高端房源成交占比提升

上海二手房单日成交1632套:连续打破5年峰值纪录,高端房源成交占比提升

澎湃新闻
2026-04-12 13:52:27
特朗普精力充沛,养生秘诀是吃大量阿司匹林,日常三餐吃麦当劳

特朗普精力充沛,养生秘诀是吃大量阿司匹林,日常三餐吃麦当劳

南权先生
2026-04-04 05:05:03
000929,申请撤销退市风险警示!

000929,申请撤销退市风险警示!

证券时报e公司
2026-04-12 17:36:43
战争爆发前的预兆出现!美国已经有4个征兆,张召忠预言要成真?

战争爆发前的预兆出现!美国已经有4个征兆,张召忠预言要成真?

老嘪科普
2026-04-12 11:26:51
巴基斯坦空军歼10枭龙部署沙特的战略信号,大国出手果然不凡

巴基斯坦空军歼10枭龙部署沙特的战略信号,大国出手果然不凡

瞳眼天下
2026-04-12 10:12:23
刚从辽宁大连回来,毫不客气的说,中山区是全国市辖区城建天花

刚从辽宁大连回来,毫不客气的说,中山区是全国市辖区城建天花

芭比衣橱
2026-04-12 18:06:10
开始抢人!美国一周挖走4位中国顶尖人才,年薪1亿美金太惊人

开始抢人!美国一周挖走4位中国顶尖人才,年薪1亿美金太惊人

百科密码
2026-04-10 15:56:21
医疗圈炸锅了:肿瘤诊疗重大突破

医疗圈炸锅了:肿瘤诊疗重大突破

白宸侃片
2026-04-11 18:40:34
这5种病都不是病?而是年龄到了!过度治疗反而伤身,坦然接受!

这5种病都不是病?而是年龄到了!过度治疗反而伤身,坦然接受!

荷兰豆爱健康
2026-04-12 13:20:38
巴基斯坦怒了:巴基斯坦不是卡塔尔,动我们的人,打到你服!

巴基斯坦怒了:巴基斯坦不是卡塔尔,动我们的人,打到你服!

人生录
2026-04-08 00:37:17
美将领:但凡有枪的伊朗人都在朝美军直升机射击

美将领:但凡有枪的伊朗人都在朝美军直升机射击

看看新闻Knews
2026-04-07 21:55:04
事实证明,73岁无儿无女的迟重瑞,早已被陈丽华“安排”好了后路

事实证明,73岁无儿无女的迟重瑞,早已被陈丽华“安排”好了后路

乡野小珥
2026-04-08 17:29:22
是时候摊牌了,中方明确信号:要打,战火必须烧进美国本土!

是时候摊牌了,中方明确信号:要打,战火必须烧进美国本土!

史说方休
2026-04-11 01:23:59
2026-04-12 19:15:00
读芯术
读芯术
专注年轻人的AI学习平台
2097文章数 5640关注度
往期回顾 全部

科技要闻

理想称遭恶意拉踩,东风日产:尊重同行

头条要闻

女子将闺蜜6.8万紫貂大衣粘上粘鼠板 硬扯下来还撒谎

头条要闻

女子将闺蜜6.8万紫貂大衣粘上粘鼠板 硬扯下来还撒谎

体育要闻

五大联赛首冠出炉?拜仁或提前4轮卫冕德甲

娱乐要闻

46岁赵达官宣结婚!曾与殷桃谈婚论嫁

财经要闻

美伊谈判破裂的三大症结

汽车要闻

焕新极氪007/007GT上市 限时19.39万起

态度原创

数码
游戏
家居
房产
军事航空

数码要闻

破壁机哪个牌子好?安全无毒材质是重点,揭秘TOP10家用哪种好

突发!知名舅舅党爆料:Xbox游戏发布会将在下周举办

家居要闻

复古风格 自然简约

房产要闻

土地供应突然暴跌!2026海口楼市,格局大变!

军事要闻

美国副总统万斯:美伊谈判未能达成协议

无障碍浏览 进入关怀版