8 つの Python 異常検出アルゴリズムのまとめ

異常検出とは、データ マイニング手法を使用して、データ セットの分布と一致しない異常なデータを検出することです。これは、外れ値、外れ値検出などとも呼ばれます。この記事では、8 つの一般的な Python 異常検出アルゴリズムを整理し、役立つことを願っています。

1. 異常検出の概要

異常検出とは、データ マイニング手法を使用して、データ セットの分布と一致しない異常なデータを検出することです。これは、外れ値、外れ値検出などとも呼ばれます。

 

1.1 異常検出が適用されるシナリオ

異常検出アルゴリズムが適用できるシーンの特徴としては、(1) ラベルが無い、またはカテゴリーが極端に偏っている、(2) サンプル内のほとんどのデータと異常データの差が大きい、(3) 異常データの割合が大きい、が挙げられます。データサンプル全体に占める異常データの割合は非常に低いです。一般的な適用例は次のとおりです。

金融分野:クレジットカード申込不正、クレジットカード盗難、信用詐欺などの金融データから「不正利用者」を特定、セキュリティ分野:トラフィックデータの変動や攻撃の有無の判定など、Eコマース分野: 取引データからウールパーティーや悪意のある画面スワイプギャングなどの「悪意のある購入者」を特定; 生態学的災害警告: 気象指数データに基づいて、将来起こり得る異常気象を判断; 医療モニタリング: 病気の状態を示す可能性のある異常なデータを検出医療機器データから;

 

1.2 異常検出の課題

異常検出は人気のある研究分野ですが、未知の複雑さ、異常の異質性、特殊性、多様性により、この分野全体には依然として多くの課題があります。

1) 最も困難な問題の 1 つは、異常検出で高い再現率を達成することが難しいことです。異常は非常にまれであり、不均一であるため、すべての異常を特定するのは困難な場合があります。

2) 異常検出モデルの精度を向上させるには、多くの場合、ビジネス特性を深く組み合わせる必要があります。そうしないと、効果が低く、少数派に対するアルゴリズムのバイアスが発生しやすくなります。

2. 異常検知方法

トレーニングセットに外れ値が含まれるかどうかにより、外れ値検出と新規性検出に分けられ、新規性検出の代表的な手法は1クラスSVMです。

異常の種類に応じて、異常検出は、異常点検出 (異常な消費者ユーザーなど)、コンテキスト異常検出 (時系列異常など)、およびグループ異常検出 (異常なギャングなど) に分類できます。

さまざまな学習方法に応じて、異常検出は、教師あり異常検出、半教師あり異常検出、教師なし異常検出に分類できます。実際の異常検出の問題では、異常なラベルのサンプルを収集することが難しいため、ラベルがないことがよくあるため、教師なし異常検出が最も広く使用されています。

教師なし異常検出は、そのアルゴリズムの考え方に応じて、次のカテゴリに大別できます。

2.1 クラスタリングベースの手法

クラスタリング ベースの異常検出方法は通常、次の仮定に依存します、1) 正常なデータ インスタンスはデータ内のクラスターに属しますが、異常なデータ インスタンスはどのクラスターにも属しません、2) 正常なデータ インスタンスは最も近いクラスターの重心に近い、異常なデータ インスタンスはそれらから遠い一方、最も近いクラスターの重心は遠くにあります; 3) 正常なデータ インスタンスは大きくて密なクラスターに属しますが、異常なデータ インスタンスは小さなクラスターまたは疎なクラスターに属します。データを異なるクラスターに分類することで、異常なデータが小さなクラスターに属するデータ、またはどのクラスターにも属さないデータ、またはクラスターの中心から遠く離れたデータです。

  • クラスターの中心から遠く離れたデータを外れ値として使用します。そのような方法には、SOM、K 平均法、最大期待値 (期待値最大化、EM)、および意味論的異常要因に基づくアルゴリズム (意味論的異常要因) などが含まれます。
  • クラスタリングによって得られた小さなクラスター データを外れ値として使用します。代表的な手法としては、K-means クラスタリングがあります。
  • 外れ値としてどのクラスターにも属さない。代表的な手法としては、DBSCAN、ROCK、SNN クラスタリングなどがあります。

