Statistische Signifikanz der Winrate bei World-of-Tanks
-
Kleines Modell:
#include <iostream> #include <random> #include <vector> #include <stdint.h> #include <algorithm> #include <cassert> using namespace std; struct Player { double skill; double gamesPlayed; double gamesWon; int name; Player(double skill,int name) :skill(skill), gamesPlayed(0), gamesWon(0), name(name) { } }; int main() { size_t playersCount=10000; vector<Player> players; //spieler erzeugen std::mt19937 generator; std::normal_distribution<double> distribution(100,10); for(size_t i=0; i!=playersCount; ++i) players.emplace_back(distribution(generator),i); double gamesPlayed=0; for(;;) { for(int i=0; i<1000; ++i) { //die ersten 30 ins Feld mischen for(size_t i=30; i>0;) { --i; swap(players[i],players[i+1+generator()%(playersCount-i-1)]); } //teamA sind die leute 0-14 und teamB sind die 15-29 //skills addieren double sumA=0; for(size_t i=0; i<15; ++i) sumA+=players[i].skill; double sumB=0; for(size_t i=15; i<30; ++i) sumB+=players[i].skill; //gewinne merken if(sumA>sumB) for(size_t i=0; i<15; ++i) ++players[i].gamesWon; else for(size_t i=15; i<30; ++i) ++players[i].gamesWon; for(size_t i=0; i<30; ++i) ++players[i].gamesPlayed; ++gamesPlayed; } double hits=0; assert(playersCount%2==0); for(size_t a=0;a!=playersCount;a+=2) { size_t b=a+1; bool wonBySkill=players[a].skill>players[b].skill; bool wonByRank=players[a].gamesWon/players[a].gamesPlayed>players[b].gamesWon/players[b].gamesPlayed; if(wonBySkill==wonByRank) ++hits; } cout<<"gamesPerPlayer="<<gamesPlayed/playersCount; double prob=hits*200.0/playersCount; cout<<" prob="<<prob<<'%'<<endl; if(prob>=95) break; } }
Man beachte, daß hier die Annahme getroffen wird, daß man einfach die Stärken der Players addieren kann und damit die Stärke der Mannschaft hat.
double sumA=0; for(size_t i=0; i<15; ++i) sumA+=players[i].skill; double sumB=0; for(size_t i=15; i<30; ++i) sumB+=players[i].skill;
Es kommt raus, daß bereits 50 Spiele reichen.
Aber das Modell ist VÖLLIG aus der Luft gegriffen.
Sagen wir mal, ein wenig realistischer, die besseren 50% nehmen überhaupt nur wirksam am Spiel teil. Die anderen sind schlicht Kanonenfutter.
double sumA=0; for(size_t i=0; i<15; ++i) if(players[i].skill>100) sumA+=players[i].skill; double sumB=0; for(size_t i=15; i<30; ++i) if(players[i].skill>100) sumB+=players[i].skill;
Ähm. Da reichen 10000 Spiele bei weitem nicht, um in die Nähe von 95% zu kommen.
Kurzum, die Abhängigkeit zwischen Spielerskill und Ranking muss an echten Daten erstmal herausgefunden werden.
Und diesen Zusammenhang suchst Du. Zu definieren, der Skill SEI nur das Ranking, ist irreführend.
a) Der Skill ist immer genau das Ranking. Dann haste auch immer 100% und fertig.
b) Der Skill ist das, wohin das Ranking des Spielers hinkonvergiert. Dann isses aber eben genau der Spielerskill, über den nicht weiß, welchen durchschnittlichen Einfluß er auf ein einzelnes Spiel hat.Das muss anhand einer Liste vieler gespielter Spiele herausgefunden werden. Haste die Liste nicht, glaube ich nicht, daß jemand den richtigen Zusammenhang, also das richtige Modell, aus der Luft erraten kann.
edit: schon 100000 Spiele pro Player und er gammelt noch bei 87% herum.
-
@volkard:
Wenn du unbedingt Experimentalmathematik machen willst, probiers mal mit folgendem Programm:#include <iostream> #include <random> #include <vector> #include <stdint.h> #include <algorithm> #include <cassert> using namespace std; struct Player { double skill; double gamesWon; int name; Player(double skill,int name) :skill(skill), gamesWon(0), name(name) { } }; int main() { const size_t playersCount = 150000; const size_t playersPerTeam = 15; assert(playersCount % 2*playersPerTeam == 0); vector<Player> players; //spieler erzeugen std::mt19937 generator; std::normal_distribution<double> distribution(100,10); for(size_t i=0; i!=playersCount; ++i) players.push_back(Player(distribution(generator),i)); double gamesPlayed=0; for(;;) { for(size_t i=0; i<100; ++i) { // alle mischen random_shuffle(players.begin(), players.end(),[&](int i){return generator() % i;}); // alle spielen lassen for (size_t n=0; n<playersCount; n+=2*playersPerTeam) { double sumA=0; for(size_t i=0; i<playersPerTeam; ++i) sumA += players[n+i].skill; double sumB=1; for(size_t i=playersPerTeam; i<2*playersPerTeam; ++i) sumB += players[n+i].skill; //gewinne merken if(sumA>sumB) for(size_t i=0; i<playersPerTeam; ++i) ++players[n+i].gamesWon; else for(size_t i=playersPerTeam; i<2*playersPerTeam; ++i) ++players[n+i].gamesWon; } ++gamesPlayed; } double hits=0; assert(playersCount%2==0); sort(players.begin(), players.end(), [](const Player& a, const Player& b) { return a.gamesWon < b.gamesWon; } ); size_t n=0; size_t b=0; for(size_t a=0; a<playersCount; a+=10) { // wir vergleichen nicht zufaellige leute, sondern welche deren winrate sich um ein wenig mehr als 1% unterscheidet while (b<playersCount && players[b].gamesWon/gamesPlayed < players[a].gamesWon/gamesPlayed + 0.01) b++; if (b>=playersCount) break; bool wonBySkill=players[a].skill>players[b].skill; bool wonByRank=players[a].gamesWon>players[b].gamesWon; if(wonBySkill==wonByRank) ++hits; ++n; } cout<<"gamesPerPlayer="<<gamesPlayed; double prob = hits*100.0/n; cout<<" prob="<<prob<<'%'<<endl; if(prob>=95) break; } system("pause"); }
Ergebnis: Um die 12000.
Dann kannst du auch mal mit der Funktion rumspielen (z.B. * statt +) und solange du keine Kanonenfutter-Funktion nimmst, sondern eine bei der die Gewinnwahrscheinlichkeit für jeden Spieler streng monoton mit dem Skill steigt, wird etwas Ähnliches rauskommen. Jedenfalls muss die Zahl im Mittel unter 20000 bleiben.
Mathematik lügt nicht.
-
C14_off schrieb:
Wir wollen aber nur herausfinden wer besser ist
Wollten wir nicht herausfinden wie viele Spiele man braucht um (relativ) sicher sagen zu können dass jemand mit einem Prozent besserer Win-Rate auch besser ist? (Ja, das ist ein Unterschied..)
C14_off schrieb:
Das ist aber genau dann der Fall wenn sein p höher ist.
Hä.. ist p nicht genau die Win-Rate?
Btw hört sich die Fragestellung "Wie viele Spiele braucht man um mit x% Sicherheit sagen zu können dass die Win-Rate eines Spielers der Win-Rate seines Skills entspricht? (Mit einem y% Fehlerintervall)" für mich sinnvoller an.
-
cooky451 schrieb:
C14_off schrieb:
Das ist aber genau dann der Fall wenn sein p höher ist.
Hä.. ist p nicht genau die Win-Rate?
Btw hört sich die Fragestellung "Wie viele Spiele braucht man um mit x% Sicherheit sagen zu können dass die Win-Rate eines Spielers der Win-Rate seines Skills entspricht? (Mit einem y% Fehlerintervall)" für mich sinnvoller an.
Das Missverständnis ist hier, das "Winrate" im Eingangsposting doppelt belegt ist.
Es gibt die Gewinnwahrscheinlichkeit, die es zu schätzen gilt ("wahre Winrate")
und die relative Häufigkeit wieviele Gefechte denn nun tatsächlich gewonnen wurden ("Winrate").
Die "Winrate" konvergiert gegen die "wahre Winrate"/Gewinnwahrscheinlichkeit im Limit unendlich vieler Gefechte
bzw. wir gehen davon aus, dass die eigentlichen Siege Ziehungen aus dieser Gewinnwahrscheinlichkeit sind (so wie Münzwürfe mit einer je nach Gewinnwahrscheinlichkeit gezinkten Münze).
Damit kann man die wahre Gewinnwahrscheinlichkeit schätzen.
Wenn diese wahre Gewinnwahrscheinlichkeit jetzt mit dem Skill wächst kann man damit auch etwas über den Skill aussagen.cooky451 schrieb:
C14_off schrieb:
Wir wollen aber nur herausfinden wer besser ist
Wollten wir nicht herausfinden wie viele Spiele man braucht um (relativ) sicher sagen zu können dass jemand mit einem Prozent besserer Win-Rate auch besser ist? (Ja, das ist ein Unterschied..)
Ja, genau das wollen wir. Im Zusammenhang wollte ich mit dem "nur" sagen, dass es nicht wichtig ist, um wieviel sich der Skill unterscheidet, sondern nur welcher Skill höher ist.
Das wollte ich deshalb betonen, weil ich glaube dass es die unbewusste Quelle deines Einwands war, die Anzahl der Spieler pro Team müsste eingehen:
Wenn die Frage lauten würde
"Wieviele Spiele braucht man, um (relativ) sicher sagen zu können, dass jemand mit einem Prozent besserer Win-Rate einen Skill-Punkt mehr hat als sein Gegner?"
müsste man den Zusammenhang zwischen Skill und Gewinnwahrscheinlichkeit kennen.
Der wäre in einem 1vs1 Spiel steiler als in einem 15vs15 Spiel (somit bräuchte man im 1vs1 weniger Gefechte) und deswegen dachtest du vermutlich intuitiv, dass die Anzahl der Spieler pro Team in die Endformel eingehen muss.
Da die Frage aber lautet
"Wie viele Spiele braucht man, um (relativ) sicher sagen zu können, dass jemand mit einem Prozent besserer Win-Rate auch den höheren Skill hat?"
reicht es zu wissen, dass der Skill streng monoton mit der Gewinnwahrscheinlichkeit wächst und der konkrete Zusammenhang zwischen Skill und Gewinnwahrscheinlichkeit ist egal.
Da jeder sinnvolle Skillbegriff diesen Einfluss auf die Gewinnwahrscheinlichkeit haben sollte, können wir auch noch einen Schritt weiter gehen und den Skill für diese Aufgabenstellung
(es kommt nur auf die Reihenfolge an, absolute Zahlenwerte sind egal) gleich als die Gewinnwahrscheinlichkeit (nicht Winrate!) definieren.