异常检测是一种识别数据中显著偏离其他观测值的技术。在数据分析中,异常也被称为离群点。例如,如果有一个包含公民每月收入的数据列,并且这个数据列中包含了比尔·盖茨的工资,那么比尔·盖茨的工资就是这个数据中的一个离群点。
这些只是众多算法中的一部分,鼓励读者探索更多的算法。
首先,需要导入所需的库并编写一些辅助函数:
!pip install pyod
import warnings
import numpy as np
import pandas as pd
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
以下是用于异常检测的数据:
data_values = [['2021-05-1', 45000.0], ['2021-05-2', 70000.0], ...]
data = pd.DataFrame(data_values, columns=['date', 'amount'])
接下来,定义一个函数来拟合模型并预测异常值:
def fit_model(model, data, column='amount'):
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='amount'):
categories = df['Predictions'].to_numpy()
colormap = np.array(['g', 'r'])
f = plt.figure(figsize=(12, 4))
f = plt.scatter(df[x], df[y], c=colormap[categories])
f = plt.xlabel(x)
f = plt.ylabel(y)
f = plt.xticks(rotation=90)
plt.show()
以上数据包含日期和金额两列,可以假设这些数据包含了一家烘焙展示公司的销售金额。
接下来,将详细介绍四分位数范围算法。四分位数范围(IQR)是一种基于数据分布的统计方法,用于识别异常值。IQR是第三四分位数(75%)和第一四分位数(25%)之间的差值。异常值被定义为低于第一四分位数减去1.5倍IQR或高于第三四分位数加上1.5倍IQR的值。
以下是IQR异常检测的代码实现:
def find_anomalies(value, lower_threshold, upper_threshold):
if value < lower_threshold or value > upper_threshold:
return 1
else: return 0
def iqr_anomaly_detector(data, column='amount', threshold=1.1):
df = data.copy()
quartiles = dict(data[column].quantile([.25, .50, .75]))
quartile_3, quartile_1 = quartiles[0.75], quartiles[0.25]
iqr = quartile_3 - quartile_1
lower_threshold = quartile_1 - (threshold * iqr)
upper_threshold = quartile_3 + (threshold * iqr)
df['Predictions'] = data[column].apply(find_anomalies, args=(lower_threshold, upper_threshold))
return df
以上代码首先计算了25%和75%的百分位数,即第一和第三四分位数。然后计算IQR,并根据阈值确定异常值的上下界。最后,使用find_anomalies函数标记异常值,并返回包含预测结果的数据框。
孤立森林算法是一种通过构建多个隔离树来检测异常值的方法。其核心思想是异常值比正常观测值更容易被隔离,且在隔离树中的位置更浅。以下是孤立森林的代码实现:
iso_forest = IsolationForest(n_estimators=125)
iso_df = fit_model(iso_forest, data)
iso_df['Predictions'] = iso_df['Predictions'].map(lambda x: 1 if x==-1 else 0)
plot_anomalies(iso_df)
中位数绝对偏差(MAD)是一种基于中位数的异常检测方法。与均值相比,中位数受异常值的影响较小。以下是MAD的代码实现:
mad_model = MAD()
mad_df = fit_model(mad_model, data)
plot_anomalies(mad_df)
K最近邻(KNN)算法使用K个最近邻的距离作为异常分数。如果一个观测值与其他观测值的距离较远,则被认为是异常值。以下是KNN的代码实现:
knn_model = KNN()
knn_df = fit_model(knn_model, data)
plot_anomalies(knn_df)