ProRCA is an end-to-end framework for diagnosing anomalies in complex operational environments by uncovering multi-hop causal pathways. Unlike traditional anomaly detection methods that focus on correlations or feature importance (e.g., via SHAP), our approach leverages structural causal modeling to trace the full causal chainβfrom hidden root causes to observed anomalies.
Inspired by the paper:
Beyond Traditional Problem-Solving: A Causal Pathway Approach for Complex Operational Environments
Ahmed Dawoud & Shravan Talupula, February 9, 2025 π Download PDFThis work introduces a methodology that combines conditional anomaly scoring with causal path discovery and ranking. By extending the DoWhy library, the framework provides decision-makers with actionable insights into the true source of complex operational disruptions.
-
Pinpoint Critical Anomalies: Don't just find outliers; identify the significant operational hiccups in your time series data that truly matter. ProRCA uses robust detection methods to flag the starting points for your investigation.
-
Map Your System's Causal DNA: Go beyond black boxes. Explicitly define and model the cause-and-effect relationships within your operations using Structural Causal Models (SCMs). This captures the real logic of how different parts of your system influence each other.
-
Uncover the Real Root Causes: This is where ProRCA shines. Move past simple correlations and discover the actual causal pathways leading to anomalies. Our analysis traces disruptions back through multiple steps (multi-hop paths) in your system, uniquely combining structural knowledge with noise pattern analysis to pinpoint the true origins.
-
Visualize Causal Stories: Complex findings become clear insights. ProRCA generates intuitive diagrams of the discovered causal pathways, making it easy to see the chain of events, understand the flow of influence, and communicate exactly where the problem started.
ProRCA/
βββ .gitignore
βββ .github/
βββ CHANGELOG.md
βββ CONTRIBUTING.md
βββ LICENSE
βββ README.md
βββ docs/
β βββ Examples/
β β βββ Example_1/
β β βββ Example_2/
β βββ research_paper/
βββ pyproject.toml
βββ src/
β βββ anomaly/
β β βββ __init__.py
β β βββ adtk.py
β βββ data_generators/
β β βββ __init__.py
β β βββ synthetic_sales_data.py
β βββ prorca/
β βββ __init__.py
β βββ dag_builder.py
β βββ pathway.py
Install dependencies:
pip install profitops-rcafrom data_generators.synthetic_sales_data import generate_fashion_data_with_brand, inject_anomalies_by_date
df = generate_fashion_data_with_brand(start_date="2023-01-01", end_date="2023-12-31")from src.create_synthetic_data import inject_anomalies_by_date
anomaly_schedule = {
'2023-06-10': ('ExcessiveDiscount', 0.8),
'2023-06-15': ('COGSOverstatement', 0.4),
'2023-07-01': ('FulfillmentSpike', 0.5)
}
df_anomalous = inject_anomalies_by_date(df, anomaly_schedule)from anomaly.adtk import AnomalyDetector
detector = AnomalyDetector(df_anomalous, date_col="ORDERDATE", value_col="PROFIT_MARGIN")
anomalies = detector.detect()
anomaly_dates = detector.get_anomaly_dates()
detector.visualize(figsize=(12, 6), ylim=(40, 60))from prorca.pathway import ScmBuilder
edges = [
("PRICEEACH", "UNIT_COST"), ("PRICEEACH", "SALES"),
("UNIT_COST", "COST_OF_GOODS_SOLD"),
("QUANTITYORDERED", "SALES"), ("QUANTITYORDERED", "COST_OF_GOODS_SOLD"),
("SALES", "DISCOUNT"), ("SALES", "NET_SALES"),
("DISCOUNT", "NET_SALES"),
("NET_SALES", "FULFILLMENT_COST"), ("NET_SALES", "MARKETING_COST"),
("NET_SALES", "RETURN_COST"), ("NET_SALES", "PROFIT"),
("FULFILLMENT_COST", "PROFIT"), ("MARKETING_COST", "PROFIT"),
("RETURN_COST", "PROFIT"), ("COST_OF_GOODS_SOLD", "PROFIT"),
("SHIPPING_REVENUE", "PROFIT"), ("PROFIT", "PROFIT_MARGIN"),
("NET_SALES", "PROFIT_MARGIN")
]
nodes = ["PRICEEACH", "UNIT_COST", "SALES", "COST_OF_GOODS_SOLD", "PROFIT_MARGIN"]
builder = ScmBuilder(edges=edges, nodes=nodes)
scm = builder.build(df_anomalous)from prorca.pathway import CausalRootCauseAnalyzer
analyzer = CausalRootCauseAnalyzer(scm, min_score_threshold=0.8)
results = analyzer.analyze(df_anomalous, anomaly_dates, start_node='PROFIT_MARGIN')from prorca.pathway import CausalResultsVisualizer
visualizer = CausalResultsVisualizer(analysis_results=results)
visualizer.plot_root_cause_paths()

