LOF для обнаружения новизны и аномалий

Local Outlier Factor (LOF) — это неконтролируемая модель для обнаружения выбросов. Он сравнивает локальную плотность каждой точки данных с ее соседями и идентифицирует точки данных с более низкой плотностью как аномалии или выбросы.

В этом уроке мы поговорим о

  • В чем разница между обнаружением новизны и обнаружением выбросов?
  • Когда использовать обнаружение новизны и обнаружение выбросов?
  • Как использовать фактор локального выброса (LOF) для обнаружения новизны?
  • Как использовать фактор локального выброса (LOF) для обнаружения аномалии или выброса?

Ресурсы для этой публикации:

Давайте начнем!

Шаг 1: Импорт библиотек

Первым шагом является импорт библиотек. Нам нужно импортировать make_classification из sklearn для создания набора данных моделирования, импортировать pandas и numpy для обработки данных, а Counter поможет нам подсчитать количество записей.

Matplotlib для визуализации.

Нам также нужен train_test_split для создания набора данных для обучения и проверки. LocalOutlierFactor предназначен для моделирования, а classification_report — для оценки производительности модели.

# Synthetic dataset
from sklearn.datasets import make_classification
# Data processing
import pandas as pd
import numpy as np
from collections import Counter
# Visualization
import matplotlib.pyplot as plt
# Model and performance
from sklearn.model_selection import train_test_split
from sklearn.neighbors import LocalOutlierFactor
from sklearn.metrics import classification_report


Шаг 2: Создайте набор данных с аномалиями

Используя make_classification из библиотеки sklearn, мы создали два класса с соотношением между классом большинства и классом меньшинства, равным 0,995:0,005. В качестве предикторов были использованы два информативных признака. Мы не включали в этот набор данных какие-либо избыточные или повторяющиеся функции.

# Create an imbalanced dataset
X, y = make_classification(n_samples=100000, n_features=2, n_informative=2,n_redundant=0, n_repeated=0,  n_classes=2,n_clusters_per_class=1, weights=[0.995, 0.005],class_sep=0.5, random_state=0)
# Convert the data from numpy array to a pandas dataframe
df = pd.DataFrame({'feature1': X[:, 0], 'feature2': X[:, 1], 'target': y})
# Check the target distribution
df['target'].value_counts(normalize = True)

Вывод показывает, что у нас есть около 1% данных в классе меньшинства и 99% в классе большинства, что означает, что у нас есть около 1% аномалий.

Шаг 3: Тренировка тестового сплита

На этом этапе мы разделяем набор данных на 80% обучающих данных и 20% проверочных данных. random_state гарантирует, что каждый раз у нас будет одно и то же разделение тестов поезда. Начальное число для random_state не обязательно должно быть 42, и это может быть любое число.

# Train test split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Check the number of records
print('The number of records in the training dataset is', X_train.shape[0])
print('The number of records in the test dataset is', X_test.shape[0])
print(f"The training dataset has {sorted(Counter(y_train).items())[0][1]} records for the majority class and {sorted(Counter(y_train).items())[1][1]} records for the minority class.")

Разделение тестов поезда дает нам 80 000 записей для набора данных для обучения и 20 000 для набора данных для проверки. Таким образом, у нас есть 79 183 точки данных из класса большинства и 817 из класса меньшинства в наборе обучающих данных.

The number of records in the training dataset is 80000
The number of records in the test dataset is 20000
The training dataset has 79183 records for the majority class and 817 records for the minority class.

Шаг 4: Обнаружение выбросов/аномалий по сравнению с обнаружением аномалий. Обнаружение новизны

Алгоритм локального фактора выброса (LOF) можно использовать для обнаружения выбросов/аномалий и обнаружения новизны. Разница между обнаружением выбросов/аномалий и обнаружением новинок заключается в обучающем наборе данных.

Обнаружение выбросов/аномалий включает выбросы в обучающем наборе данных. Алгоритм подходит к областям с высокой плотностью данных и игнорирует выбросы и аномалии.

Обнаружение новизны включает только обычные точки данных при обучении модели. Затем модель возьмет новый набор данных с выбросами/аномалиями для прогнозирования. Выбросы в обнаружении новизны также называются новинками.

Когда использовать обнаружение новизны и обнаружение выбросов? Это зависит от того, какие данные доступны. Если у нас есть набор данных с метками выбросов, мы можем использовать любую из них. В противном случае мы можем использовать только обнаружение выбросов, потому что мы не можем получить набор обучающих данных только с нормальными данными.

Шаг 5: Обнаружение новизны с использованием фактора локального выброса (LOF)

