
Ecole Nationale de la Statistique et de l’Analyse de l’Information
2025-07-03
Ligue professionnelle de basketball la plus compétitive au monde
30 équipes (Est et Ouest), 82 matchs de saison régulière
Données riches et variées sur l’ensemble de la ligue :
suivi très détaillé des performances
des archives complètes depuis plus de 75 ans
Problématique : Prédire la durée de carrière des joueurs nouvellement draftés
Objectif 1 : identifier des questions décrivant le jeu de données
Analyse exploratoire des données afin de répondre à 10 interrogations
Questions explorant différentes dimensions du basketball (équipes, les joueurs, les matchs, les play-offs ou encore la draft)
Objectif 2 : prédire la durée de carrière des joueurs NBA
Objectif 3 : développer et déployer une application

Travail de préparation des données :
Philadelphia Warriors ⇒ San Francisco Warriors ⇒ Golden State Warriors

Reponseclass Reponse:
def __init__(self, data: dict[pd.DataFrame]):
# Réalisons les tests nécessaire sur l'objet data
if (
not isinstance(data, dict)
):
raise TypeError("L'argument data doit être un dictionnaire.")
if (
any(not isinstance(data[key], pd.DataFrame) for key in data.keys())
):
raise TypeError("Toutes les valeurs des clés doivents être des "
"pandas.DataFrame.")
# Testons qu'on a bien la clé common_player_info dans le dictionnaire
if ("draft_history" not in data.keys()):
raise KeyError("La clé 'draft_history' ne fait pas parti du dictionnaire")
if ("common_player_info" not in data.keys()):
raise KeyError("La clé 'common_player_info' ne fait pas parti du "
"dictionnaire")
if ("game" not in data.keys()):
raise KeyError("La clé 'game' ne fait pas parti du dictionnaire")
self.data = copy.deepcopy(data)Entrée :
Vérification des entrées :
Présence des tables d’intérêt dans le dictionnaire
Reponse
⇐ Les méthodes indexées :
(1) retourne une table contenant le nombre de victoires ou de défaites pour chaque équipe entre les saisons données.
(2) retourne une table listant les équipes ayant remporté au moins le nombre de titres requis.
(3) retourne un dictionnaire contenant deux tables, un pour chaque conférence (Est et Ouest).
equip_victoires_defaites_saison et ses usagesdef equip_victoires_defaites_saison(self, annee_debut: int, annee_fin: int,
season_type: str = 'Regular Season',
defaite: bool = False) -> pd.DataFrame:Entrées : période – type de saison – l’issue du match
Traitement pour l’obtention du nombre de victoires ou de défaites :
# Détermination des équipes en fonction du résultat souhaité
game_chosen_season['Equipes'] = np.where(
((game_chosen_season['wl_home'] == "W") & (not defaite)) |
((game_chosen_season['wl_home'] == "L") & defaite),
game_chosen_season['team_name_home'],
game_chosen_season['team_name_away']
)
# Agrégation des résultats
results = game_chosen_season.groupby(["season_years", "Equipes"]).aggregate({
'wl_home': 'count',
'Equipes': 'first',
'season_years': 'first'
}).reset_index(drop=True)equipe_remporte_au_moins_N_fois_le_titredef equipe_remporte_au_moins_N_fois_le_titre(self, nb_victoire_min: int = 3,
debut_periode: int = 1946,
fin_periode: int = 2023
) -> pd.DataFrame
(1) nba_champions_manquant = {
"1957-1958": "Atlanta Hawks", "1958-1959": "Boston Celtics", "1960-1961": "Boston Celtics",
"1964-1965": "Boston Celtics", "1968-1969": "Boston Celtics", "1993-1994": "Houston Rockets",
"1995-1996": "Chicago Bulls", "1999-2000": "Los Angeles Lakers", "2001-2002": "Los Angeles Lakers", "2005-2006": "Miami Heat"
}Sélection des données
Identification des vainqueurs de chaque saison
Alimentation des résultats (1)
Edition de la table avec le nombre de titres gagnés sur la période par équipe
Renvoi de la table avec les équipes avec au moins 3 titres NBA
classement_conferencesdef classement_conferences(self, season: str = '2022-2023',
end: str = None) -> dict[pd.DataFrame]:
. . .
classement = {"Conférence Est": classement_est,
"Conférence Ouest": classement_ouest}Sélection des données (saison régulière)
Identification du nombre de victoire par équipe
Classement selon la conférence
Renvoie les deux tables correspondantes aux conférences Est et Ouest
Reponse
| Equipe | Nombre.de.titre.NBA |
|---|---|
| Boston Celtics | 17 |
| Los Angeles Lakers | 17 |
| Golden State Warriors | 7 |
| Chicago Bulls | 6 |
| Philadelphia 76ers | 6 |
| San Antonio Spurs | 5 |
| Miami Heat | 3 |
| Detroit Pistons | 3 |
| Houston Rockets | 3 |

