免费 python基于PyOD库实现数据异常检测(中)

  • 主题发起人 主题发起人 Scare
  • 开始时间 开始时间

Scare

0xFF|主权幽灵
07
908
172
奇源币
0
管理成员
工作人员
版主
VIP
模型替换

本文在1.1节提到,PyOD为不同的异常检测算法提供了统一的API接口,并附上了各类算法的接口说明链接。在PyOD中,其他算法的检测流程与KNN算法类似,这一点与sklearn的模型构建方式相似。以PCA为例,只需更改模型的初始化方式,即可轻松替换模型,具体操作如下:

from pyod.models.pca import PCA
# 训练PCA检测器
clf_name = 'PCA' # 设置分类器的名称
clf = PCA() # 创建kNN模型实例
clf.fit(X_train) # 使用训练数据拟合模型

PCA(contamination=0.1, copy=True, iterated_power='auto', n_components=None,
n_selected_components=None, random_state=None, standardization=True,
svd_solver='auto', tol=0.0, weighted=True, whiten=False)

其他代码一样:

# 获取训练数据的预测标签和异常分数
y_train_pred = clf.labels_ # 二进制标签(0: 正常点, 1: 异常点)
y_train_scores = clf.decision_scores_ # 训练数据的异常分数
# 对测试数据进行预测
y_test_pred = clf.predict(X_test) # 对测试数据的异常标签(0或1)
y_test_scores = clf.decision_function(X_test) # 测试数据的异常分数
# 获取预测的置信度
y_test_pred, y_test_pred_confidence = clf.predict(X_test, return_confidence=True) # 返回预测标签和置信度(范围[0,1])
from pyod.utils.data import evaluate_print # 导入评估工具
# 评估并打印结果
print("\nOn Training Data:") # 打印训练数据的评估结果
evaluate_print(clf_name, y_train, y_train_scores) # 评估训练数据
print("\nOn Test Data:") # 打印测试数据的评估结果
evaluate_print(clf_name, y_test, y_test_scores) # 评估测试数据
# 可视化结果
visualize(clf_name, X_train, y_train, X_test, y_test, y_train_pred,
y_test_pred, show_figure=True, save_figure=False) # 显示可视化图像

On Training Data:
PCA ROC:0.8964, precision @ rank n:0.8
On Test Data:
PCA ROC:0.9033, precision @ rank n:0.8

png


1.2.2 模型组合​

异常检测由于其无监督特性,常常面临模型不稳定的问题。因此,建议通过组合不同检测器的输出(例如,通过平均)来提高其稳健性。

本示例展示了四种评分组合机制:

  • 平均值:所有检测器的平均分数。
  • 最大化:所有检测器中的最高分数。
  • 最大值的平均(Average of Maximum,AOM):将基础检测器划分为子组,并取每个子组的最高分数。最终得分为所有子组分数的平均值。
  • 平均值的最大(Maximum of Average,MOA):将基础检测器划分为子组,并取每个子组的平均分数。最终得分为所有子组分数中的最高值。
以上组合机制的代码实现由combo库提供。combo库是一个用于机器学习模型组合(集成学习)的Python工具库。它提供了多种模型合并方法,包括简单的平均、加权平均、中位数、多数投票,以及更复杂的动态分类器选择(Dynamic Classifier Selection)和堆叠(Stacking)等。combo库支持多种不同的场景,如分类器合并、原始结果合并、聚类合并和异常检测器合并。combo库官方仓库地址为:combo,安装命令如下:

pip install combo
以下示例代码展示了通过PyOD库和combo库组合模型来实现异常检测:

创建数据集

# 需要安装combo库,使用命令 pip install combo
from pyod.models.combination import aom, moa, median, average, maximization
from pyod.utils.data import generate_data, evaluate_print
from pyod.utils.utility import standardizer
from sklearn.model_selection import train_test_split
import numpy as np
# 导入模型并生成样本数据
# n_train:训练样本个数,n_features:样本X的特征维度,train_only:是否仅包含训练集
X, y = generate_data(n_train=5000, n_features=2, train_only=True, random_state=42) # 加载数据
# test_size:测试集比例
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4) # 划分训练集和测试集
# 标准化数据以便处理
X_train_norm, X_test_norm = standardizer(X_train, X_test)

创建检测器