2.2 統計に基づく方法

統計ベースの手法は、データ セットが特定の分布 (正規分布、ポアソン分布、二項分布など) または確率モデルに従うという仮定に依存します。データ ポイントが分布/モデルに準拠しているかどうかを判断することによって (つまり、小さな確率のイベント識別を通じて) 異常検出を実現します。確率モデルによれば、次のように分類できます。

1) パラメトリック法: 既知の分布を持つデータからモデル パラメーター (ガウス モデルなど) を推定する最も単純なパラメーター異常検出モデルは、データ ポイントと平均値の差が大きい場合に、サンプルが正規分布に従うと仮定することです。 2 ~ 3 倍よりも分散が の場合、その点は異常であると考えられます。

2) ノンパラメトリック法。データの分布が不明な場合、ヒストグラムを描画して、異常検出用のトレーニング セットによって生成されたヒストグラムにデータが含まれているかどうかを検出できます。データの変動度 (平均偏差、標準偏差、変動係数、四分位範囲など) を使用して、データ内の外れ値を見つけることもできます。

2.3 深さに基づく方法

この方法では、データを k 次元空間の階層にマッピングし、外れ値が周縁部に分布しているのに対し、通常のデータ ポイントは階層の中心に近くなる (深さが深くなる) と想定します。

半空間深度法 (ISODEPTH 法)。各点の深度を計算し、深度値に応じて異常なデータ点を判断します。

最小楕円体推定 (最小体積楕円体推定器、MVE) メソッド。ほとんどのデータ点 (通常 > 50%) の確率分布モデルに従って、実線の楕円で示される最小楕円球の境界がフィッティングされ、この境界範囲内にないデータ点は異常点として判断されます。

 

孤立した森。上記の 2 つの深度ベースの基本モデルの時間計算量は、特徴の次元 k の増加に伴って指数関数的に増加します。これは通常、次元 k ≤ 3 の場合に適用されます。また、孤立した森林は、深度データの計算方法。

 

隔離フォレスト アルゴリズムは、Ensemble に基づく異常検出手法であるため、線形時間計算量を持ちます。また、精度が高く、ビッグデータの処理速度も速いため、現在業界で広く利用されています。基本的な考え方は、ツリー モデル手法を通じてサンプル空間をランダムに分割します。高密度のクラスターは切断を停止するまでに何度も切断されます (つまり、各点は部分空間に単独で存在します)。しかし、分散がまばらなクラスターはほとんどが切断されます。の点 (つまり、異常な点) は非常に早い段階で部分空間で停止します。アルゴリズムのステップは次のとおりです。

1) トレーニング データから Ψ サンプルをランダムに選択して、単一のツリーをトレーニングします。

2) q 次元(属性)をランダムに指定し、現在のノードデータに切断点 p をランダムに生成します。現在のノードデータにおいて、指定されたq次元の最大値と最小値の間にpカット点が生成されます。

3) ここで切断点を選択すると、現在のノードのデータ空間を 2 つの部分空間に分割する超平面が生成されます。現在のノードの左ブランチ上の現在選択されている次元に p より小さい点を配置し、それらの点を配置​​します。 p 以上。現在のノードの右のブランチに置きます。

4) ノードの左ブランチ ノードと右ブランチ ノードでステップ 2 と 3 を再帰的に実行し、リーフ ノード上のデータが 1 つだけになる (それ以上切断しない) か、ツリーが設定された高さまで成長するまで、継続的に新しいリーフ ノードを構築します。(単一ツリーの最大高さを設定するのは、異常データ レコードが比較的少なく、そのパス長が比較的短く、正常レコードと異常レコードを区別するだけでよいため、平均身長。まあ、アルゴリズムはこの方法でより効率的です。)

5) 各ツリートレーニングの特徴空間を切り出すプロセスは完全にランダムであるため、結果を収束させるためにアンサンブル法を使用する必要があります。つまり、さらにいくつかのツリーを構築し、その後、その平均値を包括的に計算する必要があります。各ツリーのセグメンテーション結果。各サンプル x について、複合異常スコア s は次の式で計算されます。

 

