Files
predictV1/routes/predict_with_players.py
mamonov.ep 8a134239d7 Initial commit: добавление проекта predictV1
Включает модели ML для предсказаний, API маршруты, скрипты обучения и данные.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-21 17:22:58 +03:00

124 lines
4.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from catboost import CatBoostClassifier
import pandas as pd
import numpy as np
from typing import Dict, Any
# Загрузка модели с игроками
modelWithPlayers = CatBoostClassifier()
modelWithPlayers.load_model("artifacts/model_with_players.cbm")
# Загрузка порядка фич
def load_feature_order(path: str) -> list:
fo = pd.read_csv(path)
first_col = fo.columns[0]
return fo[first_col].tolist()
FEATURE_ORDER_WITH_PLAYERS = load_feature_order("artifacts/feature_order_with_players.csv")
def build_player_features(payload: Dict[str, Any]) -> pd.DataFrame:
"""
Создаёт бинарные признаки для модели с игроками.
Признаки:
- radiant_p{player_id}_h{hero_id}_pos{position}
- radiant_p{player_id}_h{hero_id}
- radiant_p{player_id}_pos{position}
(аналогично для dire)
"""
features = {}
# Инициализируем все признаки нулями
for feat in FEATURE_ORDER_WITH_PLAYERS:
features[feat] = 0
# Radiant: игроки + герои + позиции
for i in range(1, 6):
hero_id = int(payload.get(f"r_h{i}", -1))
player_id = int(payload.get(f"r_p{i}", -1))
position = int(payload.get(f"rp_h{i}", -1))
# Признак: игрок + герой + позиция
if player_id > 0 and hero_id >= 0 and position >= 0:
feature_name = f"radiant_p{player_id}_h{hero_id}_pos{position}"
if feature_name in features:
features[feature_name] = 1
# Признак: только игрок + герой
if player_id > 0 and hero_id >= 0:
feature_name = f"radiant_p{player_id}_h{hero_id}"
if feature_name in features:
features[feature_name] = 1
# Признак: только игрок + позиция
if player_id > 0 and position >= 0:
feature_name = f"radiant_p{player_id}_pos{position}"
if feature_name in features:
features[feature_name] = 1
# Dire: игроки + герои + позиции
for i in range(1, 6):
hero_id = int(payload.get(f"d_h{i}", -1))
player_id = int(payload.get(f"d_p{i}", -1))
position = int(payload.get(f"dp_h{i}", -1))
# Признак: игрок + герой + позиция
if player_id > 0 and hero_id >= 0 and position >= 0:
feature_name = f"dire_p{player_id}_h{hero_id}_pos{position}"
if feature_name in features:
features[feature_name] = 1
# Признак: только игрок + герой
if player_id > 0 and hero_id >= 0:
feature_name = f"dire_p{player_id}_h{hero_id}"
if feature_name in features:
features[feature_name] = 1
# Признак: только игрок + позиция
if player_id > 0 and position >= 0:
feature_name = f"dire_p{player_id}_pos{position}"
if feature_name in features:
features[feature_name] = 1
# Создаём DataFrame с одной строкой в правильном порядке
df = pd.DataFrame([features], columns=FEATURE_ORDER_WITH_PLAYERS)
return df
def predict_with_players(payload: Dict[str, Any]) -> Dict[str, float]:
"""
Делает предсказание с использованием модели с игроками.
Возвращает:
{
"radiant_win": вероятность победы Radiant (0-100),
"dire_win": вероятность победы Dire (0-100)
}
"""
# Проверяем, есть ли хотя бы один игрок в payload
has_players = False
for i in range(1, 6):
if payload.get(f"r_p{i}", -1) > 0 or payload.get(f"d_p{i}", -1) > 0:
has_players = True
break
# Если нет игроков, возвращаем 50/50
if not has_players:
return {
"radiant_win": 50,
"dire_win": 50
}
# Создаём признаки
X = build_player_features(payload)
# Предсказание
proba = modelWithPlayers.predict_proba(X)[0, 1]
radiant_win = round(float(np.clip(proba * 100.0, 0.0, 100.0)))
dire_win = 100 - radiant_win
return {
"radiant_win": radiant_win,
"dire_win": dire_win
}