Date Notes du scientifique: Comment mesurer les temps de course du marathon en position couchée sur le canapé



Poursuivant le cycle de notes sur des problÚmes réels en Data Science, nous allons aujourd'hui traiter d'un problÚme vivant et voir quels problÚmes nous attendent en cours de route.



Par exemple, en plus de la Data Science, je suis fanatique de l'athlĂ©tisme depuis longtemps et l'un des objectifs de la course Ă  pied pour moi, bien sĂ»r, est le marathon. Et oĂč est le marathon lĂ -bas et la question est - combien courir? Souvent, la rĂ©ponse Ă  cette question est donnĂ©e Ă  l'Ɠil nu - "eh bien, en moyenne, ils courent" ou "c'est un bon moment!"



Et aujourd'hui, nous serons engagés dans une affaire importante - nous appliquerons la science des données dans la vie réelle et répondrons à la question:



que nous disent les données sur le marathon de Moscou?



Plus prĂ©cisĂ©ment, comme il ressort du tableau au dĂ©but, nous collecterons des donnĂ©es, dĂ©terminerons qui a couru et comment. Et en mĂȘme temps, cela nous aidera Ă  comprendre si nous devons intervenir et nous permettra d'Ă©valuer raisonnablement notre force!



TL; DR: J'ai collecté des données sur les courses marathon de Moscou pour 2018/2019, analysé le temps et les performances des participants, et rendu le code et les données accessibles au public.



Collecte de données



Grùce à une recherche rapide sur Google, nous avons trouvé les résultats des deux derniÚres années, 2019 et 2018 .







J'ai regardé attentivement la page Web, il est devenu clair que les données sont assez faciles à obtenir - il vous suffit de déterminer quelles classes sont responsables de ce que, par exemple, la classe «results-table__col-result», bien sûr, pour le résultat, etc.



Il reste à comprendre comment obtenir toutes les données à partir de là.







Et cela, il s'avĂšre, n'est pas difficile, car il y a une pagination directe et nous itĂ©rons en fait sur tout le segment de nombres. Bingo, je poste les donnĂ©es collectĂ©es pour 2019 et 2018 ici, si quelqu'un est intĂ©ressĂ© par une analyse plus approfondie, les donnĂ©es elles-mĂȘmes peuvent ĂȘtre tĂ©lĂ©chargĂ©es ici: ici et ici .



Qu'est-ce que j'avais Ă  bricoler?



  • — - , , - (, ).
  • - , — « ».
  • Url- — - , url — , — .
  • — — 2016, 2017
 , 2019 — , — , — , , .
  • NA: DNF, DQ, "-" — , , .
  • Types de donnĂ©es: le temps ici est un delta temporel, mais en raison de redĂ©marrages et de valeurs invalides, nous devons travailler avec des filtres et effacer les valeurs de temps afin de fonctionner sur des rĂ©sultats en temps pur pour calculer des moyennes - tous les rĂ©sultats ici sont en moyenne sur ceux qui ont terminĂ© et qui a un temps valide.


Et voici le code spoiler au cas oĂč quelqu'un dĂ©ciderait de continuer Ă  collecter des donnĂ©es de fonctionnement intĂ©ressantes.



Code analyseur
from bs4 import BeautifulSoup
import requests
from tqdm import tqdm

def main():
    for year in [2018]:
        print(f"processing year: {year}")
        crawl_year(year)


def crawl_year(year):
    outfilename = f"results_{year}.txt"
    with open(outfilename, "a") as fout:
        print("name,result,place,country,category", file=fout)
    # parametorize year
    for i in tqdm(range(1, 1100)):
        url = f"https://results.runc.run/event/absolute_moscow_marathon_2018/finishers/distance/1/page/{i}/"
        html = requests.get(url)
        soup = BeautifulSoup(html.text)
        names = list(
            map(
                lambda x: x.text.strip(),
                soup.find_all("div", {"class": "results-table__values-item-name"}),
            )
        )
        results = list(
            map(
                lambda x: x.text.strip(),
                soup.find_all("div", {"class": "results-table__col-result"}),
            )
        )[1:]
        categories = list(
            map(
                lambda x: x.text.strip().replace(" ",""),
                soup.find_all("div", {"class": "results-table__values-item-country"}),
            )
        )
        places = list(
            map(
                lambda x: x.text.strip(),
                soup.find_all("div", {"class": "results-table__col-place"}),
            )
        )[1:]
        for name, result, place, category in zip(names, results, places, categories):
            with open(outfilename, "a") as fout:
                print(name, result, place, category, sep=",", file=fout)


if __name__ == "__main__":
    main()
