9
votes

Y a-t-il un package de statistiques Perl qui ne me fait pas charger l'ensemble du jeu de données à la fois?

Je recherche un package de statistiques pour Perl (cpan va bien) qui me permet d'ajouter des données progressivement au lieu de devoir passer une gamme complète de données.

Juste la moyenne, la médiane, STDDEV, max et min est nécessaire, rien de trop compliqué.

La raison en est que mon jeu de données est entièrement trop volumineux pour s'adapter à la mémoire. La source de données est dans une base de données MySQL, alors je ne fais que interroger un sous-ensemble des données et informer les statistiques pour eux, puis combinant tous les sous-ensembles gérables plus tard.

Si vous avez d'autres idées sur la façon de surmonter cette question, je serais beaucoup obligé!


0 commentaires

7 Réponses :




4
votes

2 commentaires

Bien que cela puisse être correct pour son projet, le calcul de la statistique est souvent fortement recommandé d'être déchargé au code de l'application, car il est beaucoup plus facile d'accabler les ressources du serveur d'applications que DB Server.


@DVK: Je ne suis pas sûr d'acheter cette objection. Les ressources nécessaires à l'exportation des Data nécessaires au serveur d'applications pour effectuer ses propres statistiques sont beaucoup plus grandes que de permettre au serveur DB de les calculer eux-mêmes?



4
votes

PDL peut fournir une solution possible:

Regardez cette réponse précédente qui montre comment Pour obtenir signifie, std dev, etc .

Voici une partie pertinente du code répété ici: xxx


0 commentaires

0
votes

Ceci est largement non testé, alors utilisez-vous avec soin. Comme j'ai une mauvaise mémoire, j'ai vérifié l'algorithme contre Wikipedia . Je ne suis pas au courant d'un algorithme de calculer la médiane d'un flux de chiffres, mais cela ne signifie pas qu'il n'y en a pas.

#!/usr/bin/perl
use strict;
use warnings;

use MooseX::Declare;

class SimpleStats {
  has 'min'       => (is => 'rw', isa => 'Num', default => 9**9**9);
  has 'max'       => (is => 'rw', isa => 'Num', default => -9**9**9);
  has 'A'         => (is => 'rw', isa => 'Num', default => 0);
  has 'Q'         => (is => 'rw', isa => 'Num', default => 0);
  has 'n'         => (is => 'rw', isa => 'Int', default => 0);
  has 'n_nonzero' => (is => 'rw', isa => 'Int', default => 0);
  has 'sum_w'     => (is => 'rw', isa => 'Int', default => 0);

  method add (Num $x, Num $w = 1) {
    $self->min($x) if $x < $self->min;
    $self->max($x) if $x > $self->max;
    my $n = $self->n;
    if ($n == 0) {
      $self->A($x);
      $self->sum_w($w);
    }
    else {
      my $A = $self->A;
      my $Q = $self->Q;
      my $sum_w_before = $self->sum_w;
      $self->sum_w($sum_w_before+$w);
      $self->A($A + ($x-$A) * $w/$self->sum_w);
      $self->Q($Q + $w*($x-$A)*($x-$self->A));
    }
    $self->n($n+1);
    $self->n_nonzero($self->n_nonzero+1) if $w != 0;
    return();
  }

  method mean () { $self->A }

  method sample_variance () {
    $self->Q * $self->n_nonzero() /
    ( ($self->n_nonzero-1) * $self->sum_w )
  }

  method std_variance () { $self->Q / $self->sum_w }
  method std_dev      () { sqrt($self->std_variance) }

  # slightly evil. Just don't reuse objects
  method reset () { %$self = %{__PACKAGE__->new()} }
}

package main;

my $stats = SimpleStats->new;

while (<STDIN>) {
  s/^\s+//;
  s/\s+$//;
  my ($x, $w) = split /\s+/, $_;
  if (defined $w) {
    $stats->add($x, $w);
  } else {
    $stats->add($x);
  }
}

print "Mean:        ", $stats->mean, "\n";
print "Sample var:  ", $stats->sample_variance, "\n";
print "Std var:     ", $stats->std_variance, "\n";
print "Std dev:     ", $stats->std_dev, "\n";
print "Entries:     ", $stats->n, "\n";
print "Min:         ", $stats->min, "\n";
print "Max:         ", $stats->max, "\n";


0 commentaires

1
votes

@DVK: les algorithmes d'un laissez-passer pour calculer la moyenne et la déviation standard ici http: / /en.wikipedia.org/wiki/algorithms_for_calculant_variance#on-line_algorithm ne sont pas des approximations et sont plus solides de manière numérique que l'exemple que vous donnez. Voir Références sur cette page.


0 commentaires

0
votes

Je comprends que c'est 4 ans sur la route, mais au cas où n'importe qui est intéressé, il y a maintenant un Module pour l'efficacité de la mémoire APPROXIMAT STAUSTICIQUE STATISTIQUE. Son interface suit généralement celle des statistiques :: descriptive et co.

Il divise l'échantillon en intervalles logarithmiques et ne cesse que les comptes touchés. Ainsi, une erreur relative fixe est introduite (la précision peut être ajustée dans NOUVEAU ()), mais de grandes quantités de données peuvent être traitées sans utiliser beaucoup de mémoire.


0 commentaires