ghostofpk20 commited on
Commit
acf413e
·
verified ·
1 Parent(s): 1bd40cc

Upload run_pipeline.py

Browse files
Files changed (1) hide show
  1. run_pipeline.py +177 -0
run_pipeline.py ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Main execution script for the Robust Recommender System Pipeline.
3
+ Demonstrates: streaming data, incremental training, error compensation,
4
+ data drift detection, model drift detection, and robust output.
5
+ """
6
+ import numpy as np
7
+ import torch
8
+ import json
9
+ import time
10
+ from recommender_pipeline.data_stream import StreamingDataSource
11
+ from recommender_pipeline.pipeline import RobustRecommenderPipeline
12
+
13
+
14
+ def main():
15
+ print("=" * 70)
16
+ print("ROBUST RECOMMENDER SYSTEM PIPELINE")
17
+ print("Features: Streaming | Error Compensation | Data Drift | Model Drift")
18
+ print("=" * 70)
19
+
20
+ # --- 1. Create streaming data source with occasional drift ---
21
+ print("\n[1] Initializing streaming data source...")
22
+ stream = StreamingDataSource(
23
+ dataset_name="reczoo/Movielens1M_m1",
24
+ batch_size=128,
25
+ shuffle=True,
26
+ synthetic=True, # Use synthetic data for reliable demo
27
+ n_users=1000,
28
+ n_items=500,
29
+ drift_probability=0.08, # 8% chance of drift per batch
30
+ random_state=42
31
+ )
32
+
33
+ # --- 2. Initialize pipeline ---
34
+ print("\n[2] Initializing robust recommender pipeline...")
35
+ device = 'cuda' if torch.cuda.is_available() else 'cpu'
36
+ print(f"Using device: {device}")
37
+
38
+ pipeline = RobustRecommenderPipeline(
39
+ n_users=None, # Auto-infer
40
+ n_items=None,
41
+ embedding_dim=64,
42
+ hidden_dims=[128, 64, 32],
43
+ learning_rate=1e-3,
44
+ device=device,
45
+ error_memory_size=2000,
46
+ k_neighbors=30,
47
+ lambda_comp=1.0,
48
+ data_drift_window=1000,
49
+ model_drift_reference=500,
50
+ model_drift_current=500,
51
+ degradation_threshold=0.05,
52
+ batch_size=128
53
+ )
54
+
55
+ # --- 3. Run pipeline on stream ---
56
+ print("\n[3] Running pipeline on data stream...")
57
+ print("-" * 70)
58
+
59
+ pipeline.initialize(stream)
60
+
61
+ # Process 50 batches (simulate real-time streaming)
62
+ results = pipeline.run(stream, max_batches=50)
63
+
64
+ print("-" * 70)
65
+
66
+ # --- 4. Display summary ---
67
+ print("\n[4] Pipeline Summary")
68
+ print("=" * 70)
69
+
70
+ summary = pipeline.get_summary()
71
+ print(json.dumps(summary, indent=2, default=str))
72
+
73
+ # --- 5. Detailed drift analysis ---
74
+ print("\n[5] Drift Analysis")
75
+ print("=" * 70)
76
+
77
+ data_drift_history = list(pipeline.data_detector.drift_history)
78
+ model_drift_history = list(pipeline.model_detector.metric_history)
79
+
80
+ print(f"Total data drift checks: {len(data_drift_history)}")
81
+ print(f"Data drift events: {sum(1 for d in data_drift_history if d.get('drift_detected', False))}")
82
+ print(f"Total model drift checks: {len(model_drift_history)}")
83
+ print(f"Model drift events: {sum(1 for d in model_drift_history if d.get('drift_detected', False))}")
84
+
85
+ # Show recent alerts
86
+ alerts = list(pipeline.drift_monitor.alerts)
87
+ if alerts:
88
+ print(f"\nRecent Alerts ({len(alerts)} total):")
89
+ for alert in alerts[-5:]:
90
+ print(f" [{alert['alert_level'].upper()}] {alert['recommendation'][:100]}...")
91
+ else:
92
+ print("\nNo drift alerts triggered.")
93
+
94
+ # --- 6. Performance comparison: base vs compensated predictions ---
95
+ print("\n[6] Prediction Quality: Base vs Error-Compensated")
96
+ print("=" * 70)
97
+
98
+ base_preds = []
99
+ comp_preds = []
100
+ labels = []
101
+
102
+ for r in results:
103
+ base_preds.extend(r['predictions']['base'])
104
+ comp_preds.extend(r['predictions']['compensated'])
105
+ if 'label' in r['data'].columns:
106
+ labels.extend(r['data']['label'].values)
107
+ elif 'rating' in r['data'].columns:
108
+ labels.extend((r['data']['rating'].values >= 3.5).astype(int))
109
+
110
+ if labels:
111
+ from sklearn.metrics import roc_auc_score, log_loss
112
+
113
+ base_preds = np.array(base_preds)
114
+ comp_preds = np.array(comp_preds)
115
+ labels = np.array(labels)
116
+
117
+ try:
118
+ base_auc = roc_auc_score(labels, base_preds)
119
+ comp_auc = roc_auc_score(labels, comp_preds)
120
+ print(f"Base Model AUC: {base_auc:.4f}")
121
+ print(f"Compensated AUC: {comp_auc:.4f}")
122
+ print(f"Improvement: {(comp_auc - base_auc):.4f}")
123
+ except Exception as e:
124
+ print(f"AUC calculation skipped: {e}")
125
+
126
+ try:
127
+ base_ll = log_loss(labels, np.clip(base_preds, 1e-6, 1 - 1e-6))
128
+ comp_ll = log_loss(labels, np.clip(comp_preds, 1e-6, 1 - 1e-6))
129
+ print(f"Base Model LogLoss: {base_ll:.4f}")
130
+ print(f"Compensated LogLoss: {comp_ll:.4f}")
131
+ except Exception as e:
132
+ print(f"LogLoss calculation skipped: {e}")
133
+
134
+ # --- 7. Recommendation Output Quality ---
135
+ print("\n[7] Recommendation Output Quality")
136
+ print("=" * 70)
137
+
138
+ if pipeline.recommender_output:
139
+ pop_dist = pipeline.recommender_output.get_popularity_distribution()
140
+ print(f"Items recommended: {pop_dist.get('unique_items_recommended', 0)}")
141
+ print(f"Coverage ratio: {pop_dist.get('coverage_ratio', 0):.4f}")
142
+ print(f"Rec entropy: {pop_dist.get('popularity_entropy', 0):.4f}")
143
+
144
+ if pipeline.output_buffer:
145
+ output_metrics = pipeline.output_buffer.get_quality_metrics()
146
+ print(f"Output buffer size: {output_metrics.get('buffer_size', 0)}")
147
+ print(f"Avg latency (ms): {output_metrics.get('avg_latency_ms', 0):.2f}")
148
+ print(f"Avg confidence: {output_metrics.get('avg_confidence', 0):.4f}")
149
+ print(f"Fallback rate: {output_metrics.get('fallback_rate', 0):.4f}")
150
+
151
+ # Show a sample recommendation
152
+ if results and results[-1].get('recommendations'):
153
+ print(f"\nSample recommendation from last batch:")
154
+ sample = results[-1]['recommendations'][0]
155
+ print(f" User {sample['user_id']}: {[r['item_id'] for r in sample['recommendations'][:5]]}")
156
+
157
+ # --- 8. Save artifacts ---
158
+ print("\n[8] Saving artifacts")
159
+ print("=" * 70)
160
+
161
+ pipeline.save_model("/app/recommender_model.pt")
162
+
163
+ with open("/app/pipeline_summary.json", "w") as f:
164
+ json.dump(summary, f, indent=2, default=str)
165
+
166
+ print("Model saved to: /app/recommender_model.pt")
167
+ print("Summary saved to: /app/pipeline_summary.json")
168
+
169
+ print("\n" + "=" * 70)
170
+ print("PIPELINE EXECUTION COMPLETE")
171
+ print("=" * 70)
172
+
173
+ return pipeline, results
174
+
175
+
176
+ if __name__ == "__main__":
177
+ pipeline, results = main()