Ich habe versucht, die Verteilung der Altersgruppen und Raten der Teilnehmer an AtCoder (Wettbewerbsprogrammierung) durch Scraping und statistische Verarbeitung mit Python zu visualisieren.
Zunächst werden die an Atcoder teilnehmenden Altersgruppen erfasst und tabellarisch aufgeführt, sodass sie unten aufgeführt sind. Außerdem werden Personen, die ihr Alter nicht in ihr Profil eingeben, nicht gezählt. Wie Sie sich vorstellen können, gibt es viele junge Leute, insbesondere Studenten.
Natürlich scheint es eine Korrelation zwischen der Anzahl der Wettbewerbsbeiträge und der Rate zu geben. Übrigens kann gemäß den Spezifikationen des AtCoder-Bewertungssystems die Rate erheblich niedriger sein als die tatsächliche Fähigkeit, wenn die Anzahl der Teilnehmer 10 oder weniger beträgt. Bitte überprüfen Sie die folgende Seite für Details. Informationen zur Bewertung des AtCoder-Wettbewerbs
Ich habe versucht, die Rate der aktiven Benutzer anhand des Durchschnittswerts und der Standardabweichung für jede Anzahl von Teilnehmern am Wettbewerb zu visualisieren. Der Durchschnittswert ist der blaue Punkt, und der Durchschnittswert ± Standardabweichung wird durch das gelbe Band angezeigt. Selbst nach Abzug der oben genannten Spezifikationen des Bewertungssystems scheint eine positive Korrelation zwischen der Anzahl der Beteiligungen und der Rate zu bestehen. Wenn die Anzahl der Teilnehmer etwa 30-mal beträgt, besteht meiner Vorstellung nach keine große Korrelation zwischen der Anzahl der Teilnehmer und der Rate in dem darüber hinausgehenden Bereich (sie bleibt bei der Obergrenze), aber es scheint, dass dies tatsächlich der Fall ist. ..
Als Beispiel finden Sie hier ein Histogramm der Anzahl und Rate der Personen, die bisher fünf Mal am Wettbewerb teilgenommen haben.
Die Visualisierung anhand des Durchschnittswerts wird stark von Ausreißern beeinflusst, z. B. solchen, die Erfahrung mit wettbewerbsfähiger Programmierung haben (die Fähigkeit ist von Anfang an ungewöhnlich hoch). Daher habe ich mich für die Visualisierung anhand des Medianwerts entschieden. Der Durchschnittswert ist ein blauer Punkt, und die oberen 25% bis unteren 25% werden durch ein gelbes Band dargestellt. Der Median scheint eine etwas niedrigere Gesamtpunktzahl als der Durchschnitt zu haben.
Eine Frage stellte sich bei der Weiterentwicklung der Visualisierung von Altersgruppen und Ratenverteilungen. Sie haben wahrscheinlich von der Ruhestandstheorie des 35-jährigen Programmierers gehört, aber gibt es einen Zusammenhang zwischen dem Alter und der AtCoder-Rate? Deshalb habe ich mich entschlossen, es tatsächlich zu visualisieren. Wie oben erwähnt, kann aufgrund der Spezifikationen des AtCoder-Bewertungssystems bei einer Teilnehmerzahl von 10 oder weniger die Rate erheblich niedriger sein als die tatsächliche Fähigkeit. Die folgende Grafik zeigt also, dass die Teilnehmerzahl 10 beträgt. Der Medianwert ist auf Personen mit mehr als einer Zeit beschränkt und wird so dargestellt, dass der Einfluss der Ausreißer weniger wahrscheinlich ist. Betrachtet man die Ergebnisse, so scheint es fast keine Korrelation zwischen Alter und Bewertung zu geben. Es gibt nur wenige Daten für Personen in den Vierzigern, und die Ergebnisse variieren, sodass dies nur als Referenz dient.
Der Quellcode wird unten angezeigt.
code
from urllib import request
from bs4 import BeautifulSoup
#Durch Ändern der URL hier können Sie die Anzahl der Teilnehmer usw. begrenzen.
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") #Extrahieren Sie Informationen aus der HTML-Datei
ul = soup.find_all("ul") #Kann durch Angabe des Elementnamens und des Attributs extrahiert werden
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): #Wird gelöscht, wenn keine 10 Personen vorhanden sind
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")
#Durchschnittlicher Rang nach Alter
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()
#Zentraler Rang nach Alter
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()
#Verteilung der teilnehmenden Altersgruppen
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:]
#Überprüfen Sie das Histogramm
for i, X in enumerate(compe_count[1:20]):
plt.hist(X, bins=40)
plt.title(i)
plt.show()
#Teilnahmezahl und durchschnittliche Punktzahl
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()
#Teilnahmezahl und zentrale Punktzahl
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()
Ich habe sehr viel auf den folgenden Artikel verwiesen. Ich habe versucht, die Ratenverteilung von AtCoder durch Web-Scraping von Python zu ermitteln Ich habe die Verteilung der AtCoder-Bewertungen untersucht
Recommended Posts