```


Analyse du temps et des résultats



Passons Ă  l'analyse des donnĂ©es et des rĂ©sultats rĂ©els de la course. 

Pandas d'occasion, numpy, matplotlib et seaborn - tous dans les classiques.



En plus des valeurs moyennes pour tous les tableaux, nous considérerons séparément les groupes suivants:



  • Hommes - puisque j'appartiens Ă  ce groupe, ces rĂ©sultats m'intĂ©ressent.
  • Les femmes sont pour la symĂ©trie.
  • 35 — «» , — .
  • 2018 2019 — ?.


Tout d'abord, jetons un coup d'Ɠil au tableau ci-dessous - lĂ  encore, pour ne pas faire dĂ©filer: il y a plus de participants, 95% en moyenne atteignent la ligne d'arrivĂ©e, et la plupart des participants sont des hommes. D'accord, cela signifie que je suis dans le groupe principal en moyenne et que les donnĂ©es en moyenne devraient bien reprĂ©senter le temps moyen pour moi. Nous allons continuer.











Comme nous pouvons le voir, les moyennes pour 2018 et 2019 n'ont pratiquement pas changé - environ 1,5 minute étaient plus rapides pour les coureurs en 2019. La différence entre les groupes qui m'intéressent est négligeable.



Passons aux distributions dans leur ensemble. Et d'abord le temps total de la course.





Comme nous pouvons voir le pic juste avant 4 heures - c'est une marque conditionnelle pour ceux qui aiment «bien courir» = «manquer de 4 heures», les données confirment la rumeur populaire.



Voyons ensuite comment la situation a évolué en moyenne au cours de l'année.







Comme nous pouvons le voir, en fait, rien n'a changé du tout - les distributions semblent pratiquement identiques.



Ensuite, considérons les distributions par sexe:











En général, les deux distributions sont normales avec des centres légÚrement différents - nous voyons que le pic chez le mùle se manifeste également sur la distribution principale (générale).



Séparément, passons au groupe qui m'intéresse le plus:







comme nous pouvons le voir, l'image est fondamentalement la mĂȘme que dans le groupe masculin dans son ensemble.

De cela, nous concluons que 4 heures est Ă©galement un bon temps moyen pour moi.



Etudier les amĂ©liorations des participants 2018 → 2019



IntĂ©ressant: pour une raison quelconque, je pensais que maintenant je collecterais rapidement des donnĂ©es et que je pourrais approfondir l'analyse, y rechercher des modĂšles pendant des heures, etc. Il s'est avĂ©rĂ© que c'Ă©tait l'inverse, la collecte de donnĂ©es s'est avĂ©rĂ©e plus difficile que l'analyse elle-mĂȘme - selon les classiques, travailler avec le rĂ©seau, les donnĂ©es brutes, le nettoyage, le formatage, la diffusion, etc., a pris beaucoup plus de temps que l'analyse et la visualisation. N'oubliez pas que les petites choses prennent un peu de temps - mais il y en a pas mal de [petites choses], et Ă  la fin, elles mangeront toute votre soirĂ©e.



Séparément, je voulais voir comment les personnes qui ont participé les deux fois ont amélioré leurs résultats, en comparant les données entre les années, j'ai pu établir ce qui suit:



  • 14 personnes ont participĂ© les deux annĂ©es et n'ont jamais fini
  • 89 personnes ont couru Ă  18 m, mais ont Ă©chouĂ© Ă  19
  • 124 vice versa
  • Ceux qui ont pu courir les deux fois ont amĂ©liorĂ© leur rĂ©sultat de 4 minutes en moyenne


Mais ici, tout s'est avéré assez intéressant:







c'est-à-dire qu'en moyenne, les gens améliorent légÚrement les résultats - mais en général, la propagation est incroyable et dans les deux sens - c'est-à-dire qu'il est bon d'espérer que ce sera mieux - mais à en juger par les données, cela s'avÚre en général comme vous le souhaitez!



conclusions



J'ai tirĂ© les conclusions suivantes pour moi-mĂȘme Ă  partir des donnĂ©es analysĂ©es



  • Dans l'ensemble, 4 heures est un bon objectif moyen.

  • Le groupe principal de coureurs est dĂ©jĂ  Ă  l'Ăąge trĂšs compĂ©titif (et dans le mĂȘme groupe que moi).

  • En moyenne, les gens amĂ©liorent lĂ©gĂšrement leurs rĂ©sultats, mais en gĂ©nĂ©ral, Ă  en juger par les donnĂ©es, comment ils y parviennent.

  • Les rĂ©sultats moyens pour toute la course sont Ă  peu prĂšs les mĂȘmes pour les deux annĂ©es.

  • Il est trĂšs confortable de parler du marathon depuis le canapĂ©.






All Articles