Algorithm-Classifier-IsolationForest

 view release on metacpan or  search on metacpan

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

			$expected_cols = scalar @fields;
			die( 'Line ' . $line_int . ' of "' . $opt->{'i'} . '" has no columns' )
				if $expected_cols < 1;
		} elsif ( scalar @fields != $expected_cols ) {
			die(      'Line '
					. $line_int . ' of "'
					. $opt->{'i'}
					. '" has '
					. scalar(@fields)
					. ' columns but expected '
					. $expected_cols );
		}

		if ( !$has_mungers ) {
			my $col_int = 1;
			for my $field (@fields) {
				die(      'Line '
						. $line_int . ' of "'
						. $opt->{'i'}
						. '" value for column '
						. $col_int . ',"'
						. $field
						. '", does not appear to be a number' )
					unless looks_like_number($field);
				$col_int++;
			} ## end for my $field (@fields)
		} ## end if ( !$has_mungers )

		push @data, \@fields;

		$line_int++;
	} ## end foreach my $line ( read_file( $opt->{'i'} ) )

	# The tag count must match the CSV width whether the tags came from -t
	# or from a prototype's schema.
	my $check_tags = defined( $opt->{'t'} ) ? $opt->{'t'} : ( $iforest ? $iforest->feature_names : undef );
	if ( defined($check_tags) ) {
		my $n_tags     = scalar @$check_tags;
		my $n_features = defined($expected_cols) ? $expected_cols : 0;
		die( 'Number of feature tags (' . $n_tags . ') does not match number of CSV columns (' . $n_features . ')' )
			unless $n_tags == $n_features;
	}

	if ( !$iforest ) {
		$iforest = Algorithm::Classifier::IsolationForest->new(
			'mode'            => $mode,
			'n_trees'         => $opt->{'n'},
			'seed'            => $opt->{'s'},
			'sample_size'     => $opt->{'m'},
			'max_depth'       => $opt->{'d'},
			'extension_level' => $opt->{'e'},
			'contamination'   => $opt->{'c'},
			'feature_names'   => $opt->{'t'},
			'voting'          => $opt->{'voting'},
			'mungers'         => $mungers,
		);
	} ## end if ( !$iforest )

	# Munge the raw rows into numbers, then run the numeric validation
	# that was skipped at read time -- an unmunged column holding a
	# string is still an error, just reported post-munge.
	if ($has_mungers) {
		my $munged = $iforest->munge_rows( \@data );
		for my $i ( 0 .. $#$munged ) {
			for my $col ( 0 .. $#{ $munged->[$i] } ) {
				die(      'Line '
						. ( $i + 1 ) . ' of "'
						. $opt->{'i'}
						. '" value for column '
						. ( $col + 1 ) . ',"'
						. ( defined $munged->[$i][$col] ? $munged->[$i][$col] : 'undef' )
						. '", is not a number after munging' )
					unless looks_like_number( $munged->[$i][$col] );
			} ## end for my $col ( 0 .. $#{ $munged->[$i] } )
		} ## end for my $i ( 0 .. $#$munged )
		@data = @$munged;
	} ## end if ($has_mungers)

	$iforest->fit( \@data );

	my $model = $iforest->to_json;

	if ( $opt->{'p'} ) {
		print $model. "\n";
		exit 0;
	}

	write_file( $opt->{'o'}, { 'atomic' => 1 }, $model );
} ## end sub execute

return 1;



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