AI Anomaly Detection System for Telecom Networks

Development of an AI Anomaly Detection System for Telecom Networks

AI Development Areas

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1284
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1240
  • image_logo-advance_0.webp
    B2B Advance company logo design
    696
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    982
  • image_logo-aider_0.webp
    AIDER company logo development
    917
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1031

Development of an AI Anomaly Detection System for Telecom Networks

We build AI anomaly detection systems for telecom network operators. Our team has 10+ years of production ML experience and has delivered 40+ projects. A telecom network generates millions of metrics per minute. Traditional static thresholds — like 80% CPU or packet loss > 1% — miss subtle anomalies: slow drifts, correlated degradations across multiple KPIs, atypical traffic patterns. ML-based detection works without fixed thresholds, adapting to the normal behavior of each element. Contact us for a project assessment.

Real Anomalies We Detect

  • Volumetric: DDoS attacks, flash crowds, bandwidth saturation.
  • Structural: BGP hijacks, route leaks, prefix deaggregation.
  • KPI degradation: CPU, memory, interface errors, latency drifts.
  • Multivariate: Simultaneous degradation of 5+ KPIs on one element, each individually in range.
  • Route instability: Flapping prefixes, BGP session resets.

How We Build the Detection System

We combine multiple models: Prophet for context-dependent thresholds per KPI, Isolation Forest for multivariate anomalies on node metric vectors, and heuristics for traffic and BGP analysis. This covers three layers: univariate time series, multivariate patterns, and network events.

Context-Aware Thresholds with Prophet

Why static thresholds are insufficient:

  • Normal router CPU at peak time = 75% (not anomaly)
  • CPU at 50% at 3 AM on Saturday = anomaly (possible attack or memory leak)
  • Simultaneous 5 KPI degradation on one element = anomaly, even if each is normal alone
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 with columns ds (datetime), y (KPI value) Minimum 4 weeks of history for correct seasonality. """ 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 } 

Why Isolation Forest Fits Telecom

Isolation Forest handles high-dimensional data (up to 100 KPIs per element). It does not require normal distribution and is robust to outliers during training. We train a separate model per network element, adapting to different behaviors of routers, switches, and servers.

from sklearn.ensemble import IsolationForest from sklearn.preprocessing import StandardScaler class NetworkElementAnomalyDetector: """ Each network element has its own Isolation Forest model. Training: 30 days of normal operation. Inference: every 5 minutes on current KPI vector. """ 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) # Calibrate threshold on normal data scores = self.model.score_samples(X) self.threshold = np.percentile(scores, 1) # 1% false positive rate 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 # higher = more anomalous 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' 

Traffic Anomaly Detection

How to Distinguish DDoS from Flash Crowd?

We analyze not only volume but also traffic structure: new sources, protocol ratios, peak duration. DDoS usually is homogeneous traffic from one source type; flash crowd is distributed requests from many IPs.

def detect_traffic_anomaly(traffic_matrix: pd.DataFrame, baseline_stats: dict) -> list: """ traffic_matrix: src_ip × dst_ip × bytes per 5 minutes (NetFlow/IPFIX) Traffic anomalies: volumetric (DDoS), structural (BGP hijack), protocol-based """ anomalies = [] # 1. Volumetric anomaly: sudden inbound traffic spike 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. New sources: IPs not in 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. Protocol anomaly: ICMP or 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 and Routing Anomalies

def analyze_bgp_events(bgp_updates: pd.DataFrame, baseline_prefix_count: int) -> dict: """ BGP hijack: sudden appearance of a new AS path for a known prefix. BGP leak: routes from one provider advertised to another. Route flap: frequent updates = connectivity instability. """ # Route flapping prefix_update_counts = bgp_updates.groupby('prefix').size() flapping_prefixes = prefix_update_counts[prefix_update_counts > 10].index.tolist() # New AS-origin for known prefixes 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 and Noise Suppression

When a router uplink fails, hundreds of downstream anomalies appear. Our algorithm: build a dependency graph from CMDB topology → identify upstream source → group into one incident.

Timeline: Prophet + Isolation Forest + Traffic anomaly — 3-4 weeks. BGP anomaly, alert correlation graph, automatic RCA, NOC integration — 2-3 months.

Performance Metrics

On a typical telecom network with 500–5000 elements, the system achieves:

  • Precision of KPI anomaly detection: ≥90% (Isolation Forest, 30-minute sliding window).
  • Recall for critical incidents (outage, DDoS): ≥95%.
  • MTTD (mean time to detect): reduced from 15–30 minutes with manual monitoring to 2–5 minutes.
  • Noise reduction: 70–80% fewer alerts due to correlation and dedup.
  • Inference latency: Prophet — 50 ms per element, Isolation Forest — 5 ms per vector.

Case study: In a deployment for a major telecom provider, we cut MTTD from 8 minutes to 1.2 minutes and reduced false positives by 80%, enabling the NOC to handle 5x more incidents without adding staff.

Monitoring covers three data sources: SNMP/gRPC streams from nodes, NetFlow/IPFIX traffic data, BGP MRT dumps and syslog events. Each layer is detected independently, then events merge in the correlation engine. The system supports incremental retraining once a week without service interruption.

What's Included in the Work

Deliverable Description
Model architecture Documentation of chosen models, versions, hyperparameters
Data pipeline ETL for KPI, NetFlow, BGP updates
Inference service FastAPI API deployed in Docker/Kubernetes
Dashboard Grafana or custom UI with alerts
Integration Webhook to NOC, API for OpenNMS/Zabbix
Operator training 2-day workshop
Support 3 months incident support

Static Thresholds vs ML: A Comparison

Feature Static Thresholds ML Detection
Adapts to seasonality No Prophet with seasonal components
Multivariate anomalies Impossible Isolation Forest on KPI vectors
False positives Frequent (up to 40%) Calibrated at 1%
Subtle anomalies (drift) Not detected Detected
Implementation time 1 day 3-4 weeks
Effectiveness Misses 60% of anomalies Detects 95%

ML detection finds 3x more anomalies than static thresholds and reduces noise by 5x.

How to Get Started

Contact us for a preliminary assessment of your network. We'll analyze available data, identify typical anomalies, and propose an architecture. Get a free consultation.