昨年より仕事のデータ解析のためにPythonプログラムを書いている。昨年はデータ前処理と作図が殆どだったが、今年から統計手法のライブラリを使い始めた。最近、異常検知のためのPythonライブラリを探していたら、PyODというライブラリを見つけた。PyODは、多変量の観測データの異常検知が行えるライブラリで、提供されている手法は、統計モデルや機械学習など20に及ぶ。多様な異常検知手法を統一したインタフェースで適用して結果を相互比較できるという優れものである。リリースされてから日が浅く、日本語の解説記事はまだ殆どないようである。
今回は、英語のチュートリアル記事を参考に、PyODのデータ生成機能で作った人工データを用いて、教師なし学習の8つの手法を適用してみた。尚、PyODライブラリ利用のためにはインストールが必要です。Anacondaの場合は、ターミナルから「conda install -c conda-forge pyod」と入力して下さい。
【ライブラリのインポート】PyODライブラリは、各手法毎にインポートする。
import numpy as np import pandas as pd import matplotlib. pyplot as plt from matplotlib import rcParams rcParams['font.family'] = 'MS Gothic' from pyod.utils.data import generate_data, get_outliers_inliers # import PyOD library models from pyod.models.abod import ABOD from pyod.models.cblof import CBLOF from pyod.models.hbos import HBOS from pyod.models.iforest import IForest from pyod.models.knn import KNN from pyod.models.lof import LOF from pyod.models.pca import PCA
【人工データの生成】変数の数、異常データの出現割合(ここではデフォルト0.1)を指定して、分析用の人工データ(観測データ、正常/異常データ)を生成することができる。
# generate random data with two features X_train,X_test,Y_train,Y_test=generate_data(n_train=200,n_test=100,n_features=2,behaviour='new') # plot training data fig = plt.figure() ax1 = fig.add_subplot(111) ax1.plot(X_train[:,0], label='Col 1') ax1.plot(X_train[:,1], label='Col 2') ax1.set_title('PyOD Training Data') ax1.legend() plt.show()
【手法の記述】分析に用いる手法を辞書型変数として記述する。
# Define eight outlier detection tools to be compared random_state = np.random.RandomState(42) outliers_fraction = 0.05 classifiers = { 'Angle-based Outlier Detector (ABOD)': ABOD(contamination=outliers_fraction), 'Principal Component Analysis (PCA)': PCA(contamination=outliers_fraction), 'Cluster-based Local Outlier Factor(CBLOF)': CBLOF(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), }
【各手法のデータへの当てはめと異常判定】ここでは辞書リストの要素についてのループを組んでいる。
# Loop for outlier detection tools 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_test) # prediction of a datapoint category outlier or inlier y_pred = clf.predict(X_test) # prediciton error rate y_ErrRate = (y_pred != Y_test).sum() / len(Y_test) # plot scores_pred x = np.arange(100) y1 = scores_pred fig = plt.figure() ax1 = fig.add_subplot(111) ax1.plot(x,y1, 'k-', label='Anomaly Score') ax1.plot(x[y_pred==1], y1[y_pred==1],'ro', label='Outlier') ax1.set_title('PyOD Result: ' +clf_name + ' Error Rate: '+str(round(y_ErrRate,3))) ax1.legend() plt.show()