]> git.sesse.net Git - wloh/blobdiff - www/rating.pl
Train one model (with its own aux parms) per locale.
[wloh] / www / rating.pl
index f6aa8e17a7af8ebb5ced200cd772c59e5b86489f..5eb822807d1859b7b013c6f17960f83de2c2aacc 100755 (executable)
@@ -11,6 +11,7 @@ use HTML::Entities;
 use utf8;
 use locale;
 require '../config.pm';
+require '../common.pm';
 
 my $dbh = DBI->connect($config::local_connstr, $config::local_username, $config::local_password)
        or die "connect: " . $DBI::errstr;
@@ -19,23 +20,24 @@ $dbh->{RaiseError} = 1;
 
 binmode STDOUT, ':utf8';
 
-# Find auxillary parameters.
-my %params = ();
-my $q = $dbh->prepare('SELECT * FROM ratings WHERE id < 0');
-$q->execute;
-while (my $ref = $q->fetchrow_hashref) {
-       $params{$ref->{'id'}} = $ref->{'rating'};
-}
-my $match_stddev = $params{-2} * sqrt(2.0);
+my $cgi = CGI->new;
+my $locale = wloh_common::get_locale($cgi);
+
+my $aux_parms = wloh_common::get_auxillary_parameters($dbh, $locale);
+my $match_stddev = $aux_parms->{'score_stddev'} * sqrt(2.0);
 
 print CGI->header(-type=>'text/html; charset=utf-8', -expires=>'+5m');
 POSIX::setlocale(&POSIX::LC_ALL, 'nb_NO.UTF-8');
 
-printf <<"EOF", $params{-3}, $match_stddev;
-<html>
+printf <<"EOF", $aux_parms->{'rating_prior_stddev'}, $match_stddev;
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE
+  html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="no">
   <head>
     <title>WLoH-rating</title>
-    <link rel="stylesheet" href="/style" type="text/css" />
+    <link rel="stylesheet" href="style" type="text/css" />
   </head>
   <body>
     <h1>WLoH-rating</h1>
@@ -47,11 +49,7 @@ printf <<"EOF", $params{-3}, $match_stddev;
       for tilgang!), og oppdateres
       hver hele time. Den er fullstendig uoffisiell, og har ingen innflytelse
       på WLoH, men brukes for å estimere vinnersannsynligheter i
-      <a href="/">sannsynlighetsberegningen</a>.</p>
-
-    <p>Vær obs på at det
-      er betydelig usikkerhetsmargin, spesielt for spillere som ikke
-      har spilt spesielt mange kamper.</p>
+      <a href="index">sannsynlighetsberegningen</a>.</p>
 
     <p>Modellen kan endre seg når som helst når jeg føler for det :-)
       Ikke ta ratingen alt for alvorlig, selv om den er basert på
@@ -60,16 +58,17 @@ printf <<"EOF", $params{-3}, $match_stddev;
 
     <h2>Modellparametre</h2>
 
-    <p>For de som vet litt om slikt. Mer utførlig forklaring for begynnere kommer seinere.</p>
+    <p>For de som vet litt om slikt. Det finnes også en lengre, mer detaljert
+      <a href="ratings-explained">forklaring</a> beregnet på ikke-matematikere.</p>
 
     <ul>
-      <li>MLE-basert modell med én skalar (styrke) per spiller og to globale skalarer (begge standardavvik, se under), løst med syklisk MM (minorization-maximization). Antall iterasjoner før konvergens: $params{-1}.</li>
-      <li>Rimelighetfunksjon, prior: Normalfordeling med µ=1500, &sigma;=%.1f (est.)</li>
+      <li>MLE-basert modell med én skalar (styrke) per spiller og to globale skalarer (begge standardavvik, se under), løst med syklisk MM (minorization-maximization). Antall iterasjoner før konvergens: $aux_parms->{num_iterations}.</li>
+      <li>Rimelighetfunksjon, prior: Normalfordeling med µ=500, &sigma;=%.1f (est.)</li>
       <li>Rimelighetfunksjon, per kamp: Normalfordeling med µ=(score1 - score2), &sigma;=%.1f (est.)</li>
       <li>Vekting: Inneværende sesong samt de tre siste vektes fullt ut
        (likt med prior). Deretter eksponentielt synkende vekting, med
         halveringstid på tre sesonger. Spill som er registrert med
