Algorithm-Classifier-IsolationForest

 view release on metacpan or  search on metacpan

benchmarking/bench-sklearn-scoring.pl  view on Meta::CPAN

my $python_bin;
for my $cmd (qw(python3 python)) {
	my $probe = `$cmd -c "import sklearn; print('ok')" 2>/dev/null`;
	if ( defined $probe && $probe =~ /\bok\b/ ) {
		$python_bin = $cmd;
		last;
	}
}

# -----------------------------------------------------------------------
# Python benchmarking script (embedded, written to a temp file).
# -----------------------------------------------------------------------
my $py_script = <<'END_PY';
import sys, json
import time as pytime
import numpy as np
from sklearn.ensemble import IsolationForest

def bench(fn, seconds):
    t0 = pytime.perf_counter()
    while pytime.perf_counter() - t0 < 0.3:
        fn()
    t0 = pytime.perf_counter()
    n = 0
    while pytime.perf_counter() - t0 < seconds:
        fn()
        n += 1
    return n / (pytime.perf_counter() - t0)

def load_csv(path):
    with open(path) as f:
        return np.array([[float(v) for v in ln.strip().split(',')]
                         for ln in f if ln.strip()])

bench_secs = float(sys.argv[1])
specs      = sys.argv[2:]

models = {}
results = {}
for spec in specs:
    train_csv, query_csv, label = spec.split('|', 2)
    clf = models.get(train_csv)
    if clf is None:
        X_train = load_csv(train_csv)
        psi = min(256, len(X_train))
        clf = IsolationForest(n_estimators=100, max_samples=psi,
                              contamination='auto', random_state=1)
        clf.fit(X_train)
        models[train_csv] = clf
    X_q = load_csv(query_csv)
    results[label] = {
        'score_samples':     bench(lambda X=X_q: clf.score_samples(X),     bench_secs),
        'predict':           bench(lambda X=X_q: clf.predict(X),           bench_secs),
        'decision_function': bench(lambda X=X_q: clf.decision_function(X), bench_secs),
    }

print(json.dumps(results))
END_PY

# -----------------------------------------------------------------------
# Run Python (one subprocess for all experiments)
# -----------------------------------------------------------------------
my $sk;
if ( defined $python_bin ) {
	my ( $py_fh, $py_path ) = tempfile( SUFFIX => '.py', UNLINK => 1 );
	print $py_fh $py_script;
	close $py_fh;

	my $specs = join( ' ', map { qq("$_->{train_csv}|$_->{query_csv}|@{[exp_key($_)]}") } @experiments );
	my $raw   = `$python_bin "$py_path" $BENCH_SECS $specs 2>/dev/null`;
	$sk = eval { JSON::PP->new->decode($raw) };
}

# -----------------------------------------------------------------------
# Run Perl benchmarks for all three backends
# -----------------------------------------------------------------------
my ( %pure_pl, %c_pl, %omp_pl );

for my $exp (@experiments) {
	my $key = exp_key($exp);
	my $q   = $exp->{query_data};

	# Pure Perl
	{
		my $m = $exp->{pure_model};
		$pure_pl{$key} = {
			score_samples         => wall_rate( sub { $m->score_samples($q) },         $BENCH_SECS ),
			predict               => wall_rate( sub { $m->predict($q) },               $BENCH_SECS ),
			score_predict_samples => wall_rate( sub { $m->score_predict_samples($q) }, $BENCH_SECS ),
			score_predict_split   => wall_rate( sub { $m->score_predict_split($q) },   $BENCH_SECS ),
			path_lengths          => wall_rate( sub { $m->path_lengths($q) },          $BENCH_SECS ),
		};
	}

	# C serial (single-threaded Inline::C)
	if ($HAS_C) {
		my $m      = $exp->{c_model};
		my $packed = $m->pack_data($q);
		$c_pl{$key} = {
			score_samples              => wall_rate( sub { $m->score_samples($q) },            $BENCH_SECS ),
			score_samples_packed       => wall_rate( sub { $m->score_samples($packed) },       $BENCH_SECS ),
			predict                    => wall_rate( sub { $m->predict($q) },                  $BENCH_SECS ),
			predict_packed             => wall_rate( sub { $m->predict($packed) },             $BENCH_SECS ),
			score_predict_samples      => wall_rate( sub { $m->score_predict_samples($q) },    $BENCH_SECS ),
			score_predict_split        => wall_rate( sub { $m->score_predict_split($q) },      $BENCH_SECS ),
			score_predict_split_packed => wall_rate( sub { $m->score_predict_split($packed) }, $BENCH_SECS ),
			path_lengths               => wall_rate( sub { $m->path_lengths($q) },             $BENCH_SECS ),
		};
	} ## end if ($HAS_C)

	# C + OpenMP (parallel Inline::C)
	if ($HAS_OPENMP) {
		my $m      = $exp->{omp_model};
		my $packed = $m->pack_data($q);
		$omp_pl{$key} = {
			score_samples              => wall_rate( sub { $m->score_samples($q) },            $BENCH_SECS ),
			score_samples_packed       => wall_rate( sub { $m->score_samples($packed) },       $BENCH_SECS ),
			predict                    => wall_rate( sub { $m->predict($q) },                  $BENCH_SECS ),
			predict_packed             => wall_rate( sub { $m->predict($packed) },             $BENCH_SECS ),
			score_predict_samples      => wall_rate( sub { $m->score_predict_samples($q) },    $BENCH_SECS ),
			score_predict_split        => wall_rate( sub { $m->score_predict_split($q) },      $BENCH_SECS ),



( run in 2.435 seconds using v1.01-cache-2.11-cpan-995e09ba956 )