LOF за новост и откриване на аномалии

Локален коефициент на отклонение (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)

Библиотеката sklearn на Python има внедряване за локален коефициент на отклонение (LOF). За да използваме откриване на новости, трябва да зададем хиперпараметъра novost като 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))

Можем да видим, че откриването на извънредни стойности/аномалии с локалния фактор на отклонение (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 канал и GrabNGoInfo.com

Препоръчани уроци

Препратки