| Equipe conférence Est | Victoires | Points | Equipe conférence Ouest | Victoires | Points |
|---|---|---|---|---|---|
| Milwaukee Bucks | 58 | 9589 | Denver Nuggets | 53 | 9495 |
| Boston Celtics | 57 | 9671 | Memphis Grizzlies | 51 | 9587 |
| Philadelphia 76ers | 54 | 9448 | Sacramento Kings | 48 | 9898 |
| Cleveland Cavaliers | 51 | 9205 | Phoenix Suns | 45 | 9319 |
| New York Knicks | 47 | 9514 | Golden State Warriors | 44 | 9753 |
| Brooklyn Nets | 45 | 9295 | LA Clippers | 44 | 9314 |
| Miami Heat | 44 | 8977 | Los Angeles Lakers | 43 | 9608 |
| Atlanta Hawks | 41 | 9711 | Minnesota Timberwolves | 42 | 9494 |
| Toronto Raptors | 41 | 9254 | New Orleans Pelicans | 42 | 9378 |
| Chicago Bulls | 40 | 9276 | Oklahoma City Thunder | 40 | 9633 |
| Indiana Pacers | 35 | 9535 | Dallas Mavericks | 38 | 9366 |
| Washington Wizards | 35 | 9279 | Utah Jazz | 37 | 9600 |
| Orlando Magic | 34 | 9136 | Portland Trail Blazers | 33 | 9299 |
| Charlotte Hornets | 27 | 9098 | San Antonio Spurs | 22 | 9269 |
| Detroit Pistons | 17 | 9045 | Houston Rockets | 22 | 9081 |
| Saison | Nom | Equipe | Pays |
|---|---|---|---|
| 2019 | Zion Williamson | New Orleans | USA |
| 2020 | Anthony Edwards | Minnesota | USA |
| 2021 | Cade Cunningham | Detroit | USA |
| 2022 | Paolo Banchero | Orlando | USA |
| 2023 | Victor Wembanyama | San Antonio | France |
| position | Taille.cm | Poids.Kg |
|---|---|---|
| Pivot | 210.82 | 108.86 |
| Pivot/Ailier fort | 210.82 | 113.40 |
| Ailier | 200.66 | 98.88 |
| Ailier fort/Pivot | 208.28 | 108.86 |
| Ailier/Meneur | 200.66 | 99.79 |
| Arrière/Meneur | 190.50 | 86.18 |
| Arrière/Ailier | 198.12 | 95.25 |

PRINCIPE : Prédire une variable quantitative à l’aide d’une ou plusieurs variables explicatives (quantitatives ou qualitatives)
\[\begin{equation} y = \beta X + \epsilon \end{equation}\]
où \(\beta\) est le coefficient associé aux variables explicatives \(X\) et \(\epsilon\) le terme d’erreur.

Variables retenues



LinearRegressiondef fit(self, X: np.ndarray, y: np.ndarray):
"""
Estime les coefficients de régression par OLS.
Parameters
----------
X : np.ndarray
Matrice des prédicteurs.
y : np.ndarray
Vecteur cible.
Returns
-------
np.ndarray
Coefficients estimés.
"""
if not isinstance(X, np.ndarray) or not isinstance(y, np.ndarray):
raise TypeError("X et Y doivent-être de type np.ndarray")
cond_number = np.linalg.cond(X.T @ X)
if cond_number > 1e10:
warnings.warn(
"Matrice X.T @ X mal conditionnée (cond > 1e10)."
"Risque de multicolinéarité."
)
X_X_inv = np.linalg.pinv(X.T @ X)
Beta = X_X_inv @ X.T @ y
return Betas| Variable | Estimation | Borne.inférieure | Borne.supérieure |
|---|---|---|---|
| intercept | 13.0807938172894 | 11.2139999315576 | 14.9475877030211 |
| age_at_draft | -0.304520510475786 | -0.385970108084788 | -0.223070912866783 |
| Pivot-Ailier fort | 4.03469135857516 | 2.58019430274557 | 5.48918841440475 |
| Ailier | -0.723448794163931 | -1.24222365227521 | -0.204673936052656 |
| Ailier fort-Pivot | 3.00118640834299 | 1.80323628965945 | 4.19913652702653 |
| Ailier-Arrière | 1.31879081528329 | -0.203041070946694 | 2.84062270151327 |
| Arrière | -0.779850850158738 | -1.30098176750811 | -0.258719932809363 |
| Arrière-Ailier | 1.88960963320118 | 0.805602797554438 | 2.97361646884792 |
Age à la draft + 1 ⇒ diminution moyenne de la durée de carrière de 0.30 ans
Un pivot/ailier a plus de chance de durer à la NBA que les joueurs occupant les autres postes
Un arrière a moins de chance de durer à la NBA que les joueurs occupant les autres postes
Prédiction : \(exp = 13,08 - 0.305*Age_{draft} + \beta_j*Poste_j\)
Age_a_la_draft = 18 ans et Poste = Pivot
Durée de carrière : 7.6 ans
Intervalle de confiance [4.3, 10.9]
Ce projet entre pleinement dans le domaine de l’informatique appliquée aux données.
Suivi du processus : nettoyage, exploration et modélisation
Réponses rigoureuses aux questions posées
Construction d’un modèle supervisé pour prédire la durée de carrière des joueurs
Avantages
Acquisition de compétences transversales : manipulation de données, machine learning, visualisation interactive.
Intervalle de confiance des prédictions
Implémentation manuelle du modèle supervisé
Modularisation du code facilitant la maintenance et la réutilisation.
Prise d’initiatives (création d’une interface, traitement des noms d’équipes changeants, gestion des données manquantes)
Difficultés
Erreur de prédiction plus ou moins élevée (4,6 ans)
Des attentes initiales manquaient de clarté
Quelques difficultés à identifier et corriger les incohérences dans les données historiques


Soutenance du projet traitement de données 1A