【異常検知】 One class SVMによる外れ値検知
外れ値検出手法の一つであるOne class SVMを試したのでメモします。
import numpy as np import matplotlib.pyplot as plt from sklearn import svm np.random.seed(42) # Generate train data X = 0.3 * np.random.randn(100, 2) # fit the model clf = svm.OneClassSVM(nu=0.1, kernel='rbf', gamma='auto') clf.fit(X) # Generate some abnormal novel observations ANOMALY_DATA_COUNT = 20 X_outliers = np.random.uniform(low=-4, high=4, size=(ANOMALY_DATA_COUNT, 2)) X = np.r_[X + 2, X - 2, X_outliers] y_pred = clf.predict(X) # 正常を1、異常を-1と判定するようです ANOMALY_DATA = -1 predicted_outlier_index = np.where(y_pred == ANOMALY_DATA) predicted_outlier = X[predicted_outlier_index] # plot the level sets of the decision function xx, yy = np.meshgrid(np.linspace(-5, 5, 50), np.linspace(-5, 5, 50)) Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()]) Z = Z.reshape(xx.shape) plt.title("One Class SVM") plt.contourf(xx, yy, Z, cmap=plt.cm.Blues_r) a = plt.scatter(X[:200, 0], X[:200, 1], c='yellow', edgecolor='k', s=30, marker='o') b = plt.scatter(X[200:, 0], X[200:, 1], c='red', edgecolor='k', s=30, marker='o') c = plt.scatter(predicted_outlier[:, 0], predicted_outlier[:, 1], c='blue', edgecolor='k', s=10, marker='x') plt.axis('tight') plt.xlim((-5, 5)) plt.ylim((-5, 5)) plt.legend([a, b, c], ["normal observations", "abnormal observations", "observations predicted as abnormal"], loc="upper left", prop={'size': 12}) plt.show()
ハイパーパラメータにnuというやつがいるのですが、これはの範囲を取り、異常データ割合の上限を教えることができるようです。
今回は220個のデータの内20個を異常データとしているので、nu=0.1としました。 試しにnu=0.5とすると、確かに異常と見なされるデータ数が増えています。