HaajraMumtaz commited on
Commit
882cb91
Β·
verified Β·
1 Parent(s): 059263c

Upload folder using huggingface_hub

Browse files
.gitattributes CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ congestion_multiplier_v1.cbm filter=lfs diff=lfs merge=lfs -text
37
+ training_diagnostics.png filter=lfs diff=lfs merge=lfs -text
congestion_multiplier_v1.cbm ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:477a52f47bab33557f78432575b90cf1d5a606084484a34543569156d848f297
3
+ size 3552656
train_traffic_mult.py ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import numpy as np
3
+ import pandas as pd
4
+ from catboost import CatBoostRegressor, Pool
5
+ from sklearn.model_selection import train_test_split, KFold
6
+ from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
7
+ import matplotlib.pyplot as plt
8
+
9
+ # ─── 1. LOAD ─────────────────────────────────────────────────────────────────
10
+ df = pd.read_csv('data/raw/lahore_traffic_dataset.csv')
11
+ print(f"Loaded: {df.shape[0]} rows Γ— {df.shape[1]} cols")
12
+ print(df.dtypes)
13
+ print(df.head(3).to_string())
14
+
15
+ # ─── 2. VALIDATE ─────────────────────────────────────────────────────────────
16
+ assert df['congestion_multiplier'].between(0.55, 3.5).all(), "Target out of range!"
17
+ assert (df['origin_zone'] != df['dest_zone']).all(), "Self-loops in data!"
18
+ assert df.isnull().sum().sum() == 0, "Null values found!"
19
+ print(f"\nβœ… Validation passed")
20
+ print(f"Target range: {df['congestion_multiplier'].min():.3f} – {df['congestion_multiplier'].max():.3f}")
21
+ print(f"Target mean: {df['congestion_multiplier'].mean():.3f}")
22
+ print(f"Target std: {df['congestion_multiplier'].std():.3f}")
23
+
24
+ # ─── 3. FEATURES ─────────────────────────────────────────────────────────────
25
+ TARGET = 'congestion_multiplier'
26
+
27
+ CAT_FEATURES = [
28
+ 'origin_zone', 'dest_zone', 'road_type',
29
+ 'is_one_way', 'has_signal', 'is_construction',
30
+ 'weather_condition', 'day_of_week', 'time_slot',
31
+ 'is_weekend', 'is_holiday', 'day_type'
32
+ ]
33
+
34
+ NUM_FEATURES = [
35
+ 'speed_limit_kmh', 'num_lanes', 'distance_km', 'road_curvature'
36
+ ]
37
+
38
+ # Cast categoricals to str so CatBoost handles them correctly
39
+ for col in CAT_FEATURES:
40
+ df[col] = df[col].astype(str)
41
+
42
+ X = df[CAT_FEATURES + NUM_FEATURES]
43
+ y = df[TARGET]
44
+
45
+ print(f"\nFeatures: {list(X.columns)}")
46
+ print(f"Cat: {CAT_FEATURES}")
47
+ print(f"Num: {NUM_FEATURES}")
48
+
49
+ # ─── 4. SPLIT ────────────────────────────────────────────────────────────────
50
+ X_train, X_test, y_train, y_test = train_test_split(
51
+ X, y, test_size=0.15, random_state=42
52
+ )
53
+ X_train, X_val, y_train, y_val = train_test_split(
54
+ X_train, y_train, test_size=0.15, random_state=42
55
+ )
56
+
57
+ print(f"\nTrain: {len(X_train)} | Val: {len(X_val)} | Test: {len(X_test)}")
58
+
59
+ train_pool = Pool(X_train, y_train, cat_features=CAT_FEATURES)
60
+ val_pool = Pool(X_val, y_val, cat_features=CAT_FEATURES)
61
+ test_pool = Pool(X_test, y_test, cat_features=CAT_FEATURES)
62
+
63
+ # ─── 5. TRAIN ────────────────────────────────────────────────────────────────
64
+ model = CatBoostRegressor(
65
+ iterations=2000,
66
+ learning_rate=0.04,
67
+ depth=8,
68
+ l2_leaf_reg=3,
69
+ min_data_in_leaf=10,
70
+ loss_function='RMSE',
71
+ eval_metric='RMSE',
72
+ random_seed=42,
73
+ verbose=200,
74
+ )
75
+
76
+ model.fit(
77
+ train_pool,
78
+ eval_set=val_pool,
79
+ early_stopping_rounds=100,
80
+ )
81
+
82
+ # ─── 6. EVALUATE ─────────────────────────────────────────────────────────────
83
+ def evaluate(pool, y_true, split_name):
84
+ preds = model.predict(pool)
85
+ mae = mean_absolute_error(y_true, preds)
86
+ rmse = np.sqrt(mean_squared_error(y_true, preds))
87
+ r2 = r2_score(y_true, preds)
88
+ mape = np.mean(np.abs((y_true - preds) / y_true)) * 100
89
+ print(f"\n── {split_name} ──")
90
+ print(f" MAE : {mae:.4f}")
91
+ print(f" RMSE : {rmse:.4f}")
92
+ print(f" RΒ² : {r2:.4f}")
93
+ print(f" MAPE : {mape:.2f}%")
94
+ return preds
95
+
96
+ print("\n=== EVALUATION ===")
97
+ val_preds = evaluate(val_pool, y_val, "Validation")
98
+ test_preds = evaluate(test_pool, y_test, "Test")
99
+
100
+ # ─── 7. SANITY CHECKS ────────────────────────────────────────────────────────
101
+ print("\n=== SANITY CHECKS ===")
102
+
103
+ # Check model learned zone personalities
104
+ test_df = X_test.copy()
105
+ test_df['actual'] = y_test.values
106
+ test_df['pred'] = test_preds
107
+
108
+ print("\nMean predicted multiplier by time_slot:")
109
+ print(test_df.groupby('time_slot')['pred'].mean().sort_values(ascending=False).to_string())
110
+
111
+ print("\nMean predicted multiplier by road_type:")
112
+ print(test_df.groupby('road_type')['pred'].mean().sort_values(ascending=False).to_string())
113
+
114
+ print("\nMean predicted multiplier by day_type:")
115
+ print(test_df.groupby('day_type')['pred'].mean().sort_values(ascending=False).to_string())
116
+
117
+ print("\nMean predicted multiplier by weather_condition:")
118
+ print(test_df.groupby('weather_condition')['pred'].mean().sort_values(ascending=False).to_string())
119
+
120
+ # ─── 8. FEATURE IMPORTANCE ───────────────────────────────────────────────────
121
+ fi = pd.Series(
122
+ model.get_feature_importance(),
123
+ index=CAT_FEATURES + NUM_FEATURES
124
+ ).sort_values(ascending=False)
125
+
126
+ print("\n=== FEATURE IMPORTANCE ===")
127
+ print(fi.to_string())
128
+
129
+ # ─── 9. PLOTS ────────────────────────────────────────────────────────────────
130
+ fig, axes = plt.subplots(1, 3, figsize=(18, 5))
131
+
132
+ # Actual vs predicted
133
+ axes[0].scatter(y_test, test_preds, alpha=0.3, s=10)
134
+ axes[0].plot([0.55, 3.5], [0.55, 3.5], 'r--')
135
+ axes[0].set_xlabel('Actual')
136
+ axes[0].set_ylabel('Predicted')
137
+ axes[0].set_title('Actual vs Predicted')
138
+
139
+ # Residuals
140
+ residuals = y_test.values - test_preds
141
+ axes[1].hist(residuals, bins=50, edgecolor='black')
142
+ axes[1].axvline(0, color='red', linestyle='--')
143
+ axes[1].set_xlabel('Residual')
144
+ axes[1].set_title('Residual Distribution')
145
+
146
+ # Feature importance
147
+ fi.head(12).plot(kind='barh', ax=axes[2])
148
+ axes[2].invert_yaxis()
149
+ axes[2].set_title('Feature Importance')
150
+
151
+ plt.tight_layout()
152
+ plt.savefig('models/training_diagnostics.png', dpi=150)
153
+ plt.show()
154
+
155
+ # ─── 10. SAVE ────────────────────────────────────────────────────────────────
156
+ os.makedirs('models', exist_ok=True)
157
+ model.save_model('models/congestion_multiplier_v1.cbm')
158
+ print("\nβœ… Model saved β†’ models/congestion_multiplier_v1.cbm")
159
+
training_diagnostics.png ADDED

Git LFS Details

  • SHA256: 64612f15b164d479a909fe8fe7863fdf518e000e39b3b8abf71b054cd2b7e760
  • Pointer size: 131 Bytes
  • Size of remote file: 175 kB