h(x) は各ツリーの x の高さ、c(Ψ) はサンプル数 Ψ が与えられたときの平均パス長で、サンプル x のパス長 h(x) を標準化するために使用されます。

2.4 分類ベースのモデル

代表的な手法はOne class SVMであり、その原理はサンプル中の正例を丸くする超平面を求め、予測はこの超平面を用いて判定を行うものであり、円内のサンプルを正サンプルとする。カーネル関数の計算には時間がかかるため、大量のデータを扱うシナリオではあまり使用されません。

 

これは、正常なデータ インスタンスは密集した近傍に位置し、異常なデータ インスタンスの近くのサンプルはまばらであるという仮定に基づいています。密度/近傍に基づいてさらに細分化できます。

この方法では、密度に基づいてデータセット内の各データ領域の密度を計算し、密度が低い領域を外れ値領域とみなします。古典的な方法は、局所外れ値係数 (局所外れ値係数、LOF) です。LOF メソッドは、従来の外れ値の定義とは異なります。外れ値はローカルで外れ値として定義され、各データには、近傍を基準とした LOF 値を表す値が割り当てられます。LOF が大きいほど、近傍の密度は低くなります。外れ値である可能性が高くなります。ただし、LOF で最小最近傍を決定することは困難であり、データ次元が増加するにつれて、計算の複雑さと時間の複雑さが増加します。

距離に基づいて、比較データと隣接データ セット間の距離を計算することで異常を検出することが基本的な考え方です。正常なデータ ポイントは隣接データと類似していますが、異常データは隣接データとは異なります。

2.5 バイアスに基づく手法

データセットが与えられた場合、偏差ベースの方法によりデータセット全体の特性と一致しない点を見つけることができ、外れ値が除去されることでデータセットの分散が減少します。このアプローチは、データ ポイントを 1 つずつ比較する逐次異常手法と OLAP データ キューブ手法に分けることができます。現時点では、この方法はほとんど実用化されていません。

2.6 リファクタリングベースのアプローチ

代表的な手法はPCAです。異常検出に対する PCA のアプローチには一般に 2 つのアイデアがあります: 1 つは、データを低次元の特徴空間にマッピングし、特徴空間の異なる次元で他のデータからの各データ ポイントの偏差をチェックすることであり、もう 1 つは、データ ポイントを低次元の特徴空間にマッピングすることです。データを低次元特徴空間にマッピングし、その後、低次元特徴空間から元の空間に再マッピングし、低次元特徴を使用して元のデータを再構築してみて、再構築エラーのサイズを確認します。

2.7 ニューラルネットワークベースのアプローチ

代表的な手法としては、オートエンコーダ(autoencoder、AE)や長短期記憶ニューラルネットワーク(LSTM)などが挙げられます。

LSTM は、時系列データの異常検出に使用できます。履歴シーケンス データを使用してモデルをトレーニングし、予測値と大きな差がある外れ値を検出します。

オートエンコーダの異常検出 オートエンコーダは基本的にニューラル ネットワークを使用して、高次元の入力の低次元表現を生成します。Autoencoder は PCA に似ていますが、Autoencoder は非線形活性化関数を使用する際に PCA の線形制限を克服します。アルゴリズムの基本的な仮定は、外れ値は異なる分布に従うということです。正規データに基づいてトレーニングされたオートエンコーダーは、正規サンプルを再構成して復元できますが、正規分布とは異なるデータ ポイントを復元できないため、再構成に基づく大きな誤差が生じます。再構成誤差が特定のしきい値より大きい場合、外れ値としてマークされます。

 

要約: 教師なし異常検出手法の要素は、関連する機能の選択と、異常検出効果をより効果的に発揮できる合理的な仮定に基づく適切なアルゴリズムの選択です。

3. プロジェクトの実戦: クレジットカード詐欺対策

このプロジェクトは、kaggle の古典的なクレジット カード詐欺検出であり、データセットは高品質で、陽性サンプルと陰性サンプルの比率が大きく異なります。このプロジェクトでは主に教師なしオートエンコーダーの新規ポイント検出を使用して、再構成エラーに従って異常な不正サンプルを特定しました。

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

#!/usr/bin/env python 

# coding: utf-8 

   

import warnings 