-        150-0, 0-150 eller 150-150 ignoreres.</li>
+        0-0, 150-0, 0-150 eller 150-150 ignoreres.</li>
     </ul>
 
     <h2>Divisjonsoversikt</h2>
@@ -82,8 +81,23 @@ printf <<"EOF", $params{-3}, $match_stddev;
       </tr>
 EOF
 
-$q = $dbh->prepare('SELECT divisjon,AVG(rating) AS avg_rating,STDDEV(rating) AS stddev_rating FROM ratings NATURAL JOIN siste_divisjon GROUP BY divisjon ORDER BY divisjon');
-$q->execute;
+my $season = wloh_common::get_max_season($dbh, $locale);
+
+# Pick up all the subdivisions' ratings.
+my %subdivision_ratings = ();
+my $q = $dbh->prepare('SELECT divisjon, avdeling, serie_id, AVG(rating) AS avg_rating FROM ratings NATURAL JOIN siste_divisjon WHERE sesong=? GROUP BY divisjon, avdeling, serie_id ORDER BY divisjon, avdeling');
+$q->execute($season);
+
+while (my $ref = $q->fetchrow_hashref) {
+       my $division = $ref->{'divisjon'};
+       my $rating = $ref->{'avg_rating'};
+       my $id = $ref->{'serie_id'};
+
+       push @{$subdivision_ratings{$division}}, [ $id, $rating ];
+}
+
+$q = $dbh->prepare('SELECT divisjon,AVG(rating) AS avg_rating,STDDEV(rating) AS stddev_rating FROM ratings NATURAL JOIN siste_divisjon WHERE sesong=? GROUP BY divisjon ORDER BY divisjon');
+$q->execute($season);
 
 my $i = 0;
 while (my $ref = $q->fetchrow_hashref) {
@@ -95,6 +109,11 @@ while (my $ref = $q->fetchrow_hashref) {
        printf "        <th>%d.</th>\n", $ref->{'divisjon'};
        printf "        <td class=\"num\">%.1f</td>\n", $ref->{'avg_rating'};
        printf "        <td class=\"num\">%.1f</td>\n", $ref->{'stddev_rating'};
+
+       for my $arr (@{$subdivision_ratings{$ref->{'divisjon'}}}) {
+               my ($id, $rating) = @$arr;
+               printf "        <td class=\"num\"><a href=\"http://wordfeud.aasmul.net/serie-%d\">%.1f</a></td>\n", $id, $rating;
+       }
        print "      </tr>\n";
 }
 
@@ -107,7 +126,8 @@ print <<"EOF";
     <tr>
       <th></th>
       <th>Nick</th>
-      <th>Ranking</th>
+      <th>Rating</th>
+      <th>Std.avvik</th>
       <th>Sist sett</th>
     </tr>
 EOF
@@ -117,8 +137,10 @@ SELECT *
 FROM ratings
   NATURAL JOIN kanonisk_navn
   NATURAL JOIN siste_divisjon
+  NATURAL JOIN spiller_kultur
+WHERE kultur=?
 ORDER BY rating DESC');
-$q->execute;
+$q->execute($locale);
 
 $i = 0;
 while (my $ref = $q->fetchrow_hashref) {
@@ -130,16 +152,17 @@ while (my $ref = $q->fetchrow_hashref) {
        printf "      <th>%d.</th>\n", $i;
        printf "      <td><a href=\"http://wordfeud.aasmul.net/bruker-%d\">%s</a></td>\n", $ref->{'id'}, HTML::Entities::encode_entities(Encode::decode_utf8($ref->{'navn'}));
        printf "      <td class=\"num\">%.1f</td>\n", $ref->{'rating'};
+       printf "      <td class=\"num\">%.1f</td>\n", $ref->{'rating_stddev'};
        printf "      <td><a href=\"http://wordfeud.aasmul.net/serie-%d\">%s</a></td>\n", $ref->{'serie_id'}, $ref->{'serie_navn'};
        print "    </tr>\n";
 }
+print "    </table>\n";
+
+wloh_common::output_last_sync($dbh);
 
 print <<"EOF";
-    </table>
   </body>
 </html>
 EOF
 
-$match_stddev = $params{-2} * sqrt(2.0);
-
 $dbh->rollback;