Algorithm-Classifier-IsolationForest

 view release on metacpan or  search on metacpan

benchmarking/bench-extended-predict-accel.pl  view on Meta::CPAN

#!/usr/bin/perl
# benchmarking/bench-extended-predict-accel.pl
#
# Benchmarks extended-mode (EIF) scoring/prediction under each
# acceleration backend:
#   pure_perl   -- use_c => 0                   (pure Perl tree walk)
#   c_serial    -- use_c => 1, use_openmp => 0  (C tree walk, single thread)
#   c_openmp    -- use_c => 1, use_openmp => 1  (C tree walk, OpenMP parallel)
#
# Extended mode adds an oblique dot product at every internal node.  The
# C backend uses `#pragma omp simd` to auto-vectorize that dot product
# (when OpenMP 4.0+ is available), so the c_serial vs c_openmp gap may
# be wider here than in axis mode, especially at high feature counts.
#
# Sections:
#   1. Scoring method comparison  -- all 5 methods under each backend
#   2. Query set size scaling     -- where OpenMP parallelism shines
#   3. n_trees scaling            -- more trees = more work per point
#   4. Feature count (wide)       -- 2, 5, 10, 20, 50
#   5. Feature count (2-10)       -- fine-grained sweep
#
# Models are pre-trained before any timing begins.
#
# Run with:
#   perl -Ilib benchmarking/bench-extended-predict-accel.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;

sub gaussian {
    my ( $mu, $sigma ) = @_;
    return $mu + $sigma
        * sqrt( -2 * log( rand() || 1e-12 ) )
        * cos( 2 * PI * rand() );
}

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;
}

my $HAS_C      = $Algorithm::Classifier::IsolationForest::HAS_C;
my $HAS_OPENMP = $Algorithm::Classifier::IsolationForest::HAS_OPENMP;

sub build_models {
    my (%opts) = @_;
    my $data = delete $opts{_data};
    my %m;
    $m{pure_perl} = Algorithm::Classifier::IsolationForest->new(
        %opts, use_c => 0,
    )->fit($data);
    if ($HAS_C) {
        $m{c_serial} = Algorithm::Classifier::IsolationForest->new(
            %opts, use_c => 1, use_openmp => 0,
        )->fit($data);



( run in 0.680 second using v1.01-cache-2.11-cpan-c966e8aa7e8 )