初始化10个KNN异常检测器,设置不同的k值,并获取异常分数。k值决定了在进行预测时考虑多少个最近邻近点,较小的k值可能导致对噪声敏感,而较大的k值可能会使得模型过于平滑,从而失去某些细节。当然这段代码也可以组合不同类型的检测器,然后获取异常分数。

from pyod.models.knn import KNN
n_clf = 10 # 基础检测器的数量
# 初始化n_clf个基础检测器用于组合
k_list = list(range(1,100,n_clf))
train_scores = np.zeros([X_train.shape[0], n_clf]) # 创建训练集得分数组
test_scores = np.zeros([X_test.shape[0], n_clf]) # 创建测试集得分数组
print('Combining {n_clf} kNN detectors'.format(n_clf=n_clf)) # 输出组合的KNN检测器数量
for i in range(n_clf):
k = int(k_list) # 获取当前检测器的邻居数量


[TR]
[TD][/TD]

[TD] [/TD]
[/TR]
[TR]
[TD][/TD]

[TD] clf = KNN(n_neighbors=k, method='largest') # 初始化KNN检测器[/TD]
[/TR]
[TR]
[TD][/TD]

[TD] clf.fit(X_train_norm) # 拟合训练数据[/TD]
[/TR]
[TR]
[TD][/TD]

[TD] [/TD]
[/TR]
[TR]
[TD][/TD]

[TD] train_scores[:, i] = clf.decision_scores_ # 记录训练得分[/TD]
[/TR]
[TR]
[TD][/TD]

[TD] test_scores[:, i] = clf.decision_function(X_test_norm) # 记录测试得分[/TD]
[/TR]



Combining 10 kNN detectors

标准化检测结果

各个检测器的检测结果需要被标准化为零均值和单位标准差,这是因为在进行模型结果组合时,如果各个模型的输出得分范围差异较大,直接组合可能会导致结果偏差。通过标准化,可以确保各个模型的得分在同一尺度上,从而进行有效的组合:


# 在组合之前,需要对检测结果进行标准化
train_scores_norm, test_scores_norm = standardizer(train_scores, test_scores)

组合结果

使用combo组合结果:


# 使用平均值进行组合
y_by_average = average(test_scores_norm)
evaluate_print('Combination by Average', y_test, y_by_average) # 输出平均组合的评估结果
# 使用最大值进行组合
y_by_maximization = maximization(test_scores_norm)
evaluate_print('Combination by Maximization', y_test, y_by_maximization) # 输出最大值组合的评估结果
# 使用中位数进行组合
y_by_median = median(test_scores_norm)
evaluate_print('Combination by Median', y_test, y_by_median) # 输出中位数组合的评估结果
# 使用AOM进行组合。n_buckets为子组个数
y_by_aom = aom(test_scores_norm, n_buckets=5)
evaluate_print('Combination by AOM', y_test, y_by_aom) # 输出AOM组合的评估结果
# 使用MOA进行组合,n_buckets为子组个数
y_by_moa = moa(test_scores_norm, n_buckets=5)
evaluate_print('Combination by MOA', y_test, y_by_moa) # 输出MOA组合的评估结果


Combination by Average ROC:0.9899, precision @ rank n:0.9497
Combination by Maximization ROC:0.9866, precision @ rank n:0.9447
Combination by Median ROC:0.99, precision @ rank n:0.9548
Combination by AOM ROC:0.9896, precision @ rank n:0.9447
Combination by MOA ROC:0.9884, precision @ rank n:0.9447


1.2.3 阈值处理

PyOD通过模型计算数据的异常概率,并根据设定的阈值筛选出异常数据。在这个过程中,阈值的选择对异常检测结果的准确性具有重要影响。

PyThresh是一个全面且可扩展的Python工具包,旨在自动设置和处理单变量或多变量数据中的异常检测概率分数。它与PyOD库兼容,采用类似的语法和数据结构,但并不限于该库。PyThresh包含超过30种阈值算法,涵盖了从简单统计分析(如Z-score)到更复杂的图论和拓扑数学方法的多种技术。PyThresh库官方仓库地址为:pythresh,安装命令如下:


pip install pythresh
关于PyThresh的详细使用,可以查看其官方文档:pythresh-doc。以下示例代码展示了通过PyOD库和PyThresh库实现阈值处理的简单示例:




 
后退
顶部