Algorithm-Classifier-IsolationForest
view release on metacpan or search on metacpan
benchmarking/bench-fit.pl view on Meta::CPAN
#!/usr/bin/perl
# benchmarking/bench-fit.pl
#
# Benchmarks the fit() method across five dimensions:
# 1. n_trees -- number of isolation trees
# 2. sample_size/psi -- sub-sample size used to build each tree
# 3. dataset size -- number of training samples
# 4. feature count -- dimensionality (wide range: 2, 5, 10, 20, 50)
# 5. feature count -- fine-grained 2â10 columns
#
# Each section uses BenchAccel::wall_cmpthese so results include both the raw
# rate (fits/sec) and relative %-difference between variants.
# Data generation is done before timing starts.
#
# Run with:
# perl -Ilib benchmarking/bench-fit.pl
use strict;
use warnings;
use lib '../lib';
use FindBin;
use lib "$FindBin::Bin";
use BenchAccel qw(wall_cmpthese);
use Algorithm::Classifier::IsolationForest;
use constant PI => 3.14159265358979;
# Simple Box-Muller Gaussian sample
sub gaussian {
my ( $mu, $sigma ) = @_;
return $mu + $sigma
* sqrt( -2 * log( rand() || 1e-12 ) )
* cos( 2 * PI * rand() );
}
# Generate $n inlier samples ($nf features each) plus ~5% outliers placed at
# radius 5-8 from the origin.
sub make_data {
my ( $n, $nf ) = @_;
my @rows = map { [ map { gaussian( 0, 1 ) } 1 .. $nf ] } 1 .. $n;
for ( 1 .. int( $n * 0.05 ) ) {
my $r = 5 + rand() * 3;
push @rows, [ map { $r * ( rand() > 0.5 ? 1 : -1 ) } 1 .. $nf ];
}
return \@rows;
}
print "=" x 62, "\n";
print " fit() benchmarks -- Algorithm::Classifier::IsolationForest\n";
print "=" x 62, "\n";
print "(rates shown as fits/second wall-clock; higher is faster)\n";
# -----------------------------------------------------------------------
# 1. n_trees
# -----------------------------------------------------------------------
print "\n--- n_trees (1000 samples, 2 features, sample_size=256) ---\n";
srand(42);
my $d1k = make_data( 1000, 2 );
wall_cmpthese(
-2,
{
'n_trees=10' => sub { Algorithm::Classifier::IsolationForest->new( n_trees => 10, sample_size => 256 )->fit($d1k) },
'n_trees=50' => sub { Algorithm::Classifier::IsolationForest->new( n_trees => 50, sample_size => 256 )->fit($d1k) },
'n_trees=100' => sub { Algorithm::Classifier::IsolationForest->new( n_trees => 100, sample_size => 256 )->fit($d1k) },
'n_trees=200' => sub { Algorithm::Classifier::IsolationForest->new( n_trees => 200, sample_size => 256 )->fit($d1k) },
'n_trees=500' => sub { Algorithm::Classifier::IsolationForest->new( n_trees => 500, sample_size => 256 )->fit($d1k) },
}
);
# -----------------------------------------------------------------------
# 2. sample_size (psi)
# -----------------------------------------------------------------------
print "\n--- sample_size/psi (1000 samples, 2 features, n_trees=100) ---\n";
( run in 1.793 second using v1.01-cache-2.11-cpan-c966e8aa7e8 )