[PYTHON] J'ai essayé de visualiser la tranche d'âge et la distribution des taux d'Atcoder

introduction

J'ai essayé de visualiser la distribution des tranches d'âge et les taux de personnes participant à AtCoder (programmation de compétition) par grattage et traitement statistique avec Python.

Contenu approximatif

  1. Groupe d'âge AtCoder
  2. Répartition des tarifs pour le nombre de participants
  3. Relation entre l'âge et le taux
  4. Code source utilisé référence

1. Groupe d'âge AtCoder

Tout d'abord, les groupes d'âge participant à Atcoder sont grattés et tabulés, ils sont donc indiqués ci-dessous. De plus, les personnes qui n'indiquent pas leur âge dans leur profil ne sont pas comptabilisées. Comme vous pouvez l'imaginer, il y a beaucoup de jeunes, surtout des étudiants universitaires.

image.png

2. Répartition des tarifs pour le nombre de participants

Visualisation avec moyenne et écart type

Sans surprise, il semble y avoir une corrélation entre le nombre d'inscriptions au concours et le taux. En passant, selon les spécifications du système de notation d'AtCoder, si le nombre de participation est de 10 ou moins, le taux peut être nettement inférieur à la capacité réelle. Veuillez consulter la page suivante pour plus de détails. À propos de l'évaluation du concours AtCoder

