Представьте: на заводе останавливается критический насос. Час простоя — 500 000 рублей убытка. Мы разрабатываем системы предиктивного обслуживания, которые предсказывают отказы за 2-3 недели до аварии. Архитектура строится вокруг главного приоритета: минимизировать пропущенные отказы при приемлемом уровне ложных тревог. В основе — комбинация пяти методов: от мгновенных порогов до физических моделей.
Кейс: внедрение на нефтехимическом заводе
На одном из проектов на нефтехимическом заводе мы внедрили систему на 12 критических насосах. За первый месяц удалось избежать двух внеплановых остановок, что сэкономило более 2 млн рублей. Такие результаты достигаются за счёт многоуровневой архитектуры, описанной ниже. Каждый метод закрывает слепые зоны других, а консенсусный механизм фильтрует шум.
Проблемы, которые решаем
Пропуск отказа против ложной тревоги. Одиночный детектор даёт высокий FPR — до 30% на зашумлённых данных. Многоуровневый консенсус снижает FPR до 5% при сохранении чувствительности 95%. Система спроектирована для промышленного IoT и использует AI диагностику на каждом уровне.
Шум данных и коррелированные инциденты. Один сбой насоса вызывает аномалии давления, температуры и расхода. Наша система группирует их в один инцидент, а не генерирует множество алертов.
Как мы строим систему обнаружения аномалий
Многоуровневая архитектура комбинирует пять подходов:
| Уровень | Метод | Задержка | Тип аномалии |
|---|---|---|---|
| L1: Threshold | Статические пороги по ISO/ГОСТ (ISO 10816) | мс | Грубые нарушения |
| L2: Statistical | EWMA, CUSUM, 3σ правила | с | Медленный дрейф |
| L3: ML Unsupervised | Isolation Forest, Autoencoder | мин | Многомерные паттерны |
| L4: Supervised | XGBoost на размеченных отказах | мин | Известные типы отказов |
| L5: Physics | Модель нормального поведения актива | ч | Отклонение от физической модели |
L1/L2 дают мгновенные алерты, L3/L4 — раннюю диагностику, L5 — долгосрочный тренд. Консенсус снижает false positive rate на 40% по сравнению с одиночным детектором.
Feature Engineering для оборудования
Преобразуем сырой сигнал датчика (вибрация, ток, давление) в многодоменные признаки:
import numpy as np
from scipy import stats, signal
def extract_equipment_features(raw_signal, sampling_rate=1000):
# Временная область
features = {
'rms': np.sqrt(np.mean(raw_signal**2)),
'peak': np.max(np.abs(raw_signal)),
'crest_factor': np.max(np.abs(raw_signal)) / np.sqrt(np.mean(raw_signal**2)),
'kurtosis': stats.kurtosis(raw_signal),
'skewness': stats.skew(raw_signal),
'peak_to_peak': np.ptp(raw_signal),
'shape_factor': np.sqrt(np.mean(raw_signal**2)) / np.mean(np.abs(raw_signal))
}
# Частотная область
freqs, psd = signal.welch(raw_signal, fs=sampling_rate, nperseg=512)
total_power = np.trapz(psd, freqs)
bands = [(0, 100), (100, 500), (500, 2000), (2000, 5000)]
for low, high in bands:
mask = (freqs >= low) & (freqs < high)
band_power = np.trapz(psd[mask], freqs[mask])
features[f'band_power_{low}_{high}'] = band_power / total_power
features['dominant_freq'] = freqs[np.argmax(psd)]
features['spectral_centroid'] = np.sum(freqs * psd) / np.sum(psd)
return features
Важно не абсолютное значение, а отклонение от нормы конкретного актива. Для этого рассчитываем дельта-признаки:
def compute_delta_features(current_features, baseline_features, trend_features_7d):
deltas = {}
for key in current_features:
if key in baseline_features:
deltas[f'{key}_delta_abs'] = current_features[key] - baseline_features[key]
if baseline_features[key] != 0:
deltas[f'{key}_delta_pct'] = ((current_features[key] - baseline_features[key]) / abs(baseline_features[key]) * 100)
if key in trend_features_7d:
deltas[f'{key}_trend_7d'] = trend_features_7d[key]
return deltas
Unsupervised детекция
Isolation Forest с адаптацией к сезонности обучается на 30+ днях нормальной работы. Autoencoder (LSTM) фиксирует реконструкционную ошибку для мультисенсорных окон:
from sklearn.ensemble import IsolationForest
from sklearn.preprocessing import StandardScaler
import pandas as pd
import numpy as np
class EquipmentAnomalyDetector:
def __init__(self, contamination=0.02):
self.scaler = StandardScaler()
self.model = IsolationForest(contamination=contamination, n_estimators=200, random_state=42)
self.baseline_built = False
def fit_baseline(self, normal_operation_features: pd.DataFrame):
X = self.scaler.fit_transform(normal_operation_features)
self.model.fit(X)
self.baseline_built = True
scores = self.model.score_samples(X)
self.threshold = np.percentile(scores, 5)
def detect(self, current_features: dict) -> dict:
if not self.baseline_built:
return {'status': 'no_baseline', 'anomaly': False}
X = self.scaler.transform([list(current_features.values())])
score = self.model.score_samples(X)[0]
is_anomaly = score < self.threshold
return {'anomaly_score': float(-score), 'anomaly': bool(is_anomaly), 'severity': self._classify_severity(-score)}
def _classify_severity(self, anomaly_score):
if anomaly_score > 0.8: return 'critical'
if anomaly_score > 0.6: return 'high'
if anomaly_score > 0.4: return 'medium'
return 'low'
import torch
import torch.nn as nn
class SensorAutoencoder(nn.Module):
def __init__(self, input_dim, hidden_dim=32, latent_dim=8, seq_len=60):
super().__init__()
self.encoder = nn.LSTM(input_dim, hidden_dim, batch_first=True)
self.bottleneck = nn.Linear(hidden_dim, latent_dim)
self.decoder = nn.LSTM(latent_dim, hidden_dim, batch_first=True)
self.output_layer = nn.Linear(hidden_dim, input_dim)
def forward(self, x):
enc_out, _ = self.encoder(x)
z = self.bottleneck(enc_out[:, -1, :])
z_expanded = z.unsqueeze(1).repeat(1, x.shape[1], 1)
dec_out, _ = self.decoder(z_expanded)
reconstruction = self.output_layer(dec_out)
return reconstruction
Консенсус алертов
Разные детекторы ловят разные типы аномалий. Для стандартного оборудования требуется совпадение 2 из 3 детекторов, для критичного — достаточно одного. Коррелированные по времени и топологии алерты группируются в один инцидент.
Почему многоуровневая архитектура эффективнее одного метода?
Каждый метод имеет слепые зоны. Isolation Forest плохо ловит дрейф медленных трендов, а статистические методы пропускают многомерные паттерны. Комбинация даёт полноту покрытия. В наших проектах консенсус снизил количество ложных тревог на 60%.
Мониторинг дрейфа модели
Со временем износ оборудования меняет эталонные признаки. Еженедельная проверка KS-тестом выявляет дрейф:
from scipy.stats import ks_2samp
def detect_model_drift(recent_features, baseline_features, p_threshold=0.01):
drift_features = []
for col in recent_features.columns:
stat, p_value = ks_2samp(baseline_features[col], recent_features[col])
if p_value < p_threshold:
drift_features.append(col)
drift_ratio = len(drift_features) / len(recent_features.columns)
return {'drift_detected': drift_ratio > 0.3, 'drifted_features': drift_features, 'drift_ratio': drift_ratio}
При обнаружении дрейфа запускается переобучение на данных последних 60 дней (если они размечены как нормальные).
Что входит в работу
- Аудит текущего оборудования и сбор данных — выезд инженера, анализ датчиков и исторических логов.
- Разработка многоуровневой модели (L1-L5) — настройка порогов, обучение ML-моделей, создание физической модели.
- Интеграция в инфраструктуру — подключение к SCADA, настройка потоков данных, дашборд и алерты.
- Документация и обучение персонала — инструкции по эксплуатации, регламент реагирования.
- Поддержка и переобучение — мониторинг дрейфа, обновление baseline, доработка под новые отказы.
Процесс работы и сроки
| Этап | Длительность |
|---|---|
| Аналитика — изучение оборудования, исторических данных, требований | 1-2 недели |
| Разработка прототипа — базовые пороги, EWMA, Isolation Forest | 2-3 недели |
| Продакшн-решение — Autoencoder, консенсус, дрифт-детекция | 4-6 недель |
| Развёртывание и обучение — интеграция, дашборд, обучение операторов | 2-3 недели |
Общий срок: от 3 недель до 3 месяцев в зависимости от сложности.
Типичные ошибки при внедрении
- Обучение на грязных данных (не удалены метки ремонтов)
- Игнорирование сезонности (отопление, ночные смены)
- Отсутствие baseline для нормального режима (нужен минимум 30 дней)
- Переобучение моделей без проверки дрейфа
Пример из практики: на заводе по производству удобрений система выявила аномалию в подшипнике компрессора за 18 дней до разрушения. Ремонт обошёлся незначительно по сравнению с затратами при аварийной остановке (около 500 тыс. рублей за час простоя).
Хотите оценить потенциал для вашего оборудования? Закажите бесплатный аудит — наши инженеры проанализируют готовность к внедрению. Получите консультацию по выбору архитектуры и объёму данных. Свяжитесь с нами, чтобы обсудить ваш проект.







