Monday, May 23, 2022

One-Class Classification Algorithms for Imbalanced Datasets

 ======================================

Одноклассовые машины опорных векторов

======================================

Алгоритм машины опорных векторов, или 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