J'ai essayé de visualiser le taux d'utilisateurs actifs par la valeur moyenne et l'écart type pour chaque nombre de participation au concours jusqu'à présent. La valeur moyenne est le point bleu et la valeur moyenne ± écart type est indiquée par la bande jaune. Même après avoir soustrait les spécifications du système de notation ci-dessus, il semble y avoir une corrélation positive entre le nombre de participations et le taux. Dans mon imagination, si le nombre de participation est d'environ 30 fois, il n'y a pas beaucoup de corrélation entre le nombre de participation et le taux dans la zone au-delà (il s'en tient à la limite supérieure), mais il semble que ce soit effectivement le cas. ..

image.png

À titre d'exemple, voici un histogramme du nombre et des taux de personnes qui ont participé au concours cinq fois jusqu'à présent. image.png

Visualisation médiane et centile

La visualisation par la valeur moyenne est fortement influencée par les valeurs aberrantes telles que ceux qui ont de l'expérience en programmation compétitive (la capacité est anormalement élevée depuis le début), j'ai donc décidé de visualiser par la valeur médiane. La valeur moyenne est un point bleu et les 25% supérieurs aux 25% inférieurs sont représentés par une bande jaune. La médiane semble avoir un score global légèrement inférieur à la moyenne.

image.png

3. Relation entre l'âge et le taux

Une question s'est posée pour faire progresser la visualisation des groupes d'âge et des distributions de taux. Vous avez probablement entendu parler de la théorie de la retraite du programmeur de 35 ans, mais y a-t-il une corrélation entre l'âge et le taux d'AtCoder? Par conséquent, j'ai décidé de le visualiser. Comme mentionné ci-dessus, en raison des spécifications du système de notation d'AtCoder, si le nombre de participation est de 10 ou moins, le taux peut être nettement inférieur à la capacité réelle, de sorte que le graphique ci-dessous montre que le nombre de participation est de 10. Limité aux personnes qui ont plus d'une fois, nous avons visualisé la valeur médiane de sorte que l'influence des valeurs aberrantes soit moins susceptible de se produire. En regardant les résultats, il semble qu'il n'y ait pratiquement aucune corrélation entre l'âge et la cote. Il existe peu de données sur les personnes dans la quarantaine et les résultats varient, c'est donc juste pour référence.

image.png

4. Code source utilisé

Le code source est indiqué ci-dessous.

code


from urllib import request
from bs4 import BeautifulSoup
#En modifiant l'url ici, vous pouvez limiter le nombre de participation, etc.
url = "https://atcoder.jp/ranking/?f.Country=&f.UserScreenName=&f.Affiliation=&f.BirthYearLowerBound=0&f.BirthYearUpperBound=9999&f.RatingLowerBound=0&f.RatingUpperBound=9999&f.HighestRatingLowerBound=0&f.HighestRatingUpperBound=9999&f.CompetitionsLowerBound=1&f.CompetitionsUpperBound=9999&f.WinsLowerBound=0&f.WinsUpperBound=9999&page="
html = request.urlopen(url+"0")
soup = BeautifulSoup(html, "html.parser") #Extraire les informations du fichier html
ul = soup.find_all("ul") #Peut être extrait en spécifiant le nom de l'élément et l'attribut

a = []
page = 0
i = 0
for tag in ul:
    i+=1
    try:
        string_ = tag.get("class") 
        if "pagination" in string_:
            a = tag.find_all("a")
            break
    except:
        pass
for tag in a:
    try:
        string_ = tag.get("href")
        if "ranking" in string_:
            page = max(page, int(tag.string))
    except:
        pass
organization = []
rank = []
name = []
for i in range(1,page+1): #page
    html = request.urlopen(url+str(i))
    soup = BeautifulSoup(html, "html.parser")
    td = soup.find_all("span")
    
    for tag in td:
        try:
            string_ = tag.get("class")[0]
        except:
            continue
        try:
            if string_ == "ranking-affiliation":
                organization.append(str(tag.string))
        except:
            pass        
    pp = soup.find_all("a")
    for tag in pp:
        try:
            string_ = tag.get("class")[0]
        except:
            continue
        try:
            if string_ == "username":
                name.append(str(tag.string))
        except:
            pass
information = []
for i in range(1,page+1): #page
    html = request.urlopen(url+str(i))
    soup = BeautifulSoup(html, "html.parser")    
    tbody = soup.find_all("tbody")
    for tr in tbody:
        for td in tr:
            temp = [] 
            for tag in td:
                try:
                    string_ = str(tag.string).strip()
                    if len(string_) > 0:
                        temp.append(string_)
                except:
                    pass
            if len(temp)>0:
                information.append(temp[2:])

information = [[name[i],organization[i]] + (information[i]) for i in range(len(information))]

#%%
import matplotlib.pyplot as plt
year_upper = 2020
rank_dic = {i:[] for i in range(year_upper+1)}
generation = [0 for i in range(year_upper)]

for i in range(len(information)):
    old = information[i][2]
    try:
        rank_dic[int(old)].append(int(information[i][3]))
        generation[int(old)] += 1
    except:
        pass
for i in range(len(rank_dic)-1, -1, -1): #Supprimé lorsqu'il n'y a pas 10 personnes
    if len(rank_dic[int(i)]) < 10:
        del rank_dic[int(i)]
#%%
import numpy as np
from statistics import mean, median,variance,stdev

ave_rank = np.array([[i ,mean(rank_dic[i])] for i in list(rank_dic.keys())], dtype = "float32")
stdev_rank = np.array([[i ,stdev(rank_dic[i])] for i in list(rank_dic.keys())], dtype = "float32")
max_rank = np.array([[i ,max(rank_dic[i])] for i in list(rank_dic.keys())], dtype = "float32")
median_rank = np.array([[i ,median(rank_dic[i])] for i in list(rank_dic.keys())], dtype = "float32")
percent25 = np.array([[i,np.percentile(rank_dic[i], [25])] for i in list(rank_dic.keys())], dtype = "float32")
percent75 = np.array([[i,np.percentile(rank_dic[i], [75])] for i in list(rank_dic.keys())], dtype = "float32")

#Classement moyen par âge
plt.fill_between(ave_rank[:,0], ave_rank[:,1]-stdev_rank[:,1], ave_rank[:,1]+stdev_rank[:,1],facecolor='y',alpha=0.5)
plt.scatter(ave_rank[:,0], ave_rank[:,1])
plt.xlim(1970,2010)
plt.ylim(-100,2000)
plt.tick_params(labelsize=15)
plt.grid()
plt.title("ave")
plt.show()
#Classement central par âge
plt.fill_between(percent25[:,0], percent25[:,1], percent75[:,1],facecolor='y',alpha=0.5)
plt.scatter(median_rank[:,0], median_rank[:,1])
plt.xlim(1970,2010)
plt.ylim(-100,2000)
plt.tick_params(labelsize=15)
plt.grid()
plt.title("med")
plt.show()
#Répartition des groupes d'âge participants
plt.plot([1996,1996],[-200,5000],zorder=1,linestyle="dashed",color="red")
plt.plot([2001,2001],[-200,5000],zorder=1,linestyle="dashed",color="red")
plt.fill_between([1996,2001], [-200,-200],[5000,5000],facecolor='red',alpha=0.5)
plt.scatter(range(len(generation)), generation,s=80,c="white",zorder=2,edgecolors="black",linewidths=2)
plt.xlim(1960,2010)
plt.ylim(-100,4500)
plt.tick_params(labelsize=15)
plt.grid()
plt.title("population")
plt.show()

#%%
compe_count = [[] for i in range(201)]
for i in range(len(information)):
    compe_count[int(information[i][5])].append(int(information[i][3]))

ave_rank_count = np.array([[i,mean(X)] if len(X)>5 else [i,None] for i,X in enumerate(compe_count)], dtype = "float32")[1:]
stdev_rank_count = np.array([[i,stdev(X)] if len(X)>5 else [i,None] for i,X in enumerate(compe_count)], dtype = "float32")[1:]
max_rank_count = np.array([[i,max(X)] if len(X)>5 else [i,None] for i,X in enumerate(compe_count)], dtype = "float32")[1:]
min_rank_count = np.array([[i,min(X)] if len(X)>5 else [i,None] for i,X in enumerate(compe_count)], dtype = "float32")[1:]
med_rank_count = np.array([[i,median(X)] if len(X)>5 else [i,None] for i,X in enumerate(compe_count)], dtype = "float32")[1:]
percent25_count = np.array([[i,np.percentile(X, [25])] if len(X)>5 else [i,None] for i,X in enumerate(compe_count)], dtype = "float32")[1:]
percent75_count = np.array([[i,np.percentile(X, [75])] if len(X)>5 else [i,None] for i,X in enumerate(compe_count)], dtype = "float32")[1:]
#Vérifiez l'histogramme
for i, X in enumerate(compe_count[1:20]):
    plt.hist(X, bins=40)
    plt.title(i)
    plt.show()
#Nombre de participation et score moyen
plt.fill_between(ave_rank_count[:,0],ave_rank_count[:,1]-stdev_rank_count[:,1],ave_rank_count[:,1]+stdev_rank_count[:,1],facecolor='y',alpha=0.5)
plt.scatter(ave_rank_count[:,0], ave_rank_count[:,1],zorder=2)
plt.tick_params(labelsize=15)
plt.grid()
plt.ylim(-100,2500)
#plt.title("ave_count")
plt.show()
#Compte de participation et score central
plt.fill_between(percent25_count[:,0], percent25_count[:,1], percent75_count[:,1],facecolor='y',alpha=0.5)
plt.scatter(med_rank_count[:,0], med_rank_count[:,1])
plt.tick_params(labelsize=15)
plt.ylim(-100,2500)
plt.grid()
#plt.title("med_count")
plt.show()

référence

J'ai beaucoup parlé de l'article suivant. J'ai essayé d'obtenir la distribution des taux d'AtCoder par le Web scraping de Python J'ai examiné la répartition des notes d'AtCoder

Recommended Posts

J'ai essayé de visualiser la tranche d'âge et la distribution des taux d'Atcoder
J'ai essayé de visualiser les informations spacha de VTuber
[Python] J'ai essayé de visualiser la relation de suivi de Twitter
J'ai essayé de visualiser la condition commune des téléspectateurs de la chaîne VTuber
J'ai essayé de corriger la forme trapézoïdale de l'image
J'ai essayé d'extraire et d'illustrer l'étape de l'histoire à l'aide de COTOHA
J'ai essayé de vérifier et d'analyser l'accélération de Python par Cython
J'ai essayé de visualiser le texte du roman "Weather Child" avec Word Cloud
J'ai essayé de vectoriser les paroles de Hinatazaka 46!
Quand j'ai essayé d'écrire sur la régression logistique, j'ai fini par trouver la moyenne et la variance de la distribution logistique.
J'ai essayé de notifier la mise à jour de "Hameln" en utilisant "Beautiful Soup" et "IFTTT"
[Python] J'ai essayé de juger l'image du membre du groupe d'idols en utilisant Keras
J'ai essayé de visualiser facilement les tweets de JAWS DAYS 2017 avec Python + ELK
J'ai essayé de résumer la forme de base de GPLVM
J'ai essayé d'effacer la partie négative de Meros
J'ai essayé de classer les voix des acteurs de la voix
J'ai essayé de résumer les opérations de chaîne de Python
Python pratique 100 coups J'ai essayé de visualiser l'arbre de décision du chapitre 5 en utilisant graphviz
J'ai essayé d'automatiser la mise à jour de l'article du blog Livedoor avec Python et sélénium.
J'ai essayé de visualiser les caractéristiques des nouvelles informations sur les personnes infectées par le virus corona avec wordcloud
[First data science ⑥] J'ai essayé de visualiser le prix du marché des restaurants à Tokyo
J'ai essayé de visualiser les données de course du jeu de course (Assetto Corsa) avec Plotly
J'ai essayé de comparer la vitesse de traitement avec dplyr de R et pandas de Python
J'ai essayé de trouver l'entropie de l'image avec python
[Courses de chevaux] J'ai essayé de quantifier la force du cheval de course
J'ai essayé d'obtenir les informations de localisation du bus Odakyu
J'ai essayé d'illustrer le temps et le temps du langage C
J'ai essayé d'afficher l'heure et la météo d'aujourd'hui w
[TF] J'ai essayé de visualiser le résultat de l'apprentissage en utilisant Tensorboard
[Apprentissage automatique] J'ai essayé de résumer la théorie d'Adaboost
Je veux connaître la nature de Python et pip
J'ai essayé d'énumérer les différences entre java et python
J'ai essayé de combattre le minimum local de la fonction Goldstein-Price
J'ai affiché le chat de YouTube Live et essayé de jouer
J'ai essayé de publier automatiquement sur ChatWork au moment du déploiement avec Fabric et ChatWork Api
J'ai essayé de visualiser la consommation électrique de ma maison avec Nature Remo E lite
J'ai essayé de vérifier la classification yin et yang des membres hololive par apprentissage automatique
[Traitement du langage naturel] J'ai essayé de visualiser les remarques de chaque membre de la communauté Slack
J'ai essayé de déplacer le ballon
J'ai essayé d'estimer la section.
[Linux] J'ai essayé de résumer les commandes de confirmation des ressources
J'ai essayé d'obtenir l'index de la liste en utilisant la fonction énumérer
J'ai essayé d'automatiser l'arrosage du pot avec Raspberry Pi
J'ai essayé de visualiser les signets volant vers Slack avec Doc2Vec et PCA
[Introduction à Python] J'ai comparé les conventions de nommage de C # et Python.
J'ai essayé de créer l'image de démarrage SD de LicheePi Nano
J'ai essayé de visualiser l'ensemble de données de préférence de boisson par décomposition tenseur.
J'ai résumé comment changer les paramètres de démarrage de GRUB et GRUB2
J'ai essayé d'agrandir la taille du volume logique avec LVM
J'ai essayé de visualiser Boeing de la performance du violon par estimation de pose
J'ai essayé de résumer la méthode de mise en œuvre fréquemment utilisée de pytest-mock
J'ai essayé d'améliorer l'efficacité du travail quotidien avec Python
Je suis devenu horreur quand j'ai essayé de détecter la quantité de fonctionnalités d'un visage animé en utilisant PCA et NMF.
[Python] J'ai essayé de visualiser le prix en argent de "ONE PIECE" plus de 100 millions de caractères avec matplotlib.
J'ai essayé de prédire les hauts et les bas du cours de clôture du cours de l'action de Guru Navi en utilisant TensorFlow (progression)
J'ai essayé d'adapter la fonction exponentielle et la fonction logistique au nombre de patients positifs au COVID-19 à Tokyo
J'ai essayé le serveur asynchrone de Django 3.0