warnings.filterwarnings("ignore"

   

import pandas as pd 

import numpy as np 

import pickle 

import matplotlib.pyplot as plt 

plt.style.use('seaborn'

import tensorflow as tf 

import seaborn as sns 

from sklearn.model_selection import train_test_split 

from keras.models import Model, load_model 

from keras.layers import Input, Dense 

from keras.callbacks import ModelCheckpoint 

from keras import regularizers 

from sklearn.preprocessing import StandardScaler 

from sklearn.metrics import roc_curve, auc, precision_recall_curve 

# 安利一个异常检测Python库 https://github.com/yzhao062/Pyod 

   

# 读取数据 :信用卡欺诈数据集地址https://www.kaggle.com/mlg-ulb/creditcardfraud 

d = pd.read_csv('creditcard.csv'

   

# 查看样本比例 

num_nonfraud = np.sum(d['Class'] == 0

num_fraud = np.sum(d['Class'] == 1

plt.bar(['Fraud', 'non-fraud'], [num_fraud, num_nonfraud], color='dodgerblue'

plt.show() 

   

# 删除时间列,对Amount进行标准化 

data = d.drop(['Time'], axis=1

data['Amount'] = StandardScaler().fit_transform(data[['Amount']]) 

   

# 为无监督新颖点检测方法,只提取负样本,并且按照8:2切成训练集和测试集 

mask = (data['Class'] == 0

X_train, X_test = train_test_split(data[mask], test_size=0.2, random_state=0

X_train = X_train.drop(['Class'], axis=1).values 

X_test = X_test.drop(['Class'], axis=1).values 

   

# 提取所有正样本,作为测试集的一部分 

X_fraud = data[~mask].drop(['Class'], axis=1).values 

   

# 构建Autoencoder网络模型 

# 隐藏层节点数分别为16,8,8,16 

# epoch为5,batch size为32 

input_dim = X_train.shape[1

encoding_dim = 16 

num_epoch = 5 

batch_size = 32 

   

input_layer = Input(shape=(input_dim, )) 

encoder = Dense(encoding_dim, activation="tanh",  

                activity_regularizer=regularizers.l1(10e-5))(input_layer) 

encoder = Dense(int(encoding_dim / 2), activation="relu")(encoder) 

decoder = Dense(int(encoding_dim / 2), activation='tanh')(encoder) 

decoder = Dense(input_dim, activation='relu')(decoder) 

autoencoder = Model(inputs=input_layer, outputs=decoder) 

autoencoder.compile(optimizer='adam',  

                    loss='mean_squared_error',  

                    metrics=['mae']) 

   

# 模型保存为model.h5,并开始训练模型 

checkpointer = ModelCheckpoint(filepath="model.h5"

                               verbose=0

                               save_best_only=True

history = autoencoder.fit(X_train, X_train, 

                          epochs=num_epoch, 

                          batch_size=batch_size, 

                          shuffle=True

                          validation_data=(X_test, X_test), 

                          verbose=1,  

                          callbacks=[checkpointer]).history 

   

   

# 画出损失函数曲线 

plt.figure(figsize=(14, 5)) 

plt.subplot(121

plt.plot(history['loss'], c='dodgerblue', lw=3

plt.plot(history['val_loss'], c='coral', lw=3

plt.title('model loss'

plt.ylabel('mse'); plt.xlabel('epoch'

plt.legend(['train', 'test'], loc='upper right'

   

plt.subplot(122

plt.plot(history['mae'], c='dodgerblue', lw=3

plt.plot(history['val_mae'], c='coral', lw=3

plt.title('model mae'

plt.ylabel('mae'); plt.xlabel('epoch'

plt.legend(['train', 'test'], loc='upper right'

   

   

# 读取模型 

autoencoder = load_model('model.h5'

   

# 利用autoencoder重建测试集 

pred_test = autoencoder.predict(X_test) 

# 重建欺诈样本 

pred_fraud = autoencoder.predict(X_fraud)   

   

# 计算重构MSE和MAE误差 

mse_test = np.mean(np.power(X_test - pred_test, 2), axis=1

mse_fraud = np.mean(np.power(X_fraud - pred_fraud, 2), axis=1

mae_test = np.mean(np.abs(X_test - pred_test), axis=1

mae_fraud = np.mean(np.abs(X_fraud - pred_fraud), axis=1

mse_df = pd.DataFrame() 

mse_df['Class'] = [0] * len(mse_test) + [1] * len(mse_fraud) 

mse_df['MSE'] = np.hstack([mse_test, mse_fraud]) 

mse_df['MAE'] = np.hstack([mae_test, mae_fraud]) 

mse_df = mse_df.sample(frac=1).reset_index(drop=True

   

# 分别画出测试集中正样本和负样本的还原误差MAE和MSE 

markers = ['o', '^'

markers = ['o', '^'

colors = ['dodgerblue', 'coral'

labels = ['Non-fraud', 'Fraud'

   

plt.figure(figsize=(14, 5)) 

plt.subplot(121

for flag in [1, 0]: 

    temp = mse_df[mse_df['Class'] == flag] 

    plt.scatter(temp.index,  

                temp['MAE'],   

                alpha=0.7,  

                marker=markers[flag],  

                c=colors[flag],  

                label=labels[flag]) 

plt.title('Reconstruction MAE'

plt.ylabel('Reconstruction MAE'); plt.xlabel('Index'

plt.subplot(122

for flag in [1, 0]: 

    temp = mse_df[mse_df['Class'] == flag] 

    plt.scatter(temp.index,  

                temp['MSE'],   

                alpha=0.7,  

                marker=markers[flag],  

                c=colors[flag],  

                label=labels[flag]) 

plt.legend(loc=[1, 0], fontsize=12); plt.title('Reconstruction MSE'

plt.ylabel('Reconstruction MSE'); plt.xlabel('Index'

plt.show() 

# 下图分别是MAE和MSE重构误差,其中橘黄色的点是信用欺诈,也就是异常点;蓝色是正常点。我们可以看出异常点的重构误差整体很高。 

   

# 画出Precision-Recall曲线 

plt.figure(figsize=(14, 6)) 

for i, metric in enumerate(['MAE', 'MSE']): 

    plt.subplot(1, 2, i+1

    precision, recall, _ = precision_recall_curve(mse_df['Class'], mse_df[metric]) 

    pr_auc = auc(recall, precision) 

    plt.title('Precision-Recall curve based on %s\nAUC = %0.2f'%(metric, pr_auc)) 

    plt.plot(recall[:-2], precision[:-2], c='coral', lw=4

    plt.xlabel('Recall'); plt.ylabel('Precision'

plt.show() 

   

# 画出ROC曲线 

plt.figure(figsize=(14, 6)) 

for i, metric in enumerate(['MAE', 'MSE']): 

    plt.subplot(1, 2, i+1

    fpr, tpr, _ = roc_curve(mse_df['Class'], mse_df[metric]) 

    roc_auc = auc(fpr, tpr) 

    plt.title('Receiver Operating Characteristic based on %s\nAUC = %0.2f'%(metric, roc_auc)) 

    plt.plot(fpr, tpr, c='coral', lw=4

    plt.plot([0,1],[0,1], c='dodgerblue', ls='--'

    plt.ylabel('TPR'); plt.xlabel('FPR'

plt.show() 

# 不管是用MAE还是MSE作为划分标准,模型的表现都算是很好的。PR AUC分别是0.51和0.44,而ROC AUC都达到了0.95。 

   

# 画出MSE、MAE散点图 

markers = ['o', '^'

colors = ['dodgerblue', 'coral'

labels = ['Non-fraud', 'Fraud'

   

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

for flag in [1, 0]: 

    temp = mse_df[mse_df['Class'] == flag] 

    plt.scatter(temp['MAE'],  

                temp['MSE'],   

                alpha=0.7,  

                marker=markers[flag],  

                c=colors[flag],  

                label=labels[flag]) 

plt.legend(loc=[1, 0]) 

plt.ylabel('Reconstruction RMSE'); plt.xlabel('Reconstruction MAE'

plt.show() 

到此这篇关于8种Python异常检测算法总结的文章就介绍到这了。

点击拿去
50G+学习视频教程
100+Python初阶、中阶、高阶电子书籍

おすすめ

転載: blog.csdn.net/ai520wangzha/article/details/131086750