本文github地址:pyod包的入门使用
文章目录
0异常检测简介
1pyod包简介
1.1注意事项
- 当使用包含神经网络进行训练的函数时,需要安装keras或者tensorflow
- 在MAC端的anaconda环境中使用matplotlib可能会出现错误
- 部分算法与sklearn中的功能相同,推荐尽量使用一种即可
1.2函数的通用使用方法
- 模型训练
- fit(x)训练模型
- decision_function(x) 返回数据训练数据的异常程度得分
- predict(x)预测是否为异常值(异常=1)
- predict_proba(x)预测是异常值的概率
- 模型属性
- decision_scores 异常值的得分
- labels_ 训练的异常标签
1.3模型保存
推荐使用joblib 或者pickle
- joblib的使用方法
from joblib import dump, load
# save the model
dump(clf, 'clf.joblib')
# load the model
clf = load('clf.joblib')
- pickle
#保存
pickle.dump(需要保存的对象,
open(os.path.join(文件夹地址,'文件名'),'wb'),
protocol=4)
#加载
pickle.load(open(文件路径),'rb'))
1.4三个函数组
- 单独异常检测算法
-比如PCA,LOF等 - 集成或结合的异常检测算法
-比如LSCP,LODA - 其他多用途的函数
-generate_data,generate_data_clusters
1.5不同模型在基准数据上的表现
在选择使用哪个模型时,可以先判断数据集跟哪个基准数据的类别相同,然后选取几个模型进行综合比较
链接:Benchmark
1.6多个基准检测器的结合
由于现实预测中的各种变化,导致单一检测模型的鲁棒性较差,因此通常是用多个检测器,将结果进行综合,来提高预测结果的稳定性
- 平均处理
- 取最大值
- 取最大值的平均
- 取平均值的最大值
代码示例:comb.py
2异常值检测示例
2.1 ABOD 算法
2.1.1Angle-Based Outlier Detection (ABOD)原理介绍
abod判断异常点的大致方法:
- 如果对于一个点来说,它与其他所有点的连线的夹角都在一个小范围内,或者说其他点都在它的一侧方向上,则这个点可能是离群点
- 相反,如果与其他点的夹角的连线,分布在整个定义域空间内,则该点不是离群点
2.1.2 原始数据
生成数据:
pyod.utils.data.generate_data(n_train=1000, n_test=500, n_features=2, contamination=0.1, train_only=False, offset=10, behaviour='old', random_state=None)
- 用途:生成正常和异常样本
- 参数
- n_train 训练数据点个数
- contamination 异常样本的比例
- n_features 样本维度
- train_only 是否只用于训练
- 返回 X_train,y_train,x_test,y_testX_train,y_train,x_test,y_test
分离异常值:
pyod.utils.data.get_outliers_inliers(X, y)
- 返回X_outliers(异常值),X_inliers(正常值)
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
import matplotlib.font_manager
from pyod.models.abod import ABOD
from pyod.utils.data import generate_data,get_outliers_inliers
# 生成二维随机数据
X_train, Y_train = generate_data(n_train=200,train_only=True, n_features=2)
# 拆分出异常数据和正常数据
x_outliers, x_inliers = get_outliers_inliers(X_train,Y_train)
# 绘制生成的数据图
F1 = X_train[:,[0]].reshape(-1,1)
F2 = X_train[:,[1]].reshape(-1,1)
plt.scatter(F1,F2)
plt.xlabel('F1')
plt.ylabel('F2')
plt.show()
2.1.3 abod算法训练
pyod.models.abod.ABOD(contamination=0.1, n_neighbors=5, method='fast')
- contamination :异常样本的比例
- n_neighbors 模型中参与计算邻居点的数量
- method ‘fast’ or 'default’默认方法时间复杂度极高,不太推荐
outlier_fraction = 0.1#异常值比例
abod = ABOD(contamination=outlier_fraction)#生成模型
abod.fit(X_train)#训练模型
score = abod.decision_scores_# 注意异常得分是负的
score = score * -1
score.shape
(200,)
预测结果
分类指标的解释请参见常见分类指标
y_pred = abod.predict(X_train)# 预测训练样本的标签
from sklearn.metrics import classification_report
print(classification_report(y_true=Y_train,y_pred=y_pred))
precision recall f1-score support
0.0 0.97 0.96 0.97 180
1.0 0.68 0.75 0.71 20
accuracy 0.94 200
macro avg 0.83 0.86 0.84 200
weighted avg 0.94 0.94 0.94 200
** 绘制热力图 **
n_inliers = len(x_inliers)
n_outliers = len(x_outliers)
#生成热力图的坐标点
xx , yy = np.meshgrid(np.linspace(-10, 10, 200), np.linspace(-10, 10, 200))
# 根据百分比生成
threshold = -abod.threshold_
# 得到每个坐标点的异常值得分
Z = abod.decision_function(np.c_[xx.ravel(), yy.ravel()]) * -1
Z = Z.reshape(xx.shape)
plt.figure(figsize=(10, 10))
#将正常样本区域绘制成蓝色
plt.contourf(xx, yy, Z, levels = np.linspace(Z.min(), threshold, 10),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(X_train[:-n_outliers, 0], X_train[:-n_outliers, 1], c='white',s=20, edgecolor='k')
# 绘制异常点(黑色)
c = plt.scatter(X_train[-n_outliers:, 0], X_train[-n_outliers:, 1], c='black',s=20, edgecolor='k')
plt.axis('tight')
plt.legend(
[a.collections[0], b, c],
['learned decision function', 'true inliers', 'true outliers'],
prop=matplotlib.font_manager.FontProperties(size=10),
loc='lower right')
plt.title('ADOB')
plt.xlim((-10, 10))
plt.ylim((-10, 10))
plt.show()
2.2 KNN算法 介绍
- 基本原理:
计算点到k个最近的邻居之间的距离,距离值越大,越可能是异常点 - 判断异常值的三种方法
- 最大:使用到第k个邻居的距离作为离群值得分
- 平均值:使用所有k个邻居的平均值作为离群值得分
- 中位数:使用到k个邻居的距离的中值作为离群值得分
- 特点:
- 对K的取值比较敏感,K值小,容易过拟合,K值大,有容易导致精确度不高
- 对噪声敏感
- 计算量大,尤其是对于高维数据,计算最近邻时的时间复杂度较大
2.2.1 knn函数
classpyod.models.knn.KNN(contamination=0.1, n_neighbors=5,
method='largest', radius=1.0, algorithm='auto', leaf_size=30,
metric='minkowski', p=2, metric_params=None, n_jobs=1, **kwargs)
- 参数
- contamination:异常点比例
- n_neighbors:选取相邻点数量
- method:‘largest’、‘mean’、‘median’
‘largest’:使用与第k个相邻点的距离作为异常得分
‘mean’:使用k个相邻点距离的平均值作为异常得分
‘median’:使用k个相邻点距离的中值作为异常得分 - radius:radius_neighbors使用的参数空间半径
- metric:距离计算标准
- p:metric参数
2.2.2模型训练
from pyod.models.knn import KNN
outlier_fraction = 0.1#异常值比例
knn = KNN(contamination=outlier_fraction)#生成模型
knn.fit(X_train)#训练模型
score = knn.decision_scores_# 注意异常得分是负的
score = score * -1
score.shape
(200,)
### 2.2.3预测结果
y_pred = knn.predict(X_train)# 预测训练样本的标签
from sklearn.metrics import classification_report
print(classification_report(y_true=Y_train,y_pred=y_pred))
precision recall f1-score support
0.0 0.98 0.98 0.98 180
1.0 0.85 0.85 0.85 20
accuracy 0.97 200
macro avg 0.92 0.92 0.92 200
weighted avg 0.97 0.97 0.97 200
n_inliers = len(x_inliers)
n_outliers = len(x_outliers)
#生成热力图的坐标点
xx , yy = np.meshgrid(np.linspace(-10, 10, 200), np.linspace(-10, 10, 200))
# 根据百分比生成
threshold = -knn.threshold_
# 得到每个坐标点的异常值得分
Z = knn.decision_function(np.c_[xx.ravel(), yy.ravel()]) * -1
Z = Z.reshape(xx.shape)
plt.figure(figsize=(10, 10))
#将正常样本区域绘制成蓝色
plt.contourf(xx, yy, Z, levels = np.linspace(Z.min(), threshold, 10),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(X_train[:-n_outliers, 0], X_train[:-n_outliers, 1], c='white',s=20, edgecolor='k')
# 绘制异常点(黑色)
c = plt.scatter(X_train[-n_outliers:, 0], X_train[-n_outliers:, 1], c='black',s=20, edgecolor='k')
plt.axis('tight')
plt.legend(
[a.collections[0], b, c],
['learned decision function', 'true inliers', 'true outliers'],
prop=matplotlib.font_manager.FontProperties(size=10),
loc='lower right')
plt.title('KNN')
plt.xlim((-10, 10))
plt.ylim((-10, 10))
plt.show()
2.3 ADOB 与KNN的检验结果对比
- ADOB算法的模型检测的弹性较小,异常检测能力较强,大面积的颜色较深的蓝色区域,都是被判断为正常的样本,而且在边角的区域点,也被预测成了异常点
- KNN的检验结果的弹性就比较大,异常能力检测虽然较弱,但是在此随机数据中的检测结果要优于ADOB
3其他模型的使用
待更新