X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=train.pl;h=9b1e0dcb923ef580014df114878e4a666a7c8199;hb=854c8eb6e0a3f9836043faaf2f43c05c190619fb;hp=d128d58cd1f25bb876eb0db428d8c303048e1802;hpb=4755b6aa6bc213c2ef700d9b17fdbc42c21828c4;p=wloh diff --git a/train.pl b/train.pl index d128d58..9b1e0dc 100755 --- a/train.pl +++ b/train.pl @@ -6,76 +6,114 @@ no warnings qw(once); use POSIX; require './config.pm'; -my $dbh = DBI->connect($config::local_connstr, $config::local_username, $config::local_password) - or die "connect: " . $DBI::errstr; -$dbh->{AutoCommit} = 0; -$dbh->{RaiseError} = 1; - -$dbh->do('SET client_min_messages TO WARNING'); - # Find last completely done season -my $ref = $dbh->selectrow_hashref('SELECT sesong FROM fotballserier GROUP BY sesong HAVING COUNT(*)=COUNT(avgjort=1 OR NULL) ORDER BY sesong DESC LIMIT 1'); -my $last_season = $ref->{'sesong'}; +sub find_last_season { + my ($dbh, $locale) = @_; + my $ref = $dbh->selectrow_hashref('SELECT sesong FROM fotballserier se JOIN fotballspraak sp ON se.spraak=sp.id GROUP BY kultur,sesong HAVING COUNT(*)=COUNT(avgjort=1 OR NULL) AND kultur=? ORDER BY kultur,sesong DESC LIMIT 1', undef, $locale); + return $ref->{'sesong'}; +} -# Fetch games -my $q = $dbh->prepare(' +sub fetch_games { + my ($dbh, $locale, $last_season, $games, $ids) = @_; + my $q = $dbh->prepare(' SELECT deltager1.id as p1, deltager2.id as p2, maalfor, maalmot, least(pow(2.0, (sesong - ? + 3) / 3.0), 1.0) AS vekt FROM Fotballresultater resultater JOIN Fotballdeltagere deltager1 ON resultater.Lagrecno=deltager1.Nr AND resultater.Serie=deltager1.Serie JOIN Fotballdeltagere deltager2 ON resultater.Motstander=deltager2.Nr AND resultater.Serie=deltager2.Serie - JOIN Fotballserier serier on resultater.Serie=serier.Nr -WHERE deltager1.Nr > deltager2.nr -'); -$q->execute($last_season); - -my @games = (); -my %ids = (); - -while (my $ref = $q->fetchrow_hashref) { - next if ($ref->{'maalfor'} == 150 && $ref->{'maalmot'} == 0); - next if ($ref->{'maalfor'} == 0 && $ref->{'maalmot'} == 150); - next if ($ref->{'maalfor'} == 150 && $ref->{'maalmot'} == 150); - next if ($ref->{'maalfor'} == 0 && $ref->{'maalmot'} == 0); - push @games, { %$ref }; - $ids{$ref->{'p1'}} = 1; - $ids{$ref->{'p2'}} = 1; + JOIN Fotballserier serier ON resultater.Serie=serier.Nr + JOIN Fotballspraak spraak ON serier.Spraak=spraak.Id +WHERE deltager1.Nr > deltager2.nr AND kultur=? + '); + $q->execute($last_season, $locale); + + while (my $ref = $q->fetchrow_hashref) { + next if ($ref->{'maalfor'} == 150 && $ref->{'maalmot'} == 0); + next if ($ref->{'maalfor'} == 0 && $ref->{'maalmot'} == 150); + next if ($ref->{'maalfor'} == 150 && $ref->{'maalmot'} == 150); + next if ($ref->{'maalfor'} == 0 && $ref->{'maalmot'} == 0); + push @$games, { %$ref }; + $ids->{$ref->{'p1'}} = 1; + $ids->{$ref->{'p2'}} = 1; + } } -# Output to file -my $tmpnam = POSIX::tmpnam(); -open DATA, ">", $tmpnam - or die "$tmpnam: $!"; +sub output_to_file { + my ($games, $ids) = @_; + + my $tmpnam = POSIX::tmpnam(); + open DATA, ">", $tmpnam + or die "$tmpnam: $!"; -printf DATA "%d\n", scalar keys %ids; -for my $id (keys %ids) { - printf DATA "%d\n", $id; + printf DATA "%d\n", scalar keys %$ids; + for my $id (keys %$ids) { + printf DATA "%d\n", $id; + } + for my $ref (@$games) { + printf DATA "%d %d %d %d %f\n", $ref->{'p1'}, $ref->{'p2'}, $ref->{'maalfor'}, $ref->{'maalmot'}, $ref->{'vekt'}; + } + close DATA; + + return $tmpnam; } -for my $ref (@games) { - printf DATA "%d %d %d %d %f\n", $ref->{'p1'}, $ref->{'p2'}, $ref->{'maalfor'}, $ref->{'maalmot'}, $ref->{'vekt'}; + +sub train_model { + my ($filename, $locale, $ratings, $covariances, $aux_params) = @_; + + open RATINGS, "$config::base_dir/bayeswf < $filename |" + or die "bayeswf: $!"; + while () { + chomp; + my @x = split; + if ($x[0] eq 'covariance') { + push @$covariances, (join("\t", @x[1..3])); + } elsif ($x[0] eq 'aux_param') { + push @$aux_params, ($locale . "\t" . $x[1] . "\t" . $x[2]); + } else { + push @$ratings, ($x[2] . "\t" . $x[0] . "\t" . $x[1]); + } + } + + close RATINGS; } -close DATA; -my @ratings = (); -my @covariances = (); +sub find_all_locales { + my $dbh = shift; + my $q = $dbh->prepare('SELECT kultur FROM fotballspraak'); + $q->execute; -open RATINGS, "$config::base_dir/bayeswf < $tmpnam |" - or die "bayeswf: $!"; -while () { - chomp; - my @x = split; - if ($x[0] eq 'covariance') { - push @covariances, (join("\t", @x[1..3])); - } else { - push @ratings, ($x[2] . "\t" . $x[0] . "\t" . $x[1]); + my @locales = (); + while (my $ref = $q->fetchrow_hashref) { + push @locales, $ref->{'kultur'}; } + + return @locales; } -$dbh->do('TRUNCATE ratings'); -$dbh->do('COPY ratings ( id, rating, rating_stddev ) FROM STDIN'); -$dbh->pg_putcopydata(join("\n", @ratings)); -$dbh->pg_putcopyend(); +my $dbh = DBI->connect($config::local_connstr, $config::local_username, $config::local_password) + or die "connect: " . $DBI::errstr; +$dbh->{AutoCommit} = 0; +$dbh->{RaiseError} = 1; + +$dbh->do('SET client_min_messages TO WARNING'); + +my @locales = find_all_locales($dbh); + +my @ratings = (); +my @covariances = (); +my @aux_params = (); + +for my $locale (@locales) { + my $last_season = find_last_season($dbh, $locale); + my @games = (); + my %ids = (); + fetch_games($dbh, $locale, $last_season, \@games, \%ids); + my $tmpnam = output_to_file(\@games, \%ids); + + train_model($tmpnam, $locale, \@ratings, \@covariances, \@aux_params); + unlink($tmpnam); +} $dbh->do('CREATE TABLE new_covariance ( player1 smallint NOT NULL, player2 smallint NOT NULL, cov float NOT NULL )'); $dbh->do('COPY new_covariance ( player1, player2, cov ) FROM STDIN'); @@ -85,5 +123,14 @@ $dbh->do('ALTER TABLE new_covariance ADD PRIMARY KEY ( player1, player2 );'); $dbh->do('DROP TABLE IF EXISTS covariance'); $dbh->do('ALTER TABLE new_covariance RENAME TO covariance'); +$dbh->do('TRUNCATE aux_params'); +$dbh->do('COPY aux_params ( kultur, id, value ) FROM STDIN'); +$dbh->pg_putcopydata(join("\n", @aux_params)); +$dbh->pg_putcopyend(); + +$dbh->do('TRUNCATE ratings'); +$dbh->do('COPY ratings ( id, rating, rating_stddev ) FROM STDIN'); +$dbh->pg_putcopydata(join("\n", @ratings)); +$dbh->pg_putcopyend(); + $dbh->commit; -unlink($tmpnam);