Algorithm-BaumWelch

 view release on metacpan or  search on metacpan

lib/Algorithm/BaumWelch.pm  view on Meta::CPAN

    $self->[0][2] = scalar @obs;
    return;
}

sub feed_values {
    croak qq{\nThis method expects 3 arguments.} if @_ != 4;
    my ($self, $trans, $emis, $start) = @_;
    croak qq{\nThis method expects 3 arguments.} if (ref $trans ne q{ARRAY} || ref $emis ne q{HASH} || ref $start ne q{ARRAY});
    my $obs_tipos = $self->[0][1];
    my $obs_numero = $self->[0][2];
    my $t_length = &_check_trans($trans);
    &_check_emis($emis, $obs_tipos, $obs_numero, $t_length);
    &_check_start($start, $t_length);
    $self->[1][0] = $trans;
    $self->[1][1] = $emis;
    $self->[1][2] = $start;
    my @stop; # 0.1/1 nao faz diferenca e para|comeca (stop|start) sempre iguala = 0
    for (0..$#{$trans}) { push @stop, 1 };
    $self->[1][3] = [@stop];
    return;
}

sub _check_start {
    my ($start, $t_length) = @_;
    croak qq{\nThere must be an initial probablity for each state in the start ARRAY.} if scalar @{$start} != $t_length;
    for (@{$start}) { croak qq{\nThe start ARRAY values must be numeric.} if !(/^[+-]?\ *(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$/) };
    my $sum =0;
    for (@{$start}) { $sum += $_ }
    croak qq{\nThe starting probabilities must sum to 1.} if ($sum <= 0.95 || $sum >= 1.05);
    return;
}

sub _check_emis {
    my ($emis, $obs_tipos, $obs_numero, $t_length) = @_;
    my @emis_keys = (keys %{$emis});
    @emis_keys = sort {$a cmp $b} @emis_keys;
    croak qq{\nThere must be an entry in the emission matrix for each type of observation in the observation series.} if $obs_numero != scalar @emis_keys;
    for (0..$#emis_keys) { croak qq{\nThe observations in the emission matrix do not match those in the observation series.} if $emis_keys[$_] ne $obs_tipos->[$_]; }
    for (values %{$emis}) { 
        croak qq{\nThere must be a probability value for each state in the emission matrix.} if scalar @{$_} != $t_length;
        for my $cell (@{$_}) { croak qq{\nThe emission matrix values must be numeric.} if $cell !~ /^[+-]?\ *(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$/; }
    }
    for my $i (0..$t_length-1) { # só fazendo 2-estado agora
        my $sum = 0;
        for my $o (@{$obs_tipos}) { $sum += $emis->{$o}[$i] }
        croak qq{\nThe emission matrix column must sum to 1.} if ($sum <= 0.95 || $sum >= 1.05);
    }
    return;
}

sub _check_trans {
    my $trans = shift;
    my $t_length = scalar @{$trans};
    for (@{$trans}) { 
        croak qq{\nThe transition matrix much be square.} if scalar @{$_} != $t_length;
        my $sum = 0;
        for my $cell (@{$_}) { 
            croak qq{\nThe transition matrix values must be numeric.} if $cell !~ /^[+-]?\ *(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$/;
            $sum += $cell
        }
        croak qq{\nThe transition matrix row must sum to 1.} if ($sum <= 0.95 || $sum >= 1.05);
    }
    return $t_length;
}

sub random_initialise {
    my ($self, $states) = @_;
    my $obs_names = $self->[0][1];
    my $trans = &_gera_trans($states);
    my $emis = &_gera_emis($states, $obs_names);
    my $start = &_gera_init($states);
    $self->[1][0] = $trans;
    $self->[1][1] = $emis;
    $self->[1][2] = $start;
    my @stop; # 0.1/1 nao faz diferenca e para|comeca (stop|start) sempre iguala = 0
    for (0..$states-1) { push @stop, 1 };
    $self->[1][3] = [@stop];
    return;
}

sub _gera_init {
    my $length = shift;
    my $sum = 0;
    my $init = [];
    srand;
    $#{$init} = $length-1; # só fazendo 2-estado agora
    for (@{$init}) { $_ = rand; $sum += $_ }
    #/ normalise such that sum is equal to 1
    for (@{$init}) { $_ /= $sum }
    return $init;
}

sub _gera_trans {
    my $length = shift;
    my $t = [];
    $#{$t} = $length-1; # só fazendo 2-estado agora
    #/ gera_init normalises
    for (@{$t}) { $_ = &_gera_init($length); }
    return $t;
}

sub _gera_emis {
    my ($length, $obs_names) = @_;
    my $e = {};
    srand;
    for (@{$obs_names}) { 
        my $init = [];
        $#{$init} = $length-1; # só fazendo 2-estado agora
        for (@{$init}) { $_ = rand;  }
        $e->{$_} = $init;
    }
    # para cada estado a suma deve iguala 1 - normalise such that sum of obs_x|state = 1
    for my $i (0..$length-1) { # só fazendo 2-estado agora
        my $sum = 0;
        for my $o (@{$obs_names}) { $sum += $e->{$o}[$i] }
        for my $o (@{$obs_names}) { $e->{$o}[$i] /= $sum }
    }
    #print qq{\n\nauto-gera emis de numeros aleatorios que sumam 1 para cada estado}; draw($e);
    return $e;
}

sub _forwardbackward_reestimacao {
    my $self = shift;

lib/Algorithm/BaumWelch.pm  view on Meta::CPAN

    }
    return;
}

sub _baum_welch_10 {
    my $self = shift;
    for (0..10) { $self->_forwardbackward_reestimacao; }
    return;
}

sub _baum_welch_length {
    my $self = shift;
    for (0..$#{$self->[0][0]}) { $self->_forwardbackward_reestimacao; }
    return;
}

sub results {
    my $self = shift;
    my $trans = $self->[1][0];
    my $emis = $self->[1][1];
    my $start = $self->[1][2];

lib/Algorithm/BaumWelch.pm  view on Meta::CPAN

}

1; # Magic true value required at end of module

__END__

#ARRAY REFERENCE (0)
#  |  
#  |__ARRAY REFERENCE (1) [ '->[0]' ]
#  |    |  
#  |    |__ARRAY REFERENCE (2) ---LONG_LIST_OF_SCALARS--- [ length = 33 ] e.g. 0..2:  obs2, obs3, obs3 [ '->[0][0]' ] # a serie
#  |    |  
#  |    |__ARRAY REFERENCE (2) ---LONG_LIST_OF_SCALARS--- [ length = 3 ]: obs3, obs1, obs2 [ '->[0][1]' ] # a lista de tipos de observacoes
#  |    |  
#  |    |__SCALAR = '3' (2)  [ '->[0][2]' ] # o numero de tipos de observacoes 
#  |  
#  |__ARRAY REFERENCE (1) [ '->[1]' ]
#  |    |  
#  |    |__ARRAY REFERENCE (2) [ '->[1][0]' ] # transition matrix
#  |    |    |  
#  |    |    |__ARRAY REFERENCE (3) ---LONG_LIST_OF_SCALARS--- [ length = 2 ]: 0.933779184947876, 0.0718663090308487 [ '->[1][0][0]' ]
#  |    |    |  
#  |    |    |__ARRAY REFERENCE (3) ---LONG_LIST_OF_SCALARS--- [ length = 2 ]: 0.0662208150521236, 0.864944219467616 [ '->[1][0][1]' ]
#  |    |  
#  |    |__HASH REFERENCE (2) [ '->[1][1]' ] # emission matrix
#  |    |    |  
#  |    |    |__'obs3'=>ARRAY REFERENCE (3) ---LONG_LIST_OF_SCALARS--- [ length = 2 ]: 0.211448366743702, 0.465609305295478 [ '->[1][1]{obs3}' ]
#  |    |    |  
#  |    |    |__'obs1'=>ARRAY REFERENCE (3) ---LONG_LIST_OF_SCALARS--- [ length = 2 ]: 0.640481492730478, 7.18630557481621e-09 [ '->[1][1]{obs1}' ]
#  |    |    |  
#  |    |    |__'obs2'=>ARRAY REFERENCE (3) ---LONG_LIST_OF_SCALARS--- [ length = 2 ]: 0.14807014052582, 0.534390687518216 [ '->[1][1]{obs2}' ]
#  |    |  
#  |    |__ARRAY REFERENCE (2) ---LONG_LIST_OF_SCALARS--- [ length = 2 ]: 4.52394236439737e-30, 1 [ '->[1][2]' ] # start conditions
#  |
#  |__ ARRAY REFERENCE (1)  [ '->[2]' ] # perp
#

=head1 SEE ALSO

Algorithm::Viterbi

=cut



( run in 0.512 second using v1.01-cache-2.11-cpan-65fba6d93b7 )