В библиотеке Python sklearn есть реализация Local Outlier Factor (LOF). Чтобы использовать обнаружение новизны, нам нужно установить новизну гиперпараметра как True. fit_predictfit недоступен, потому что алгоритм подходит и делает прогнозы для разных наборов данных. Нам нужно сопоставить набор обучающих данных со всеми нормальными данными и предсказать набор тестовых данных, который включает выбросы.

# Keep only the normal data for the training dataset
X_train_normal = X_train[np.where(y_train == 0)]
# Train the local outlier factor (LOF) model for novelty detection
lof_novelty = LocalOutlierFactor(n_neighbors=5, novelty=True).fit(X_train_normal)
# Predict novelties
prediction_novelty = lof_novelty.predict(X_test)
# Change the anomalies' values to make it consistent with the true values
prediction_novelty = [1 if i==-1 else 0 for i in prediction_novelty]
# Check the model performance
print(classification_report(y_test, prediction_novelty))

Мы видим, что обнаружение новизны локального фактора выбросов (LOF) зафиксировало 2% выбросов/аномалий.

          precision    recall  f1-score   support
      0       0.99      1.00      0.99     19787
      1       0.05      0.02      0.03       213
accuracy                           0.99     20000
macro avg       0.52      0.51      0.51     20000
weighted avg       0.98      0.99      0.98     20000

Шаг 6: Обнаружение выбросов с использованием локального фактора выбросов (LOF)

Локальный фактор выброса (LOF) для обучения обнаружению выбросов и прогнозирования на одном и том же наборе данных. Поэтому, если мы хотим сравнить производительность модели при обнаружении новинок и обнаружении выбросов, нам нужно подобрать и спрогнозировать набор данных тестирования. Нам также нужно установить novelty toFalse`, чтобы включить алгоритм обнаружения выбросов.

# The local outlier factor (LOF) model for outlier detection
lof_outlier = LocalOutlierFactor(n_neighbors=5, novelty=False)
# Predict novelties
prediction_outlier = lof_outlier.fit_predict(X_test)
# Change the anomalies' values to make it consistent with the true values
prediction_outlier = [1 if i==-1 else 0 for i in prediction_outlier]
# Check the model performance
print(classification_report(y_test, prediction_outlier))

Мы видим, что обнаружение выбросов/аномалий с помощью Local Outlier Factor (LOF) зафиксировало 3% выбросов/аномалий, что немного лучше, чем результат обнаружения новизны.

          precision    recall  f1-score   support
      0       0.99      0.99      0.99     19787
      1       0.06      0.03      0.04       213
accuracy                           0.98     20000
macro avg       0.53      0.51      0.52     20000
weighted avg       0.98      0.98      0.98     20000

Шаг 7: Визуализация

На этом шаге будут построены точки данных и проверены различия между фактическим обнаружением новизны LOF и обнаружением выбросов LOF.

# Put the testing dataset and predictions in the same dataframe
df_test = pd.DataFrame(X_test, columns=['feature1', 'feature2'])
df_test['y_test'] = y_test
df_test['prediction_novelty'] = prediction_novelty
df_test['prediction_outlier'] = prediction_outlier
# Visualize the actual and predicted anomalies
fig, (ax0, ax1, ax2)=plt.subplots(1,3, sharey=True, figsize=(20,6))
# Ground truth
ax0.set_title('Original')
ax0.scatter(df_test['feature1'], df_test['feature2'], c=df_test['y_test'], cmap='rainbow')
# Local Outlier Factor (LOF) Novelty Detection
ax1.set_title('LOF Novelty Detection')
ax1.scatter(df_test['feature1'], df_test['feature2'], c=df_test['prediction_novelty'], cmap='rainbow')
# Local Outlier Factor (LOF) Outlier / Anomaly Detection
ax2.set_title('LOF Outlier / Anomaly Detection')ax2.scatter(df_test['feature1'], df_test['feature2'], c=df_test['prediction_outlier'], cmap='rainbow')

Мы видим, что в этом примере обнаружение выбросов выявило больше выбросов, чем обнаружение новизны.

Краткое содержание

В этом руководстве показано, как использовать фактор локального выброса (LOF) для обнаружения выбросов и новизны.

Используя библиотеку sklearn в Python, мы рассмотрели

  • В чем разница между обнаружением новизны и обнаружением выбросов?
  • Когда использовать обнаружение новизны и обнаружение выбросов?
  • Как использовать фактор локального выброса (LOF) для обнаружения новизны?
  • Как использовать фактор локального выброса (LOF) для обнаружения аномалии или выброса?

Дополнительные уроки доступны на моем YouTube Channel и GrabNGoInfo.com.

Рекомендуемые учебники

Рекомендации