AI-DecisionTree
view release on metacpan or search on metacpan
lib/AI/DecisionTree.pm view on Meta::CPAN
use strict;
package AI::DecisionTree;
{
$AI::DecisionTree::VERSION = '0.11';
}
use AI::DecisionTree::Instance;
use Carp;
use vars qw(@ISA);
sub new {
my $package = shift;
return bless {
noise_mode => 'fatal',
prune => 1,
purge => 1,
verbose => 0,
max_depth => 0,
@_,
nodes => 0,
instances => [],
name_gen => 0,
}, $package;
}
sub nodes { $_[0]->{nodes} }
sub noise_mode { $_[0]->{noise_mode} }
sub depth { $_[0]->{depth} }
sub add_instance {
my ($self, %args) = @_;
croak "Missing 'attributes' parameter" unless $args{attributes};
croak "Missing 'result' parameter" unless defined $args{result};
$args{name} = $self->{name_gen}++ unless exists $args{name};
my @attributes;
while (my ($k, $v) = each %{$args{attributes}}) {
$attributes[ _hlookup($self->{attributes}, $k) ] = _hlookup($self->{attribute_values}{$k}, $v);
}
$_ ||= 0 foreach @attributes;
push @{$self->{instances}}, AI::DecisionTree::Instance->new(\@attributes, _hlookup($self->{results}, $args{result}), $args{name});
}
sub _hlookup {
$_[0] ||= {}; # Autovivify as a hash
my ($hash, $key) = @_;
unless (exists $hash->{$key}) {
$hash->{$key} = 1 + keys %$hash;
}
return $hash->{$key};
}
sub _create_lookup_hashes {
my $self = shift;
my $h = $self->{results};
$self->{results_reverse} = [ undef, sort {$h->{$a} <=> $h->{$b}} keys %$h ];
foreach my $attr (keys %{$self->{attribute_values}}) {
my $h = $self->{attribute_values}{$attr};
$self->{attribute_values_reverse}{$attr} = [ undef, sort {$h->{$a} <=> $h->{$b}} keys %$h ];
}
}
sub train {
my ($self, %args) = @_;
if (not @{ $self->{instances} }) {
croak "Training data has been purged, can't re-train" if $self->{tree};
croak "Must add training instances before calling train()";
}
$self->_create_lookup_hashes;
local $self->{curr_depth} = 0;
( run in 0.469 second using v1.01-cache-2.11-cpan-140bd7fdf52 )