AI-Calibrate
view release on metacpan or search on metacpan
lib/AI/Calibrate.pm view on Meta::CPAN
Calibrate returns a reference to an ordered list of references:
[ [score, prob], [score, prob], [score, prob] ... ]
Scores will be in descending numerical order. See the DESCRIPTION section for
how this structure is interpreted. You can pass this structure to the
B<score_prob> function, along with a new score, to get a probability.
=cut
sub calibrate {
my($data, $sorted) = @_;
if (DEBUG) {
print "Original data:\n";
for my $pair (@$data) {
my($score, $prob) = @$pair;
print "($score, $prob)\n";
}
}
lib/AI/Calibrate.pm view on Meta::CPAN
push(@result, [$last_score, $last_prob] );
}
$last_prob = $prob;
$last_score = $score;
}
return \@result;
}
sub PAV {
my ( $result ) = @_;
for ( my $i = 0; $i < @$result - 1; $i++ ) {
if ( $result->[$i][PROB] < $result->[ $i + 1 ][PROB] ) {
$result->[$i][PROB] =
( $result->[$i][PROB] + $result->[ $i + 1 ][PROB] ) / 2;
$result->[ $i + 1 ][PROB] = $result->[$i][PROB];
print "Averaging elements $i and ", $i + 1, "\n" if DEBUG;
for ( my $j = $i - 1; $j >= 0; $j-- ) {
lib/AI/Calibrate.pm view on Meta::CPAN
flatten( $result, $j, $d );
}
else {
last;
}
}
}
}
}
sub print_vector {
my($vec) = @_;
for my $pair (@$vec) {
print join(", ", @$pair), "\n";
}
}
sub flatten {
my ( $vec, $start, $len ) = @_;
if (DEBUG) {
print "Flatten called on vec, $start, $len\n";
print "Vector before: \n";
print_vector($vec);
}
my $sum = 0;
for my $i ( $start .. $start + $len-1 ) {
$sum += $vec->[$i][PROB];
lib/AI/Calibrate.pm view on Meta::CPAN
while (<>) {
chomp;
my(@fields) = split;
my $score = classifier(@fields);
my $prob = score_prob($score);
print "Estimated probability: $prob\n";
}
=cut
sub score_prob {
my($calibrated, $score) = @_;
my $last_prob = 1.0;
for my $tuple (@$calibrated) {
my($bound, $prob) = @$tuple;
return $prob if $score >= $bound;
$last_prob = $prob;
}
# If we drop off the end, probability estimate is zero
lib/AI/Calibrate.pm view on Meta::CPAN
1.00 > SCORE >= 0.71 prob = 0.667
0.71 > SCORE >= 0.39 prob = 0.000
0.39 > SCORE >= 0.00 prob = 0.000
These ranges are not necessarily compressed/optimized, as this sample output
shows.
=back
=cut
sub print_mapping {
my($calibrated) = @_;
my $last_bound = 1.0;
for my $tuple (@$calibrated) {
my($bound, $prob) = @$tuple;
printf("%0.3f > SCORE >= %0.3f prob = %0.3f\n",
$last_bound, $bound, $prob);
$last_bound = $bound;
}
if ($last_bound != 0) {
printf("%0.3f > SCORE >= %0.3f prob = %0.3f\n",
t/AI-Calibrate-1.t view on Meta::CPAN
# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl AI-Calibrate.t'
#########################
use Test::More tests => 34;
BEGIN { use_ok('AI::Calibrate', ':all') };
srand;
sub deeply_approx {
# Like Test::More::is_deeply but uses approx() to compare elements.
my( $got, $expected ) = @_;
my $EPSILON = 1.0e-6;
sub max { $_[0] > $_[1] ? $_[0] : $_[1] }
sub approx {
my($x, $y) = @_;
print("approx($x, $y)\n");
if ($x == 0 and $y == 0) {
return(1);
} else {
return(abs($x-$y) / max($x,$y) < $EPSILON);
}
}
for my $i (0 .. $#{$got}) {
my $g = $got->[$i];
t/AI-Calibrate-1.t view on Meta::CPAN
}
} else {
return(0);
}
}
return(1);
}
# Given an array reference, shuffle the array. This is the Fisher-Yates code
# from The Perl Cookbook.
sub shuffle_array {
my($array) = shift;
my($i);
for ($i = @$array ; --$i; ) {
my $j = int rand ($i+1);
next if $i == $j;
@$array[$i,$j] = @$array[$j,$i]
}
}
# These points are from the ROCCH-PAV paper, Table 1
t/AI-Calibrate-KL.t view on Meta::CPAN
# -*- Mode: CPerl -*-
use strict;
# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl AI-Calibrate.t'
#########################
use Test::More tests => 4;
BEGIN { use_ok('AI::Calibrate', ':all') };
sub trim($) {
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}
# These points are from Kun Liu
# Format of each point is [Threshold, Class].
my $points = [
[0.999, 1],
t/AI-Calibrate-NB.t view on Meta::CPAN
[0.535425255450615, 0.666666666666667]
);
for my $i (0 .. $#expected) {
print "$i = @{$expected[$i]}\n";
}
# This fails because two numbers differ at the 15th digit:
# is_deeply($calibrated, \@expected, "Naive Bayes calibration test");
sub close_enough {
my($x, $y) = @_;
return(abs($x - $y) < 1.0e-5);
}
sub lists_close_enough {
my($got, $expected) = @_;
if (@$got != @$expected) {
return 0;
}
for my $i (0 .. $#{$got}) {
for my $elem (0, 1) {
if (! close_enough($got->[$i][$elem], $expected->[$i][$elem])) {
diag(sprintf( "Got: %f\n", $got->[$i]));
diag(sprintf( "Expected: %f\n", $expected->[$i]));
return 0;
( run in 0.517 second using v1.01-cache-2.11-cpan-a5abf4f5562 )