======================================
Одноклассовые машины опорных векторов
======================================
Алгоритм машины опорных векторов, или SVM, первоначально разработанный для бинарной классификации, можно использовать для классификации одного класса.
Если используется для несбалансированной классификации, рекомендуется оценить стандартную SVM и взвешенную SVM в наборе данных, прежде чем тестировать версию с одним классом.При моделировании одного класса алгоритм фиксирует плотность большинства классов и классифицирует примеры на экстремумах функции плотности как выбросы. Эта модификация SVM называется One-Class SVM.
Основное отличие от стандартного SVM заключается в том, что он подходит неконтролируемым образом и не предоставляет обычных гиперпараметров для настройки поля, как C. Вместо этого он предоставляет гиперпараметр «nu», который управляет чувствительностью опорных векторов и должен быть настроен на приблизительное соотношение выбросов в данных, например. 0,01%
(.env) boris@boris-All-Series:~/ONECLASS$ cat oneClassSVM.py
# one-class svm for imbalanced binary classification
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import f1_score
from sklearn.svm import OneClassSVM
# generate dataset
X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0,
n_clusters_per_class=1, weights=[0.999], flip_y=0, random_state=4)
# split into train/test sets
trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.5, random_state=2, stratify=y)
# define outlier detection model
model = OneClassSVM(gamma='scale', nu=0.01)
# fit on majority class
trainX = trainX[trainy==0]
model.fit(trainX)
# detect outliers in the test set
yhat = model.predict(testX)
# mark inliers 1, outliers -1
testy[testy == 1] = -1
testy[testy == 0] = 1
# calculate score
score = f1_score(testy, yhat, pos_label=-1)
print('F1 Score: %.3f' % score)
(.env) boris@boris-All-Series:~/ONECLASS$ python3 oneClassSVM.py
F1 Score: 0.123
(.env) boris@boris-All-Series:~/ONECLASS$ cat plot_oneclassSVM.py
"""
==========================================
One-class SVM with non-linear kernel (RBF)
==========================================
"""
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.font_manager
from sklearn import svm
xx, yy = np.meshgrid(np.linspace(-5, 5, 500), np.linspace(-5, 5, 500))
# Generate train data
X = 0.3 * np.random.randn(100, 2)
X_train = np.r_[X + 2, X - 2]
# Generate some regular novel observations
X = 0.3 * np.random.randn(20, 2)
X_test = np.r_[X + 2, X - 2]
# Generate some abnormal novel observations
X_outliers = np.random.uniform(low=-4, high=4, size=(20, 2))
# fit the model
clf = svm.OneClassSVM(nu=0.1, kernel="rbf", gamma=0.1)
clf.fit(X_train)
y_pred_train = clf.predict(X_train)
y_pred_test = clf.predict(X_test)
y_pred_outliers = clf.predict(X_outliers)
n_error_train = y_pred_train[y_pred_train == -1].size
n_error_test = y_pred_test[y_pred_test == -1].size
n_error_outliers = y_pred_outliers[y_pred_outliers == 1].size
# plot the line, the points, and the nearest vectors to the plane
Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.title("Novelty Detection")
plt.contourf(xx, yy, Z, levels=np.linspace(Z.min(), 0, 7), cmap=plt.cm.PuBu)
a = plt.contour(xx, yy, Z, levels=[0], linewidths=2, colors="darkred")
plt.contourf(xx, yy, Z, levels=[0, Z.max()], colors="palevioletred")
s = 40
b1 = plt.scatter(X_train[:, 0], X_train[:, 1], c="white", s=s, edgecolors="k")
b2 = plt.scatter(X_test[:, 0], X_test[:, 1], c="blueviolet", s=s, edgecolors="k")
c = plt.scatter(X_outliers[:, 0], X_outliers[:, 1], c="gold", s=s, edgecolors="k")
plt.axis("tight")
plt.xlim((-5, 5))
plt.ylim((-5, 5))
plt.legend(
[a.collections[0], b1, b2, c],
[
"learned frontier",
"training observations",
"new regular observations",
"new abnormal observations",
],
loc="upper left",
prop=matplotlib.font_manager.FontProperties(size=11),
)
plt.xlabel(
"error train: %d/200 ; errors novel regular: %d/40 ; errors novel abnormal: %d/40"
% (n_error_train, n_error_test, n_error_outliers)
)
plt.show()
================================
ИзоляцияЛес (IsolationForest)
================================
IsolationForest «изолирует» наблюдения, случайным образом выбирая признак, а затем случайным образом выбирая значение разделения между максимальным и минимальным значениями выбранного признака.Поскольку рекурсивное разбиение может быть представлено древовидной структурой, количество разбиений, необходимых для выделения выборки, эквивалентно длине пути от корневого узла до конечного узла.Эта длина пути, усредненная по лесу таких случайных деревьев, является мерой нормальности и нашей решающей функцией.
Случайное разбиение дает заметные более короткие пути для аномалий. Следовательно, когда лес случайных деревьев вместе дает более короткие пути для конкретных выборок, они, скорее всего, будут аномалиями.
(.env) boris@boris-All-Series:~/ONECLASS$ cat plot_isolation_forest.py
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import IsolationForest
rng = np.random.RandomState(42)
# Generate train data
X = 0.3 * rng.randn(100, 2)
X_train = np.r_[X + 2, X - 2]
# Generate some regular novel observations
X = 0.3 * rng.randn(20, 2)
X_test = np.r_[X + 2, X - 2]
# Generate some abnormal novel observations
X_outliers = rng.uniform(low=-4, high=4, size=(20, 2))
# fit the model
clf = IsolationForest(max_samples=100, random_state=rng)
clf.fit(X_train)
y_pred_train = clf.predict(X_train)
y_pred_test = clf.predict(X_test)
y_pred_outliers = clf.predict(X_outliers)
# plot the line, the samples, and the nearest vectors to the plane
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("IsolationForest")
plt.contourf(xx, yy, Z, cmap=plt.cm.Blues_r)
b1 = plt.scatter(X_train[:, 0], X_train[:, 1], c="white", s=20, edgecolor="k")
b2 = plt.scatter(X_test[:, 0], X_test[:, 1], c="green", s=20, edgecolor="k")
c = plt.scatter(X_outliers[:, 0], X_outliers[:, 1], c="red", s=20, edgecolor="k")
plt.axis("tight")
plt.xlim((-5, 5))
plt.ylim((-5, 5))
plt.legend(
[b1, b2, c],
["training observations", "new regular observations", "new abnormal observations"],
loc="upper left",
)
plt.show()
Комбинация источников по One-Class Classification Algorithms for Imbalanced Datasets, включая
https://machinelearningmastery.com/one-class-classification-algorithms/
No comments:
Post a Comment