Spaces:
Sleeping
Sleeping
File size: 5,725 Bytes
a3d10df 336608c a3d10df 336608c a3d10df 336608c a3d10df | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | import os
import joblib
import pandas as pd
from data_loader import DataLoader
from feature_engineer import FeatureEngineer
from rule_based_model import RuleBasedModel
def get_predictions(model_dir='artifacts'):
loader = DataLoader()
rankings = loader.get_rankings()
form = loader.get_team_form()
teams = loader.get_teams()
matches = loader.get_matches()
try:
manual_features = loader.get_manual_features()
except Exception as e:
print(f"WARNING: Could not load manual features: {e}")
manual_features = None
odds_summary = loader.get_latest_odds_summary()
weather_summary = loader.get_latest_weather_summary()
loader.close()
engineer = FeatureEngineer(rankings, form, teams, manual_features)
# Select upcoming matches
upcoming = matches[matches['status'].isin(['scheduled', 'active'])].copy()
if len(upcoming) == 0:
return {"predictions": [], "skipped": []}
X_pred, _ = engineer.build_dataset(upcoming)
# Load model
model_path = os.path.join(model_dir, 'rule_based_baseline.pkl')
if not os.path.exists(model_path):
raise FileNotFoundError(f"Model not found at {model_path}. Run train.py first.")
clf = joblib.load(model_path)
# Predict probabilities
probs = clf.predict_proba(X_pred)
X_pred['prob_away_win'] = probs[:, 0]
X_pred['prob_draw'] = probs[:, 1]
X_pred['prob_home_win'] = probs[:, 2]
# Merge back to upcoming by match_id
upcoming = upcoming.merge(X_pred[['match_id', 'prob_away_win', 'prob_draw', 'prob_home_win']], left_on='id', right_on='match_id', how='left')
results = []
skipped = []
for _, row in upcoming.iterrows():
if pd.isna(row['prob_home_win']):
# Determine reason
reason = "unknown"
if pd.isna(row['home_team_id']) or pd.isna(row['away_team_id']):
reason = "missing_team_placeholder"
else:
reason = "missing_features"
skipped.append({
"match_id": row['id'],
"home_team_id": row['home_team_id'] if not pd.isna(row['home_team_id']) else None,
"away_team_id": row['away_team_id'] if not pd.isna(row['away_team_id']) else None,
"reason": reason
})
continue
# Check if manual features were applied
applied = False
if manual_features is not None and row['id'] in manual_features.index:
applied = True
odds_rows = []
if odds_summary is not None and not odds_summary.empty:
match_odds = odds_summary[odds_summary['match_id'] == row['id']]
for _, odds in match_odds.iterrows():
odds_rows.append({
"bookmaker_key": odds.get("bookmaker_key"),
"bookmaker_title": odds.get("bookmaker_title"),
"market_key": odds.get("market_key"),
"market_title": odds.get("market_title"),
"home_odds": float(odds["home_odds"]) if not pd.isna(odds.get("home_odds")) else None,
"draw_odds": float(odds["draw_odds"]) if not pd.isna(odds.get("draw_odds")) else None,
"away_odds": float(odds["away_odds"]) if not pd.isna(odds.get("away_odds")) else None,
"last_update": str(odds.get("last_update")) if not pd.isna(odds.get("last_update")) else None,
})
weather = None
if weather_summary is not None and not weather_summary.empty and row['id'] in weather_summary.index:
w = weather_summary.loc[row['id']]
weather = {
"forecast_time": str(w.get("forecast_time")) if not pd.isna(w.get("forecast_time")) else None,
"temperature_c": float(w["temperature_c"]) if not pd.isna(w.get("temperature_c")) else None,
"apparent_temperature_c": float(w["apparent_temperature_c"]) if not pd.isna(w.get("apparent_temperature_c")) else None,
"humidity_pct": float(w["humidity_pct"]) if not pd.isna(w.get("humidity_pct")) else None,
"precipitation_probability_pct": float(w["precipitation_probability_pct"]) if not pd.isna(w.get("precipitation_probability_pct")) else None,
"precipitation_mm": float(w["precipitation_mm"]) if not pd.isna(w.get("precipitation_mm")) else None,
"wind_speed_kmh": float(w["wind_speed_kmh"]) if not pd.isna(w.get("wind_speed_kmh")) else None,
"wind_gusts_kmh": float(w["wind_gusts_kmh"]) if not pd.isna(w.get("wind_gusts_kmh")) else None,
"weather_code": int(w["weather_code"]) if not pd.isna(w.get("weather_code")) else None,
}
results.append({
"match_id": row['id'],
"home_team_id": row['home_team_id'],
"away_team_id": row['away_team_id'],
"prob_home_win": float(row['prob_home_win']),
"prob_draw": float(row['prob_draw']),
"prob_away_win": float(row['prob_away_win']),
"manual_features_applied": applied,
"odds": odds_rows,
"weather": weather
})
return {
"predictions": results,
"skipped": skipped
}
def run_predictions():
data = get_predictions()
print("\nUpcoming Match Predictions:")
for p in data['predictions']:
print(f"Match {p['match_id']} | {p['home_team_id']} vs {p['away_team_id']} "
f"| 1: {p['prob_home_win']:.2f} X: {p['prob_draw']:.2f} 2: {p['prob_away_win']:.2f}")
if __name__ == "__main__":
run_predictions()
|