Algorithm-Classifier-IsolationForest

 view release on metacpan or  search on metacpan

lib/Algorithm/Classifier/IsolationForest/App/Command/csv2plot.pm  view on Meta::CPAN


	if ( !defined( $opt->{'i'} ) ) {
		$self->usage_error('-i has not been specified for a file to process');
	} elsif ( !-f $opt->{'i'} ) {
		$self->usage_error( '-i, "' . $opt->{'i'} . '", is not a file or does not exist' );
	} elsif ( !-r $opt->{'i'} ) {
		$self->usage_error( '-i, "' . $opt->{'i'} . '", is not readable' );
	}

	if ( -e $opt->{'o'} && !$opt->{'w'} ) {
		$self->usage_error( '-o, "' . $opt->{'o'} . '", already exists and -w is not given' );
	} elsif ( -e $opt->{'o'} && !-f $opt->{'o'} ) {
		$self->usage_error( '-o, "' . $opt->{'o'} . '", already exists and -w given but file is not a file' );
	} elsif ( -e $opt->{'o'} && !-w $opt->{'o'} ) {
		$self->usage_error( '-o, "' . $opt->{'o'} . '", already exists and -w given but file is not writable' );
	}

	if (   ( $opt->{'p'} ne 'auto' )
		&& ( $opt->{'p'} ne '2heat' )
		&& ( $opt->{'p'} ne '3range' )
		&& ( $opt->{'p'} ne '3binary' ) )
	{
		$self->usage_error( '-p, "' . $opt->{'p'} . '", is not set to auto, 2heat, 3range, or 3binary' );
	}

	return 1;
} ## end sub validate

sub execute {
	my ( $self, $opt, $args ) = @_;

	my @raw_csv      = read_file( $opt->{'i'} );
	my @first_fields = split( /,/, $raw_csv[0] );
	my $ncols        = scalar @first_fields;

	if ( $opt->{'p'} eq 'auto' && $ncols >= 4 ) {
		$opt->{'p'} = '3range';
	} elsif ( $opt->{'p'} eq 'auto' && $ncols >= 2 ) {
		$opt->{'p'} = '2heat';
	} elsif ( $opt->{'p'} eq 'auto' ) {
		die('-p is set to auto and the specified CSV does not have enough columns');
	} elsif ( $opt->{'p'} eq '2heat' && $ncols < 2 ) {
		die('2heat specified but there is no column for y');
	} elsif ( $opt->{'p'} eq '3range' && $ncols < 3 ) {
		die('3range specified but there is no column for score');
	} elsif ( $opt->{'p'} eq '3binary' && $ncols < 3 ) {
		die('3binary specified but there is no column for truth');
	}

	# For predict -d output: score is the second-to-last column, prediction is last.
	my $score_col = $ncols - 1;
	my $pred_col  = $ncols;

	$opt->{'i'} = File::Spec->rel2abs( $opt->{'i'} );
	$opt->{'o'} = File::Spec->rel2abs( $opt->{'o'} );

	my ( $tempfh, $tempfile ) = tempfile( 'UNLINK' => 1 );

	my $ps = $opt->{'small_points'} ? '0.8' : '1.5';

	my $gnu_plot_stuff = 'set terminal pngcairo size 1200,900 font "Sans,11"
set output "' . $opt->{'o'} . '"

set datafile separator ","
set key autotitle columnhead

set grid lc "gray70" lw 0.5 dt 2

';

	if ( $opt->{'p'} eq '3range' ) {
		$gnu_plot_stuff = $gnu_plot_stuff . '
set palette defined (0 "#4575b4", 0.5 "#ffffbf", 1 "#d73027")
set cblabel "outlier score"
plot "' . $opt->{'i'} . '" using 1:2:' . $score_col . ' with points pt 7 ps ' . $ps . ' palette title ""
';
	} elsif ( $opt->{'p'} eq '3binary' ) {
		$gnu_plot_stuff
			= $gnu_plot_stuff
			. 'plot "'
			. $opt->{'i'}
			. '" using 1:($'
			. $pred_col
			. '==0 ? $2 : 1/0) with points pt 7  ps 1.2 lc rgb "#4575b4" title "normal", \
     "'
			. $opt->{'i'}
			. '" using 1:($'
			. $pred_col
			. '==1 ? $2 : 1/0) with points pt 13 ps 2.0 lc rgb "#d73027" title "abnormal"
';
	} elsif ( $opt->{'p'} eq '2heat' ) {
		$gnu_plot_stuff = $gnu_plot_stuff . '
unset key
set view map
set palette cubehelix negative

set dgrid 25,25 gauss  kdensity 3, 3

splot "' . $opt->{'i'} . '" using 1:2:(1) with pm3d, \
      "" using 1:2:(1) with points lc "black" pt 7 ps 0.6 nogrid
';
	} ## end elsif ( $opt->{'p'} eq '2heat' )

	if ( $opt->{'print'} ) {
		print $gnu_plot_stuff;
		exit 0;
	}

	write_file( $tempfile, $gnu_plot_stuff );

	system( 'gnuplot', $tempfile );
	if ( $? != 0 ) {
		die( '"gnuplot ' . $tempfile . '" exited non-zero' );
	}

	if ( $opt->{'open'} ) {
		system( 'xdg-open', $opt->{'o'} );
	}

} ## end sub execute



( run in 0.335 second using v1.01-cache-2.11-cpan-acf6aa7dc9e )