Calculo de valor futuro - regrassão linear

Publicado por Alex Falcao 11/02/2006

[ Hits: 6.120 ]

Homepage: http://alexfalcao.pro.br

Download Forecast.pl




Este é um módulo orientado a objeto para calcular um valor futuro usando valores existentes.
O novo valor é calculado usando a regressão linear.

  



Esconder código-fonte

package Statistics::Forecast;

$VERSION = '0.1';

use strict;

=head1 NAME

Statistics::Forecast

=head1 DESCRIPTION

This is a Oriented Object module that calculates a future value by using existing values. The new value is calculated by using linear regression.

=head1 SYNOPSIS

   use Statistics::Forecast;

Create forecast object

   my $FCAST = new Statistics::Forecast("My Forecast Name");

Add data

   $FCAST->{DataX} = \@Array_X;
   $FCAST->{DataY} = \@Array_Y;
   $FCAST->{NextX} = $NextX;

Calculate the result

   $FCAST->calc;

Get the result

   my $Result_Forecast = $FCAST->{ForecastY);

=head1 INTERNALS

The equation for Forecast is:

   a+bx, where 'x' is the predicted value and
       _    _
   a = y + bx

   b = sum((x+x)(y-y))/sum(x-x)**2

=head1 METHODS

=over

=item F<new>

Receives a forecast name, only to remember
and returns the blessed data structure as
a Statistics::Forecast object.

 my $FCAST = new Statistics::Forecast("My Forecast");

=cut

################################################################

sub new {
        my $classname= shift(@_);
        my $ForecastName = shift(@_) || "with no name";
        my $DataX = shift(@_) || undef;
        my $DataY = shift(@_) || undef;
        my $NextX = shift(@_) || undef;
        my $self = {
                ForecastName => $ForecastName,
                DataX => $DataX,
                DataY => $DataY,
                NextX => $NextX,

                # Initialializing Acumulative variables
                SumX => 0,
                SumY => 0,
                SumXY => 0,
                SumXX => 0
        };

        bless $self;
        return $self;

}

=item F<calc>

Calculate and return the forecast value.

 $FCAST->calc;

=cut

################################################################

sub calc {
        my $self = shift;

        # Verify if the inputed values are correct.
        if (!$self->{DataY}) { die "Cannot run without Y values" };

        # if no X values were input, populate with 1, 2 ...
        if ($#{$self->{DataX}} eq -1) {
           for (my $X=1; $X <= $#{$self->{DataY}}+1; $X++) {
              $self->{DataX}[$X-1] = $X;
           }
        }

        if (join("", @{$self->{DataX}}) =~ /[^0-9\-]/) { die "You tried to input an illegal value to 'X'." };
        if (join("", @{$self->{DataY}}) =~ /[^0-9\-]/) { die "You tried to input an illegal value to 'Y'." };
        if ($self->{NextX} =~ /[^0-9\-]/) { die "You tried to input an illegal value to predict." };

        if ($#{$self->{DataY}} != $#{$self->{DataX}}) { die "Cannot run with different number of 'X' values." };
        if (!$self->{NextX}) { die "Cannot run with no data point which you want to predict a value." };


        # Calculate the Sum of Y, X, X*Y and X**2 values.
        for (my $X=0; $X <= $#{$self->{DataX}}; $X++) {
           $self->{SumY} += $self->{DataY}[$X];
           $self->{SumX} += $self->{DataX}[$X];
           $self->{SumXY} += ($self->{DataX}[$X] * $self->{DataY}[$X]);
           $self->{SumXX} += ($self->{DataX}[$X]**2);
        }

        $self->{N} = $#{$self->{DataX}}+1;              # Number of Elements
        $self->{AvgX} = $self->{SumX} / $self->{N};     # X Average
        $self->{AvgY} = $self->{SumY} / $self->{N};     # Y Average

        my $B1 = ($self->{N} * $self->{SumXY} - $self->{SumX} * $self->{SumY});
        my $B2 = ($self->{N} * $self->{SumXX} - $self->{SumX}**2 );
        my $B = $B1 / $B2;
        my $A = $self->{AvgY} - $B*$self->{AvgX};

        $self->{ForecastY} = $A + $B*$self->{NextX}; # The forecast
}

################################################################

=item F<dump>

Prints data for debuging propose.

 $FCAST->{dump};

=item F<SumX>

Returns the sum of X values.

 my $SumOfX = $FCAST->{SumX};

=item F<SumY>

Returns the sum of Y values.

 my $SumOfY = $FCAST->{SumY};

=item F<SumXX>

Returns the sum of X**2 values.

 my $SumOfXX = $FCAST->{SumXX};

=item F<SumXY>

Returns the sum of X * Y values.

 my $SumOfXY = $FCAST->{SumXY};

=item F<AvgX>

Returns the average of X values.

 my $AvgX = $FCAST->{AvgX};

=item F<AvgY>

Returns the average of Y values.

 my $AvgY = $FCAST->{AvgY};

=item F<N>

Return the number of X values.

 my $N = $FCAST->{N};

=back

=cut

################################################################

sub dump {

        my $self = shift;
        print "\n\n";
        print "###########################################\n";
        print "      This is a Forecast dump              \n";
        print "###########################################\n";
        print "\n";
        if ($self->{N}) {
           print ".  Forecast Name   : ", $self->{ForecastName}, "\n";
           print ".  Number of elements: ", $self->{N}, "\n";
           print ".  --------------------------------------- \n";
           print ".  X Values\n\t", join(";  ", @{$self->{DataX}}), "\n";
           print ".  Sum of X values   : ", $self->{SumX}, "\n";
           print ".  --------------------------------------- \n";
           print ".  Y Values\n\t", join(";  ", @{$self->{DataY}}), "\n";
           print ".  Sum of Y values   : ", $self->{SumY}, "\n";
           print ".  --------------------------------------- \n";
           print ".  Sum of X*Y values : ", $self->{SumXY}, "\n";
           print ".  Sum of X**2 values: ", $self->{SumXX}, "\n";
           print ".  --------------------------------------- \n";
           print ".  Predict inputed   : ", $self->{NextX}, "\n";
           print ".  Forecast value    : ", $self->{ForecastY}, "\n";
           print ".  --------------------------------------- \n";
           print ".  Thanks for using Statistics::Forecast\n\n";
        } else {
           print "Error: You have to use method <calc> \n";
           print "       before dump the values.\n";
           print "\n";
        }
}

=head1 EXAMPLE

   use Statistics::Forecast;

   my @Y = (1,3,7,12);
   my @X = (1,2,3,4);

   my $FCAST = new Statistics::Forecast("My Forecast");

   $FCAST->{DataX} = \@X;
   $FCAST->{DataY} = \@Y;
   $FCAST->{NextX} = 8;
   $FCAST->calc;

   print "The Forecast ", $FCAST->{ForecastName};
   print " has the forecast value: ", $FCAST->{ForecastY}, "\n";

=head1 AUTHOR

This module was developed by Alex Falcao (webmaster@brfic.com).
http://www.brfic.com/webmaster/

=head1 STATUS OF THE MODULE

This is the first version and calculates forecast value.

=head1 VERSION

0.1

=head1 COPYRIGHT

This module is released for free public use under a GPL license.

=cut

1;

Scripts recomendados

Separando seu código em módulos no Perl

Usando sub/method signatures no Perl

Exemplo de uso do módulo Term::InKey

Perl OO & Atributos com Class::Accessor

Usando comandos shell com Perl


  

Comentários

Nenhum comentário foi encontrado.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts