235 lines
7.7 KiB
Python
235 lines
7.7 KiB
Python
|
|
import sys
|
|||
|
|
sys.path.insert(0, '.')
|
|||
|
|
|
|||
|
|
import psycopg2
|
|||
|
|
import pandas as pd
|
|||
|
|
import numpy as np
|
|||
|
|
from routes.predict import build_long_format_input, modelPro
|
|||
|
|
from routes.predict_bag_of_heroes import build_bag_of_heroes_features, modelBagOfHeroes
|
|||
|
|
from routes.predict_with_players import build_player_features, modelWithPlayers
|
|||
|
|
from routes.predict_stacking import predict_stacking
|
|||
|
|
|
|||
|
|
# Подключение к БД
|
|||
|
|
conn = psycopg2.connect(
|
|||
|
|
host="localhost",
|
|||
|
|
port=5432,
|
|||
|
|
database="korobka_db",
|
|||
|
|
user="postgres",
|
|||
|
|
password="postgres"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# Получаем случайные матчи с известными игроками
|
|||
|
|
query = """
|
|||
|
|
SELECT
|
|||
|
|
m.id as match_id,
|
|||
|
|
m.radiant_win,
|
|||
|
|
m.leagueid
|
|||
|
|
FROM matches m
|
|||
|
|
WHERE EXISTS (
|
|||
|
|
SELECT 1
|
|||
|
|
FROM details_match dm
|
|||
|
|
WHERE dm.match_id = m.id
|
|||
|
|
AND dm.players_id IS NOT NULL
|
|||
|
|
AND dm.players_id != 0
|
|||
|
|
)
|
|||
|
|
ORDER BY RANDOM()
|
|||
|
|
LIMIT 100
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
matches_df = pd.read_sql(query, conn)
|
|||
|
|
print(f"Загружено {len(matches_df)} случайных матчей")
|
|||
|
|
|
|||
|
|
# Получаем детали этих матчей
|
|||
|
|
match_ids = matches_df['match_id'].tolist()
|
|||
|
|
placeholders = ','.join(['%s'] * len(match_ids))
|
|||
|
|
|
|||
|
|
query_details = f"""
|
|||
|
|
SELECT
|
|||
|
|
dm.match_id,
|
|||
|
|
dm.hero_id,
|
|||
|
|
dm.team,
|
|||
|
|
dm.players_id,
|
|||
|
|
dm.pos,
|
|||
|
|
dm."order"
|
|||
|
|
FROM details_match dm
|
|||
|
|
WHERE dm.match_id IN ({placeholders})
|
|||
|
|
ORDER BY dm.match_id, dm."order"
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
cursor = conn.cursor()
|
|||
|
|
cursor.execute(query_details, match_ids)
|
|||
|
|
details_rows = cursor.fetchall()
|
|||
|
|
conn.close()
|
|||
|
|
|
|||
|
|
# Преобразуем детали в словарь по match_id
|
|||
|
|
details_by_match = {}
|
|||
|
|
for row in details_rows:
|
|||
|
|
match_id = row[0]
|
|||
|
|
if match_id not in details_by_match:
|
|||
|
|
details_by_match[match_id] = []
|
|||
|
|
details_by_match[match_id].append({
|
|||
|
|
'hero_id': row[1],
|
|||
|
|
'team': row[2],
|
|||
|
|
'players_id': row[3],
|
|||
|
|
'pos': row[4],
|
|||
|
|
'order': row[5]
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
print(f"Загружено деталей для {len(details_by_match)} матчей\n")
|
|||
|
|
|
|||
|
|
# Счётчики правильных предсказаний
|
|||
|
|
correct = {
|
|||
|
|
'model1': 0,
|
|||
|
|
'model2': 0,
|
|||
|
|
'model3': 0,
|
|||
|
|
'stacking': 0
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# Списки для хранения всех предсказаний (для расчёта AUC)
|
|||
|
|
predictions = {
|
|||
|
|
'model1': [],
|
|||
|
|
'model2': [],
|
|||
|
|
'model3': [],
|
|||
|
|
'stacking': []
|
|||
|
|
}
|
|||
|
|
actuals = []
|
|||
|
|
|
|||
|
|
print("Тестирование моделей...")
|
|||
|
|
print("="*80)
|
|||
|
|
|
|||
|
|
# Проверяем каждый матч
|
|||
|
|
for idx, match_row in matches_df.iterrows():
|
|||
|
|
match_id = match_row['match_id']
|
|||
|
|
radiant_win = match_row['radiant_win']
|
|||
|
|
|
|||
|
|
if match_id not in details_by_match:
|
|||
|
|
continue
|
|||
|
|
|
|||
|
|
details = details_by_match[match_id]
|
|||
|
|
|
|||
|
|
# Формируем payload
|
|||
|
|
payload = {}
|
|||
|
|
|
|||
|
|
# Разделяем на Radiant и Dire
|
|||
|
|
radiant_picks = sorted([d for d in details if d['team'] == 0], key=lambda x: x['order'])
|
|||
|
|
dire_picks = sorted([d for d in details if d['team'] == 1], key=lambda x: x['order'])
|
|||
|
|
|
|||
|
|
# Заполняем Radiant
|
|||
|
|
for i in range(5):
|
|||
|
|
if i < len(radiant_picks):
|
|||
|
|
payload[f'r_h{i+1}'] = radiant_picks[i]['hero_id']
|
|||
|
|
payload[f'r_p{i+1}'] = radiant_picks[i]['players_id'] if radiant_picks[i]['players_id'] else -1
|
|||
|
|
payload[f'rp_h{i+1}'] = radiant_picks[i]['pos'] if radiant_picks[i]['pos'] else -1
|
|||
|
|
else:
|
|||
|
|
payload[f'r_h{i+1}'] = -1
|
|||
|
|
payload[f'r_p{i+1}'] = -1
|
|||
|
|
payload[f'rp_h{i+1}'] = -1
|
|||
|
|
|
|||
|
|
# Заполняем Dire
|
|||
|
|
for i in range(5):
|
|||
|
|
if i < len(dire_picks):
|
|||
|
|
payload[f'd_h{i+1}'] = dire_picks[i]['hero_id']
|
|||
|
|
payload[f'd_p{i+1}'] = dire_picks[i]['players_id'] if dire_picks[i]['players_id'] else -1
|
|||
|
|
payload[f'dp_h{i+1}'] = dire_picks[i]['pos'] if dire_picks[i]['pos'] else -1
|
|||
|
|
else:
|
|||
|
|
payload[f'd_h{i+1}'] = -1
|
|||
|
|
payload[f'd_p{i+1}'] = -1
|
|||
|
|
payload[f'dp_h{i+1}'] = -1
|
|||
|
|
|
|||
|
|
# Предсказания
|
|||
|
|
try:
|
|||
|
|
# Модель 1: Heroes + Positions
|
|||
|
|
X1 = build_long_format_input(payload)
|
|||
|
|
pred1_proba = float(modelPro.predict_proba(X1)[0, 1])
|
|||
|
|
pred1 = pred1_proba >= 0.5
|
|||
|
|
|
|||
|
|
# Модель 2: Bag of Heroes
|
|||
|
|
X2 = build_bag_of_heroes_features(payload)
|
|||
|
|
pred2_proba = float(modelBagOfHeroes.predict_proba(X2)[0, 1])
|
|||
|
|
pred2 = pred2_proba >= 0.5
|
|||
|
|
|
|||
|
|
# Модель 3: With Players
|
|||
|
|
X3 = build_player_features(payload)
|
|||
|
|
pred3_proba = float(modelWithPlayers.predict_proba(X3)[0, 1])
|
|||
|
|
pred3 = pred3_proba >= 0.5
|
|||
|
|
|
|||
|
|
# Стекинг
|
|||
|
|
stack_result = predict_stacking(payload)
|
|||
|
|
pred_stack_proba = stack_result['radiant_win'] / 100.0
|
|||
|
|
pred_stack = pred_stack_proba >= 0.5
|
|||
|
|
|
|||
|
|
# Сохраняем предсказания
|
|||
|
|
predictions['model1'].append(pred1_proba)
|
|||
|
|
predictions['model2'].append(pred2_proba)
|
|||
|
|
predictions['model3'].append(pred3_proba)
|
|||
|
|
predictions['stacking'].append(pred_stack_proba)
|
|||
|
|
actuals.append(int(radiant_win))
|
|||
|
|
|
|||
|
|
# Подсчитываем правильные предсказания
|
|||
|
|
if pred1 == radiant_win:
|
|||
|
|
correct['model1'] += 1
|
|||
|
|
if pred2 == radiant_win:
|
|||
|
|
correct['model2'] += 1
|
|||
|
|
if pred3 == radiant_win:
|
|||
|
|
correct['model3'] += 1
|
|||
|
|
if pred_stack == radiant_win:
|
|||
|
|
correct['stacking'] += 1
|
|||
|
|
|
|||
|
|
# Показываем первые 10 матчей
|
|||
|
|
if idx < 10:
|
|||
|
|
actual_str = "Radiant" if radiant_win else "Dire"
|
|||
|
|
print(f"\nМатч #{idx+1} (ID: {match_id}):")
|
|||
|
|
print(f" Реальный результат: {actual_str} win")
|
|||
|
|
print(f" Модель 1: {pred1_proba*100:.1f}% Radiant ({'✓' if pred1 == radiant_win else '✗'})")
|
|||
|
|
print(f" Модель 2: {pred2_proba*100:.1f}% Radiant ({'✓' if pred2 == radiant_win else '✗'})")
|
|||
|
|
print(f" Модель 3: {pred3_proba*100:.1f}% Radiant ({'✓' if pred3 == radiant_win else '✗'})")
|
|||
|
|
print(f" Стекинг: {pred_stack_proba*100:.1f}% Radiant ({'✓' if pred_stack == radiant_win else '✗'})")
|
|||
|
|
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"Ошибка при обработке матча {match_id}: {e}")
|
|||
|
|
continue
|
|||
|
|
|
|||
|
|
# Итоговая статистика
|
|||
|
|
total = len(actuals)
|
|||
|
|
|
|||
|
|
print("\n" + "="*80)
|
|||
|
|
print("ИТОГОВАЯ СТАТИСТИКА")
|
|||
|
|
print("="*80)
|
|||
|
|
print(f"Всего проверено матчей: {total}\n")
|
|||
|
|
|
|||
|
|
print("Точность (Accuracy):")
|
|||
|
|
print(f" Модель 1 (Heroes + Positions): {correct['model1']}/{total} = {correct['model1']/total*100:.2f}%")
|
|||
|
|
print(f" Модель 2 (Bag of Heroes): {correct['model2']}/{total} = {correct['model2']/total*100:.2f}%")
|
|||
|
|
print(f" Модель 3 (With Players): {correct['model3']}/{total} = {correct['model3']/total*100:.2f}%")
|
|||
|
|
print(f" Мета-модель (Stacking): {correct['stacking']}/{total} = {correct['stacking']/total*100:.2f}%")
|
|||
|
|
|
|||
|
|
# Расчёт AUC
|
|||
|
|
from sklearn.metrics import roc_auc_score
|
|||
|
|
|
|||
|
|
print("\nAUC (Area Under ROC Curve):")
|
|||
|
|
try:
|
|||
|
|
auc1 = roc_auc_score(actuals, predictions['model1'])
|
|||
|
|
print(f" Модель 1 (Heroes + Positions): {auc1:.4f}")
|
|||
|
|
except:
|
|||
|
|
print(f" Модель 1 (Heroes + Positions): N/A")
|
|||
|
|
|
|||
|
|
try:
|
|||
|
|
auc2 = roc_auc_score(actuals, predictions['model2'])
|
|||
|
|
print(f" Модель 2 (Bag of Heroes): {auc2:.4f}")
|
|||
|
|
except:
|
|||
|
|
print(f" Модель 2 (Bag of Heroes): N/A")
|
|||
|
|
|
|||
|
|
try:
|
|||
|
|
auc3 = roc_auc_score(actuals, predictions['model3'])
|
|||
|
|
print(f" Модель 3 (With Players): {auc3:.4f}")
|
|||
|
|
except:
|
|||
|
|
print(f" Модель 3 (With Players): N/A")
|
|||
|
|
|
|||
|
|
try:
|
|||
|
|
auc_stack = roc_auc_score(actuals, predictions['stacking'])
|
|||
|
|
print(f" Мета-модель (Stacking): {auc_stack:.4f}")
|
|||
|
|
except:
|
|||
|
|
print(f" Мета-модель (Stacking): N/A")
|
|||
|
|
|
|||
|
|
print("\n" + "="*80)
|