Files
predictV1/routes/predict_bag_of_heroes.py

86 lines
2.8 KiB
Python
Raw Normal View History

from catboost import CatBoostClassifier
import pandas as pd
import numpy as np
from typing import Dict, Any
# Загрузка модели
modelBagOfHeroes = CatBoostClassifier()
modelBagOfHeroes.load_model("artifacts/model_bag_of_heroes.cbm")
# Загрузка порядка фич
def load_feature_order(path: str) -> list[str]:
fo = pd.read_csv(path)
first_col = fo.columns[0]
return fo[first_col].tolist()
FEATURE_ORDER_BAG: list[str] = load_feature_order("artifacts/feature_order_bag_of_heroes.csv")
def build_bag_of_heroes_features(payload: Dict[str, Any]) -> pd.DataFrame:
"""
Конвертирует payload в bag-of-heroes формат.
payload содержит:
- is_first_pick_radiant
- r_h1, r_h2, r_h3, r_h4, r_h5
- d_h1, d_h2, d_h3, d_h4, d_h5
Возвращает DataFrame с колонками:
- is_first_pick_radiant
- radiant_hero_{1-145}
- dire_hero_{1-145}
"""
# Получаем героев из payload
radiant_heroes = []
dire_heroes = []
for i in range(1, 6):
r_hero = payload.get(f"r_h{i}", -1)
d_hero = payload.get(f"d_h{i}", -1)
if r_hero and r_hero != -1:
radiant_heroes.append(int(r_hero))
if d_hero and d_hero != -1:
dire_heroes.append(int(d_hero))
# Создаем словарь признаков
features = {feat: 0 for feat in FEATURE_ORDER_BAG}
# Устанавливаем is_first_pick_radiant
features["is_first_pick_radiant"] = int(payload.get("is_first_pick_radiant", 0))
# Устанавливаем бинарные признаки для героев Radiant
for hero_id in radiant_heroes:
feat_name = f"radiant_hero_{hero_id}"
if feat_name in features:
features[feat_name] = 1
# Устанавливаем бинарные признаки для героев Dire
for hero_id in dire_heroes:
feat_name = f"dire_hero_{hero_id}"
if feat_name in features:
features[feat_name] = 1
# Создаем DataFrame с правильным порядком колонок
return pd.DataFrame([features], columns=FEATURE_ORDER_BAG)
def predict_bag_of_heroes(payload: Dict[str, Any]) -> Dict[str, float]:
"""
Делает предсказание с использованием bag-of-heroes модели.
Возвращает:
{
"radiant_win": вероятность победы Radiant (0-100),
"dire_win": вероятность победы Dire (0-100)
}
"""
X = build_bag_of_heroes_features(payload)
proba = modelBagOfHeroes.predict_proba(X)[0, 1]
radiant_win = round(float(np.clip(proba * 100.0, 0.0, 100.0)))
dire_win = 100.0 - radiant_win
return {
"radiant_win": radiant_win,
"dire_win": dire_win
}