Analyses eSports dans R : prédire les matchs Dota 2
L’analyse de l’eSport est encore un domaine sous-exploré dans l’écosystème R, ce qui en fait une niche idéale pour un travail pratique et original. Alors que les modèles de football, de basket-ball et de paris disposent déjà de communautés fortes, les jeux compétitifs tels que Dota 2 et Counter-Strike offrent des données riches sur les événements, des boucles de rétroaction rapides et des problèmes de prédiction intéressants. Dans cet article, je montrerai comment R peut être utilisé pour extraire des données de match, concevoir des fonctionnalités utiles, classer des joueurs ou des équipes et créer des modèles pour prédire les résultats des matchs.
L’idée principale est simple : traiter les matchs eSports comme n’importe quel autre ensemble de données de compétition structuré. Nous pouvons collecter des informations historiques sur les matchs, les transformer en prédicteurs au niveau de l’équipe ou du joueur, puis former des modèles d’apprentissage automatique qui estiment la probabilité de victoire. Pour Dota 2, l’écosystème OpenDota est particulièrement utile car il expose les données publiques des matchs et des joueurs via une API accessible depuis R.
Pourquoi l’analyse des sports électroniques convient parfaitement à R
R est particulièrement bien adapté à l’analyse de l’eSport car il combine la collecte, le nettoyage, la visualisation, la modélisation et le reporting de données dans un seul flux de travail. Avec les packages de Tidyverse, Tidymodels et des outils API tels que httr et jsonliteil devient simple de passer de points de terminaison de correspondance bruts à un pipeline prédictif.
C’est aussi l’une des raisons pour lesquelles le sujet se démarque. Comparé aux sports grand public, l’eSport a encore une couverture R beaucoup moins mature, donc un article axé sur prédire les matchs de Dota 2 dans R se sent frais. Il est pratique, techniquement intéressant et pertinent pour les analystes qui souhaitent travailler sur des ensembles de données sportives non traditionnelles.
Questions d’analyse typiques dans les jeux Dota 2 ou de style CS
Une fois les données de match disponibles, plusieurs problèmes intéressants apparaissent naturellement :
- Quelles caractéristiques de l’équipe sont les plus associées à la victoire ?
- Peut-on prédire l’issue d’un match avant qu’il ne commence ?
- Quels joueurs surpassent les attentes de leur rôle ou de leur groupe ?
- Certains héros, cartes ou compositions créent-ils des bords mesurables ?
- Quelle est la stabilité des notes des équipes dans le temps ?
Certaines d’entre elles sont des tâches de classification, d’autres des problèmes de classement ou de régression, et plusieurs peuvent bénéficier d’une modélisation temporelle. Si vous aimez les approches probabilistes, un livre d’analyse bayésienne du sport en R peut être un complément utile lorsque vous souhaitez passer de prédictions ponctuelles à des prévisions tenant compte de l’incertitude.
Collecte de données en R avec OpenDota
Un point de départ pratique est les données de correspondance Dota 2 de l’API OpenDota. Dans R, vous pouvez travailler soit avec un wrapper dédié tel que ROpenDota lorsqu’il est disponible dans votre environnement, ou appelez l’API directement avec httr2, httret jsonlite. Je préfère souvent les appels API directs car ils rendent le flux de données plus transparent et plus facile à déboguer.
L’exemple ci-dessous montre un moyen simple de récupérer des matchs professionnels récents et de les convertir en un tibble bien rangé.
library(httr2) library(jsonlite) library(dplyr) library(purrr) library(tibble) base_url <- " resp <- request(base_url) |> req_perform() pro_matches <- resp |> resp_body_string() |> fromJSON(flatten = TRUE) |> as_tibble() glimpse(pro_matches)
A ce stade, l’objectif principal n’est pas encore la modélisation. Il s’agit de comprendre ce que contient l’ensemble de données. Vous souhaitez inspecter des variables telles que les identifiants des matchs, les heures de début, les noms des équipes rayonnantes et désastreuses, la durée, les informations sur la ligue et le vainqueur final. Une fois la structure claire, l’étape suivante consiste à collecter des détails plus riches au niveau du match ou du joueur.
Téléchargement des enregistrements de match détaillés
Les modèles prédictifs nécessitent généralement plus qu’un résultat de correspondance de haut niveau. Nous voulons souvent des détails par match : éliminations, décès, passes décisives, or par minute, expérience par minute, choix de héros, interdictions, type de lobby, informations sur les correctifs et agrégats au niveau de l’équipe. Un flux de travail courant consiste à récupérer un ensemble d’ID de correspondance, puis à parcourir le point de terminaison détaillé pour chaque correspondance.
library(httr2)
library(jsonlite)
library(dplyr)
library(purrr)
library(tidyr)
get_match_details <- function(match_id)
url <- paste0(" match_id)
tryCatch(
request(url) , error = function(e)
NULL
)
sample_ids <- pro_matches |>
slice_head(n = 50) |>
pull(match_id)
match_details_raw <- map(sample_ids, get_match_details)
match_details_raw <- compact(match_details_raw)
Cela nous donne une liste des enregistrements de matchs. À partir de là, nous pouvons créer une table de modélisation au niveau de l’équipe. Pour le travail prédictif, cela signifie généralement une ligne par équipe et par match, ainsi qu’une variable cible indiquant si cette équipe a gagné.
Ingénierie des fonctionnalités pour la prédiction des matchs
L’ingénierie des fonctionnalités est l’endroit où la majeure partie de la valeur est créée. Un modèle devient rarement utile grâce à l’algorithme seul ; cela devient utile car les variables d’entrée capturent quelque chose de significatif sur la qualité, l’élan ou la composition de l’équipe.
Certaines fonctionnalités intéressantes des candidats incluent :
- Taux de victoire récent sur les 5 ou 10 derniers matchs
- KDA moyen de l’équipe lors des matchs récents
- Or moyen par minute et expérience par minute
- Diversité du pool de héros
- Performances spécifiques au correctif
- Proxy de force de l’adversaire
- Indicateur secondaire tel que Radiant vs Dire
- Temps écoulé depuis le dernier match de l’équipe
Un pipeline d’ingénierie de base au niveau de l’équipe dans R pourrait ressembler à ceci :
library(dplyr) library(purrr) library(tidyr) library(stringr) team_rows <- map_dfr(match_details_raw, function(m) ) team_rows
Ce tableau est déjà suffisant pour un premier modèle de classification. Il n’est pas parfait et n’inclut pas encore de fonctionnalités de pré-match uniquement, mais il est idéal pour le prototypage. Dans les prévisions réelles, nous devons faire attention à ne pas divulguer d’informations d’après-match dans l’objectif de prédiction. Par exemple, les éliminations finales et le GPM moyen conviennent pour une analyse explicative mais pas pour de véritables prévisions d’avant-match.
Construire un ensemble de données d’avant-match approprié
Si l’objectif est de prédire le vainqueur avant le début du jeu, alors chaque fonctionnalité doit être disponible avant la première seconde du match. Cela signifie que les résumés historiques glissants sont généralement meilleurs que les totaux en cours de match. Une configuration plus propre est :
- Trier les matchs par ordre chronologique
- Créez une ligne par équipe et par match
- Calculer uniquement les caractéristiques glissantes des matchs précédents
- Rejoignez les deux équipes en compétition dans un face-à-face
- Former un classificateur binaire sur le gagnant
Voici un exemple simplifié de formulaire d’équipe glissant :
library(dplyr)
library(slider)
team_history <- team_rows |>
arrange(match_id) |>
group_by(side) |>
mutate(
recent_win_rate = slide_dbl(win, mean, .before = 5, .complete = FALSE),
recent_avg_kills = slide_dbl(team_kills, mean, .before = 5, .complete = FALSE),
recent_avg_deaths = slide_dbl(team_deaths, mean, .before = 5, .complete = FALSE)
) |>
ungroup()
Dans un ensemble de données plus complet, vous calculeriez ces statistiques glissantes en fonction de l’identité réelle de l’équipe plutôt que par côté uniquement. Cela produit un signal de force d’équipe beaucoup plus réaliste.
Prédire les résultats des matchs avec des modèles bien rangés
Une fois qu’une table de modélisation propre est prête, tidymodels fournit un cadre élégant pour diviser les données, prétraiter les prédicteurs, former des modèles et évaluer les performances. La régression logistique constitue une base de référence solide car elle est interprétable et rapide. Après cela, des méthodes basées sur les arbres telles que les forêts aléatoires ou l’augmentation de gradient peuvent être testées.
library(tidymodels)
model_data <- team_rows |>
select(win, team_kills, team_deaths, team_assists, avg_gpm, avg_xpm, hero_diversity, duration) |>
mutate(win = factor(win, levels = c(0, 1)))
set.seed(123)
split_obj <- initial_split(model_data, prop = 0.8, strata = win)
train_data <- training(split_obj)
test_data <- testing(split_obj)
rec <- recipe(win ~ ., data = train_data) |>
step_impute_median(all_numeric_predictors()) |>
step_normalize(all_numeric_predictors())
log_spec <- logistic_reg() |>
set_engine("glm")
wf <- workflow() |>
add_recipe(rec) |>
add_model(log_spec)
fit_log <- fit(wf, data = train_data)
preds <- predict(fit_log, test_data, type = "prob") |>
bind_cols(predict(fit_log, test_data)) |>
bind_cols(test_data)
roc_auc(preds, truth = win, .pred_1)
accuracy(preds, truth = win, .pred_class)
Le premier modèle est rarement le modèle final, mais il nous donne une base de référence. Si les performances sont faibles, cela signifie généralement que le problème réside dans l’ensemble des fonctionnalités plutôt que dans la syntaxe de modélisation. De meilleures variables historiques, de meilleurs identifiants d’équipe et de meilleures données tenant compte des correctifs comptent souvent plus que le changement immédiat d’algorithme.
Aller au-delà de la régression logistique
Après une base de référence, plusieurs améliorations sont possibles. Les forêts aléatoires peuvent capturer des relations non linéaires. L’augmentation du dégradé fonctionne souvent bien lorsque les interactions entre les fonctionnalités sont importantes. Les modèles bayésiens peuvent être particulièrement intéressants lorsque la taille des échantillons est inégale ou lorsque vous souhaitez des distributions de probabilité plutôt que des estimations ponctuelles. Pour les lecteurs intéressés par la pensée probabiliste et l’incertitude prédictive, une ressource sur les paris sportifs bayésiens avec R peut aider à relier les résultats du modèle à la prise de décision pratique.
rf_spec <- rand_forest(
trees = 500,
min_n = 5
) |>
set_engine("ranger") |>
set_mode("classification")
rf_wf <- workflow() |>
add_recipe(rec) |>
add_model(rf_spec)
fit_rf <- fit(rf_wf, data = train_data)
rf_preds <- predict(fit_rf, test_data, type = "prob") |>
bind_cols(predict(fit_rf, test_data)) |>
bind_cols(test_data)
roc_auc(rf_preds, truth = win, .pred_1)
accuracy(rf_preds, truth = win, .pred_class)
Un bon article n’a pas besoin de revendiquer un pouvoir prédictif parfait. En fait, les lecteurs font généralement davantage confiance à l’analyse lorsque vous expliquez clairement les contraintes. Les effectifs des équipes changent, les correctifs modifient la méta, les données publiques peuvent être incomplètes et de nombreux matchs sont influencés par des facteurs contextuels difficiles à encoder numériquement.
Idées de classement et de notation des joueurs
La prédiction de match n’est qu’un seul angle. Une autre direction forte est la classification des joueurs. Par exemple, nous pouvons regrouper les joueurs en fonction de leur agressivité, de leur style de farm, de leur contribution au soutien et de leur efficacité. Ceci est particulièrement intéressant car les rôles dans l’eSport sont à la fois stratégiques et comportementaux.
Un simple flux de travail non supervisé peut inclure :
- K-means clustering sur les mesures de performances des joueurs
- PCA pour la réduction de dimensionnalité et la visualisation
- Classification des rôles à l’aide d’exemples étiquetés
- Systèmes de notation de style Elo ou Glicko pour des estimations de compétences évolutives
library(dplyr)
library(ggplot2)
player_data <- map_dfr(match_details_raw, function(m) length(m$players) == 0) return(NULL)
as_tibble(m$players) ) |>
filter(!is.na(account_id))
player_summary <- player_data |>
group_by(account_id) |>
summarise(
avg_kills = mean(kills, na.rm = TRUE),
avg_deaths = mean(deaths, na.rm = TRUE),
avg_assists = mean(assists, na.rm = TRUE),
avg_gpm = mean(gpm, na.rm = TRUE),
avg_xpm = mean(xpm, na.rm = TRUE),
avg_last_hits = mean(last_hits, na.rm = TRUE),
matches = n(),
.groups = "drop"
) |>
filter(matches >= 10)
À partir de là, le regroupement ou la classification supervisée devient simple. C’est le genre de section qui donne l’impression qu’un article sur l’eSport est plus large qu’un simple didacticiel API.
Des idées de visualisation qui rendent la publication plus forte
Les visuels peuvent transformer une publication technique en une publication mémorable. Dans l’eSport, quelques intrigues sont particulièrement efficaces :
- Gagner des tracés d’étalonnage de probabilité
- Graphiques de forme d’équipe glissante
- Utilisation des héros et cartes thermiques du taux de victoire
- Nuages de points de cluster de joueurs de PCA
- Graphiques d’importance des fonctionnalités pour les modèles d’arbres
Par exemple, voici un simple tableau d’importance des variables après ajustement d’une forêt aléatoire :
library(vip) fit_rf |> extract_fit_parsnip() |> vip()
Le but de ces parcelles n’est pas seulement la décoration. Ils aident à répondre visuellement à la question analytique : qu’est-ce qui détermine réellement le succès de l’équipe et quels signaux semblent stables d’un match à l’autre ?
Qu’en est-il de Counter-Strike ou d’autres titres d’eSports ?
Le même flux de travail se généralise bien. Même si le support des packages est moins standardisé que dans Dota 2, la logique de modélisation reste la même :
- Collecter des données de match historiques
- Créer des fonctionnalités pour l’équipe et les joueurs
- Utiliser des fenêtres déroulantes pour représenter le formulaire récent
- Modèles de classification ou de notation des trains
- Évaluez les probabilités, pas seulement les prédictions difficiles
Dans les ensembles de données de style Counter-Strike, les caractéristiques probables incluent les taux de victoire sur la carte, la force spécifique au camp, le différentiel de victoires récentes, la stabilité de la liste et l’historique des face-à-face. En ce sens, le sport change, mais pas le flux de travail R.
Pourquoi ce genre de message peut se démarquer
Un article sur l’analyse des sports électroniques dans R se démarque car il se situe à l’intersection de la nouveauté de la science des données et de la modélisation pratique. Il est suffisamment spécifique pour être utile, mais suffisamment inhabituel pour attirer les lecteurs fatigués des mêmes exemples répétés des sports traditionnels. Un titre construit autour de la prédiction des matchs Dota 2 est particulièrement efficace car il communique immédiatement un livrable concret.
Il s’intègre également naturellement dans un parcours d’apprentissage plus large en analyse sportive. Les lecteurs qui découvrent ce sujet via l’eSport voudront peut-être plus tard explorer le travail dans le football, le football ou la modélisation multisports, où des livres tels que Football Analytics with R, Mastering Sports Analytics with R: Soccer ou Sports Analytics with R dans plusieurs sports peuvent étendre le même état d’esprit analytique à d’autres domaines.
Réflexions finales
L’analyse des sports électroniques mérite plus d’attention dans R, et Dota 2 est l’un des meilleurs points de départ. Grâce à l’accès aux API, à des flux de données ordonnés et à des outils de modélisation flexibles, il est possible de passer d’enregistrements de correspondance publics bruts à des systèmes prédictifs significatifs entièrement dans R. Même une première version simple peut en apprendre beaucoup sur l’ingénierie des données, la conception des fonctionnalités, la classification et l’évaluation.
La véritable opportunité n’est pas seulement de prédire les gagnants, mais aussi de construire un cadre reproductible pour comprendre les performances des équipes, les styles des joueurs et la dynamique compétitive dans des jeux qui deviennent chaque année plus importants. Cette combinaison de nouveauté, de richesse de données et de profondeur analytique est exactement ce qui fait de l’eSport un sujet si convaincant pour un article R.
PakarPBN
A Private Blog Network (PBN) is a collection of websites that are controlled by a single individual or organization and used primarily to build backlinks to a “money site” in order to influence its ranking in search engines such as Google. The core idea behind a PBN is based on the importance of backlinks in Google’s ranking algorithm. Since Google views backlinks as signals of authority and trust, some website owners attempt to artificially create these signals through a controlled network of sites.
In a typical PBN setup, the owner acquires expired or aged domains that already have existing authority, backlinks, and history. These domains are rebuilt with new content and hosted separately, often using different IP addresses, hosting providers, themes, and ownership details to make them appear unrelated. Within the content published on these sites, links are strategically placed that point to the main website the owner wants to rank higher. By doing this, the owner attempts to pass link equity (also known as “link juice”) from the PBN sites to the target website.
The purpose of a PBN is to give the impression that the target website is naturally earning links from multiple independent sources. If done effectively, this can temporarily improve keyword rankings, increase organic visibility, and drive more traffic from search results.