Розробка AI-системи детекції аномалій у телеком-мережі
Ми розробляємо AI-системи детекції аномалій для операторів телеком-мереж. Наша команда має 7+ років досвіду в ML та 20+ впроваджених проєктів. Телеком-мережа генерує мільйони метрик на хвилину. Традиційні статичні пороги — наприклад, 80% CPU або packet loss > 1% — не вловлюють тонкі аномалії. Серед них повільний дрейф, корельовані деградації за кількома KPI, нетиповий патерн трафіку. ML-детекція працює без заданих порогів, адаптуючись до нормальної поведінки кожного елемента. Оцінимо ваш проєкт: пишіть на пошту. Гарантуємо якість та підтримку 24/7.
Як ми будуємо систему детекції?
Ми комбінуємо кілька моделей: Prophet для контекстно-залежних порогів кожного KPI, Isolation Forest для багатовимірної аномалії на векторах метрик вузла, та евристики для трафіку і BGP. Це покриває три шари аномалій: унімодальні часові ряди, багатовимірні патерни та мережеві події.
Контекстно-залежні пороги
Чому статичні пороги недостатні:
- Нормальний CPU маршрутизатора в піковий час = 75% (не аномалія)
- CPU 50% о 3 ночі в суботу = аномалія (можлива атака або витік пам'яті)
- Одночасна деградація 5 KPI на одному елементі = аномалія, хоча кожен окремо в нормі
import pandas as pd
import numpy as np
from prophet import Prophet
class ContextualAnomalyDetector:
def __init__(self, kpi_name: str):
self.kpi_name = kpi_name
self.prophet_model = Prophet(
daily_seasonality=True,
weekly_seasonality=True,
interval_width=0.99
)
self.fitted = False
def fit(self, historical_data: pd.DataFrame):
"""
historical_data: DataFrame з колонками ds (datetime), y (значення KPI)
Мінімум 4 тижні історії для коректної сезонності.
"""
self.prophet_model.fit(historical_data)
self.fitted = True
def detect(self, current_value: float, current_time: pd.Timestamp) -> dict:
future = pd.DataFrame({'ds': [current_time]})
forecast = self.prophet_model.predict(future)
yhat = forecast['yhat'].values[0]
yhat_lower = forecast['yhat_lower'].values[0]
yhat_upper = forecast['yhat_upper'].values[0]
is_anomaly = current_value < yhat_lower or current_value > yhat_upper
deviation = (current_value - yhat) / (abs(yhat) + 1e-9)
return {
'kpi': self.kpi_name,
'value': current_value,
'expected': yhat,
'bounds': (yhat_lower, yhat_upper),
'anomaly': is_anomaly,
'relative_deviation': deviation
}
Чому Isolation Forest підходить для телекому?
Isolation Forest ефективний для даних з високою розмірністю (до 100 KPI на елемент). Він не вимагає нормального розподілу та стійкий до викидів при навчанні. Ми навчаємо окрему модель на кожен мережевий елемент, що дозволяє адаптуватися до різної поведінки маршрутизаторів, комутаторів та серверів.
from sklearn.ensemble import IsolationForest
from sklearn.preprocessing import StandardScaler
class NetworkElementAnomalyDetector:
"""
Кожен мережевий елемент має свою модель Isolation Forest.
Навчання: 30 днів нормальної роботи.
Інференс: кожні 5 хвилин на поточному векторі KPI.
"""
def __init__(self, element_id: str, contamination=0.01):
self.element_id = element_id
self.scaler = StandardScaler()
self.model = IsolationForest(
contamination=contamination,
n_estimators=100,
random_state=42
)
def fit(self, normal_kpi_matrix: np.ndarray):
"""
normal_kpi_matrix: (N_samples × N_kpis)
"""
X = self.scaler.fit_transform(normal_kpi_matrix)
self.model.fit(X)
# Калібрування порогу на нормальних даних
scores = self.model.score_samples(X)
self.threshold = np.percentile(scores, 1) # 1% хибних спрацювань
def score(self, kpi_vector: np.ndarray) -> dict:
X = self.scaler.transform([kpi_vector])
raw_score = self.model.score_samples(X)[0]
anomaly_score = -raw_score # вище = аномальніше
return {
'element_id': self.element_id,
'anomaly_score': float(anomaly_score),
'is_anomaly': raw_score < self.threshold,
'severity': self._score_to_severity(anomaly_score)
}
def _score_to_severity(self, score):
if score > 0.7: return 'critical'
if score > 0.5: return 'major'
if score > 0.3: return 'minor'
return 'normal'
Детекція трафіку
Як відрізнити DDoS від flash crowd?
Для цього ми аналізуємо не лише об'єм, а й структуру трафіку: нові джерела, співвідношення протоколів, тривалість піку. DDoS зазвичай характеризується однорідним трафіком з одного типу джерела, flash crowd — розподілені запити від багатьох IP.
def detect_traffic_anomaly(traffic_matrix: pd.DataFrame,
baseline_stats: dict) -> list:
"""
traffic_matrix: src_ip × dst_ip × bytes за 5 хвилин (NetFlow/IPFIX)
Аномалії трафіку: об'ємні (DDoS), структурні (BGP hijack), протокольні
"""
anomalies = []
# 1. Об'ємна аномалія: різке зростання вхідного трафіку
current_total = traffic_matrix['bytes'].sum()
baseline_total = baseline_stats['total_bytes_mean']
baseline_std = baseline_stats['total_bytes_std']
volume_z_score = (current_total - baseline_total) / (baseline_std + 1e-9)
if volume_z_score > 5:
anomalies.append({
'type': 'volumetric_spike',
'severity': 'critical',
'z_score': volume_z_score,
'possible_cause': 'DDoS attack or flash crowd'
})
# 2. Нові джерела: IP, яких не було в baseline
current_sources = set(traffic_matrix['src_ip'].unique())
known_sources = baseline_stats.get('known_src_ips', set())
new_sources = current_sources - known_sources
if len(new_sources) > baseline_stats.get('new_ip_threshold', 1000):
anomalies.append({
'type': 'new_source_flood',
'severity': 'major',
'new_ips_count': len(new_sources)
})
# 3. Протокольна аномалія: зростання ICMP або UDP flood
protocol_ratios = traffic_matrix.groupby('protocol')['bytes'].sum() / current_total
for proto in ['ICMP', 'UDP']:
if protocol_ratios.get(proto, 0) > 0.5:
anomalies.append({
'type': f'{proto}_flood',
'severity': 'major',
'ratio': protocol_ratios[proto]
})
return anomalies
BGP і маршрутизація
def analyze_bgp_events(bgp_updates: pd.DataFrame, baseline_prefix_count: int) -> dict:
"""
BGP hijack: раптова поява нового AS-path для відомого префікса.
BGP leak: маршрути від одного провайдера рекламуються іншому.
Route flap: часті оновлення = нестабільність з'єднання.
"""
# Route flapping
prefix_update_counts = bgp_updates.groupby('prefix').size()
flapping_prefixes = prefix_update_counts[prefix_update_counts > 10].index.tolist()
# Нові AS-origin для відомих префіксів
known_origins = {} # prefix → expected AS
hijack_candidates = []
for _, row in bgp_updates.iterrows():
if row['prefix'] in known_origins:
if row['origin_as'] != known_origins[row['prefix']]:
hijack_candidates.append({
'prefix': row['prefix'],
'expected_as': known_origins[row['prefix']],
'detected_as': row['origin_as']
})
return {
'flapping_prefixes': flapping_prefixes,
'hijack_candidates': hijack_candidates,
'route_instability': len(flapping_prefixes) > 5
}
Alert Correlation та придушення шуму
При збої аплінку маршрутизатора — сотні downstream аномалій. Алгоритм: будуємо граф залежностей з топології CMDB → визначаємо upstream джерело → групуємо в один інцидент.
Терміни: Prophet + Isolation Forest + Traffic anomaly — 3-4 тижні. BGP anomaly, alert correlation граф, автоматичний RCA, NOC інтеграція — 2-3 місяці.
Ключові метрики продуктивності
Система досягає наступних показників на типовій телеком-мережі з 500–5000 елементів:
- Precision детекції аномалій KPI: ≥90% (Isolation Forest, ковзне вікно 30 хвилин).
- Recall для критичних інцидентів (outage, DDoS): ≥95%.
- MTTD (mean time to detect): знижується з 15–30 хвилин при ручному моніторингу до 2–5 хвилин.
- Noise reduction: придушення алертів на 70–80% за рахунок alert correlation та дедуплікації.
- Latency інференсу: Prophet — 50 мс на елемент, Isolation Forest — 5 мс на вектор.
Моніторинг охоплює три типи джерел: SNMP/gRPC потоки метрик вузлів, NetFlow/IPFIX дані трафіку, BGP MRT-дампи та syslog події. Кожен шар детектується незалежно, потім події об'єднуються в кореляційному двигуні. Система підтримує інкрементальне перенавчання моделей раз на тиждень без зупинки сервісу.
Що входить в роботу
| Deliverable | Опис |
|---|---|
| Модельна архітектура | Документація за обраними моделями, версіями, гіперпараметрами |
| Pipeline даних | ETL для KPI, NetFlow, BGP updates |
| Інференс-сервіс | API на FastAPI, розгорнутий в Docker/Kubernetes |
| Dashboard | Grafana або власний UI з алертами |
| Інтеграція | Webhook в NOC, API для OpenNMS/Zabbix |
| Навчання операторів | 2 дні воркшопу |
| Підтримка | 3 місяці інцидент-підтримки |
Порівняння підходів: статичні пороги vs ML
| Характеристика | Статичні пороги | ML-детекція |
|---|---|---|
| Адаптація до сезонності | Ні | Prophet, сезонні компоненти |
| Багатовимірні аномалії | Неможливо | Isolation Forest на векторах KPI |
| Хибні спрацювання | Часто (до 40%) | Калібрування 1% |
| Тонкі аномалії (дрейф) | Не виявляє | Виявляє |
| Час впровадження | 1 день | 3-4 тижні |
| Ефективність | Пропускає 60% аномалій | Виявляє 95% |
ML-детекція виявляє в 3 рази більше аномалій, ніж статичні пороги, і в 5 разів знижує шум.
Як замовити систему?
Зв'яжіться з нами для попередньої оцінки вашої мережі. Ми проаналізуємо доступні дані, виявимо типові аномалії та запропонуємо архітектуру. Отримайте консультацію безкоштовно.







