Обнаружение аномалий является важной задачей в различных областях, включая финансы, здравоохранение, кибербезопасность и многое другое. Данные временных рядов используются повсеместно в этих областях, что делает обнаружение аномалий в данных временных рядов важной и сложной проблемой. К счастью, с появлением библиотек машинного обучения процесс обнаружения аномалий стал как никогда доступным. В этом сообщении блога мы обсудим реализацию обнаружения аномалий в данных временных рядов с использованием библиотеки временных рядов Nixtla.

Nixtla — это библиотека Python для анализа и прогнозирования временных рядов, которая предоставляет обширную коллекцию моделей и алгоритмов временных рядов. Библиотека построена на основе популярных сред машинного обучения, таких как TensorFlow и scikit-learn, что упрощает ее использование и расширение.

Библиотека Nixtla предоставляет различные методы обнаружения аномалий в данных временных рядов. Одним из самых популярных методов является использование архитектуры нейронной сети LSTM (Long Short-Term Memory). LSTM — это тип рекуррентной нейронной сети (RNN), которая может обрабатывать последовательности произвольной длины, что делает их идеальными для данных временных рядов.

Для начала нам сначала нужно установить библиотеку Nixtla с помощью pip. Откройте терминал и введите следующую команду:

pip install nixtla

После завершения установки мы можем приступить к обнаружению аномалий с помощью LSTM. В этом примере мы будем использовать набор данных Yahoo Finance, который содержит ежедневные цены акций. Цель состоит в том, чтобы обнаружить аномалии в ценах на акции.

Во-первых, давайте загрузим набор данных с помощью библиотеки pandas:

import pandas as pd

df = pd.read_csv('stock_prices.csv')

Затем нам нужно предварительно обработать данные, чтобы передать их в модель LSTM. Мы нормализуем данные и разделим их на обучающую и тестовую выборки:

from nixtla.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split

scaler = MinMaxScaler(feature_range=(0, 1))
data = scaler.fit_transform(df['Close'].values.reshape(-1, 1))

train_data, test_data = train_test_split(data, test_size=0.2, shuffle=False)

Мы будем использовать данные обучения за последние 30 дней, чтобы предсказать цену следующего дня. Поэтому нам нужно создать скользящее окно в 30 дней:

import numpy as np

def create_window_data(data, window_size):
    X = []
    y = []
    for i in range(window_size, len(data)):
        X.append(data[i-window_size:i, 0])
        y.append(data[i, 0])
    return np.array(X), np.array(y)

window_size = 30
X_train, y_train = create_window_data(train_data, window_size)
X_test, y_test = create_window_data(test_data, window_size)

Теперь мы можем создать модель LSTM с помощью библиотеки Nixtla:

from nixtla.model import LSTMModel

model = LSTMModel(
    input_shape=(X_train.shape[1], 1),
    output_shape=1,
    loss='mean_squared_error',
    optimizer='adam',
)

Далее мы можем обучить модель, используя обучающие данные:

model.fit(X_train, y_train, epochs=100, batch_size=32)

После того, как модель обучена, мы можем использовать ее для прогнозирования цен на акции и расчета среднеквадратичной ошибки (MSE) между прогнозируемыми и фактическими ценами:

y_pred_train = model.predict(X_train)
y_pred_test = model.predict(X_test)

mse_train = np.mean(np.square(y_train - y_pred_train))
mse_test = np.mean(np.square(y_test - y_pred_test))

Наконец, мы можем использовать рассчитанные значения MSE для обнаружения аномалий в тестовых данных. Мы можем установить порог для значения MSE и пометить любые точки данных, которые имеют значение MSE выше порога, как аномалию:

threshold = 0.01

anomalies = np.where(np.square(y_test - y_pred_test) > threshold)[0]

В приведенном выше коде мы используем функцию where numpy, чтобы найти индексы точек данных со значениями MSE выше порогового значения.

Мы можем построить фактические и прогнозируемые цены акций вместе с помеченными аномалиями, используя следующий код:

import matplotlib.pyplot as plt

plt.plot(y_test, label='Actual')
plt.plot(y_pred_test, label='Predicted')
plt.scatter(anomalies, y_test[anomalies], marker='o', color='red', label='Anomaly')
plt.legend()
plt.show()

В заключение следует отметить, что библиотека временных рядов Nixtla предоставляет мощную и простую в использовании основу для реализации обнаружения аномалий в данных временных рядов. Используя LSTM, мы можем эффективно обнаруживать аномалии в различных данных временных рядов, что делает его ценным инструментом для различных областей.