Примечание
Перейти в конец, чтобы скачать полный код примера или запустить этот пример в браузере через JupyterLite или Binder.
Сравнение алгоритмов обнаружения аномалий для выявления выбросов в учебных наборах данных
В этом примере показаны особенности различных алгоритмов обнаружения аномалий на двумерных наборах данных. Наборы данных содержат одну или две моды (области высокой плотности), чтобы продемонстрировать способность алгоритмов работать с мультимодальными данными.
Для каждого набора данных 15% образцов генерируются как случайный равномерный шум. Эта доля задаётся параметром nu для OneClassSVM и параметром contamination для остальных алгоритмов обнаружения выбросов. Границы принятия решений между внутренними точками и выбросами отображаются чёрным цветом, за исключением Local Outlier Factor (LOF), поскольку у него нет метода predict, который можно применить к новым данным при обнаружении выбросов.
OneClassSVM известен своей чувствительностью к выбросам и поэтому не очень хорошо подходит для их обнаружения. Этот оцениватель лучше всего подходит для обнаружения новизны, если обучающая выборка не содержит выбросов. Следует отметить, что обнаружение выбросов в пространствах высокой размерности или без каких-либо предположений о распределении внутренних данных — очень сложная задача, и One-class SVM может дать полезные результаты в таких ситуациях в зависимости от значений его гиперпараметров.
sklearn.linear_model.SGDOneClassSVM — это реализация One-Class SVM на основе стохастического градиентного спуска (SGD). В сочетании с аппроксимацией ядра этот оцениватель можно использовать для приближённого нахождения решения ядерного варианта sklearn.svm.OneClassSVM. Отметим, что границы принятия решений у sklearn.linear_model.SGDOneClassSVM и sklearn.svm.OneClassSVM очень похожи, хотя и не идентичны. Главное преимущество использования sklearn.linear_model.SGDOneClassSVM заключается в том, что его вычислительная сложность линейно зависит от числа образцов.
sklearn.covariance.EllipticEnvelope предполагает, что данные имеют гауссово распределение, и обучается на эллипсе. Поэтому качество его работы снижается, если данные не являются унимодальными. Однако этот оцениватель устойчив к выбросам.
IsolationForest и LocalOutlierFactor, по-видимому, достаточно хорошо работают с мультимодальными наборами данных. Преимущество LocalOutlierFactor перед другими оценивателями проявляется на третьем наборе данных, где две моды имеют разную плотность. Это преимущество объясняется локальным характером LOF: оценка аномальности одного образца сравнивается только с оценками его соседей.
Наконец, для последнего набора данных трудно утверждать, что один образец более аномален, чем другой, поскольку они равномерно распределены в гиперкубе. За исключением OneClassSVM, который немного переобучается, все оцениватели дают приемлемые решения для этой ситуации. В таком случае полезно внимательнее изучить оценки аномальности образцов: хороший оцениватель должен присваивать всем образцам похожие оценки.
Хотя эти примеры дают некоторое представление об алгоритмах, оно может оказаться неприменимым к данным очень высокой размерности.
Наконец, обратите внимание, что параметры моделей здесь были выбраны вручную, но на практике их необходимо настраивать. При отсутствии размеченных данных задача полностью неконтролируемая, поэтому выбор модели может быть непростым.

# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause
import time
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
from sklearn import svm
from sklearn.covariance import EllipticEnvelope
from sklearn.datasets import make_blobs, make_moons
from sklearn.ensemble import IsolationForest
from sklearn.kernel_approximation import Nystroem
from sklearn.linear_model import SGDOneClassSVM
from sklearn.neighbors import LocalOutlierFactor
from sklearn.pipeline import make_pipeline
matplotlib.rcParams["contour.negative_linestyle"] = "solid"
# Example settings
n_samples = 300
outliers_fraction = 0.15
n_outliers = int(outliers_fraction * n_samples)
n_inliers = n_samples - n_outliers
# define outlier/anomaly detection methods to be compared.
# the SGDOneClassSVM must be used in a pipeline with a kernel approximation
# to give similar results to the OneClassSVM
anomaly_algorithms = [
(
"Robust covariance",
EllipticEnvelope(contamination=outliers_fraction, random_state=42),
),
("One-Class SVM", svm.OneClassSVM(nu=outliers_fraction, kernel="rbf", gamma=0.1)),
(
"One-Class SVM (SGD)",
make_pipeline(
Nystroem(gamma=0.1, random_state=42, n_components=150),
SGDOneClassSVM(
nu=outliers_fraction,
shuffle=True,
fit_intercept=True,
random_state=42,
tol=1e-6,
),
),
),
(
"Isolation Forest",
IsolationForest(contamination=outliers_fraction, random_state=42),
),
(
"Local Outlier Factor",
LocalOutlierFactor(n_neighbors=35, contamination=outliers_fraction),
),
]
# Define datasets
blobs_params = dict(random_state=0, n_samples=n_inliers, n_features=2)
datasets = [
make_blobs(centers=[[0, 0], [0, 0]], cluster_std=0.5, **blobs_params)[0],
make_blobs(centers=[[2, 2], [-2, -2]], cluster_std=[0.5, 0.5], **blobs_params)[0],
make_blobs(centers=[[2, 2], [-2, -2]], cluster_std=[1.5, 0.3], **blobs_params)[0],
4.0
* (
make_moons(n_samples=n_samples, noise=0.05, random_state=0)[0]
- np.array([0.5, 0.25])
),
14.0 * (np.random.RandomState(42).rand(n_samples, 2) - 0.5),
]
# Compare given classifiers under given settings
xx, yy = np.meshgrid(np.linspace(-7, 7, 150), np.linspace(-7, 7, 150))
plt.figure(figsize=(len(anomaly_algorithms) * 2 + 4, 12.5))
plt.subplots_adjust(
left=0.02, right=0.98, bottom=0.001, top=0.96, wspace=0.05, hspace=0.01
)
plot_num = 1
rng = np.random.RandomState(42)
for i_dataset, X in enumerate(datasets):
# Add outliers
X = np.concatenate([X, rng.uniform(low=-6, high=6, size=(n_outliers, 2))], axis=0)
for name, algorithm in anomaly_algorithms:
t0 = time.time()
algorithm.fit(X)
t1 = time.time()
plt.subplot(len(datasets), len(anomaly_algorithms), plot_num)
if i_dataset == 0:
plt.title(name, size=18)
# fit the data and tag outliers
if name == "Local Outlier Factor":
y_pred = algorithm.fit_predict(X)
else:
y_pred = algorithm.fit(X).predict(X)
# plot the levels lines and the points
if name != "Local Outlier Factor": # LOF does not implement predict
Z = algorithm.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contour(xx, yy, Z, levels=[0], linewidths=2, colors="black")
colors = np.array(["#377eb8", "#ff7f00"])
plt.scatter(X[:, 0], X[:, 1], s=10, color=colors[(y_pred + 1) // 2])
plt.xlim(-7, 7)
plt.ylim(-7, 7)
plt.xticks(())
plt.yticks(())
plt.text(
0.99,
0.01,
("%.2fs" % (t1 - t0)).lstrip("0"),
transform=plt.gca().transAxes,
size=15,
horizontalalignment="right",
)
plot_num += 1
plt.show()
Общее время выполнения скрипта: (0 минут 3.734 секунды)
Связанные примеры
© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/auto_examples/miscellaneous/plot_anomaly_comparison.html