Algorithm-Classifier-IsolationForest

 view release on metacpan or  search on metacpan

examples/contamination-threshold.pl  view on Meta::CPAN

#!/usr/bin/env perl

# 03-contamination-threshold.pl
#
# Picking an anomaly score cutoff by hand is fiddly. If you can estimate what
# fraction of your data is anomalous, pass it as `contamination` and fit() will
# learn a threshold that flags about that fraction of the training set. predict()
# then uses that learned threshold by default, so you never have to guess a
# number.
#
#     perl -Ilib examples/contamination-threshold.pl

use strict;
use warnings;
use Algorithm::Classifier::IsolationForest;
use List::Util qw(sum);

use constant PI => 3.14159265358979;

examples/contamination-threshold.pl  view on Meta::CPAN

printf "Flagged with a fixed 0.5 threshold : %d / %d points (%.1f%%)\n", $n_fixed, scalar @data, 100 * $n_fixed / @data;
printf "\n(true anomaly rate baked into the data: %.1f%%)\n",            100 * 20 / @data;

print <<'NOTE';

Takeaways:
  * decision_threshold() exposes whatever fit() learned (undef if you never set
    contamination).
  * predict() with no threshold uses that learned cutoff; pass an explicit
    threshold to override it for a single call.
  * Set contamination to your best guess of the anomaly fraction -- it doesn't
    have to be exact, it just calibrates where the cutoff lands.
NOTE

t/37-majority-voting.t  view on Meta::CPAN

		like( $out, qr/"voting"\s*:\s*"majority"/, 'printed model records voting => majority' );

		$out = `$^X -Ilib $bin fit -i $csv -p --voting bogus -s 5 2>&1`;
		isnt( $?, 0, 'fit --voting bogus exits non-zero' );
		like( $out, qr/must be either mean or majority/, 'bogus voting value is rejected' );
	}; ## end 'CLI fit --voting' => sub
} ## end SKIP:

# ------------------------------------------------------------------------
# CLI: set_voting flips a saved model, recalibrating when contamination
# was set and refusing to guess a threshold without the training data.
# ------------------------------------------------------------------------
SKIP: {
	my $bin = File::Spec->rel2abs('bin/iforest');
	skip "bin/iforest not found", 1 unless -x $bin;

	subtest 'CLI set_voting' => sub {
		require File::Temp;
		my ( $cfh, $csv ) = File::Temp::tempfile( SUFFIX => '.csv', UNLINK => 1 );
		print $cfh join( ',', @$_ ) . "\n" for @data;
		close $cfh;



( run in 0.902 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )