///|
pub fn ConvergenceReport::iterations(self : ConvergenceReport) -> Int {
self.completed_iterations
}
///|
pub fn ConvergenceReport::pair_updates(self : ConvergenceReport) -> Int {
self.completed_pair_updates
}
///|
pub fn ConvergenceReport::support_vectors(self : ConvergenceReport) -> Int {
self.retained_support_vectors
}
///|
pub fn ConvergenceReport::max_kkt_violation(self : ConvergenceReport) -> Double {
self.largest_kkt_violation
}
///|
pub fn ConvergenceReport::dual_objective(self : ConvergenceReport) -> Double {
self.final_dual_objective
}
///|
pub fn ConvergenceReport::converged(self : ConvergenceReport) -> Bool {
self.reached_stopping_condition
}
///|
pub fn BinaryModel::negative_class(self : BinaryModel) -> Int {
self.lower_class
}
///|
pub fn BinaryModel::positive_class(self : BinaryModel) -> Int {
self.upper_class
}
///|
pub fn BinaryModel::feature_count(self : BinaryModel) -> Int {
self.input_columns
}
///|
pub fn BinaryModel::kernel(self : BinaryModel) -> Kernel {
self.model_kernel
}
///|
pub fn BinaryModel::bias(self : BinaryModel) -> Double {
self.bias_value
}
///|
pub fn BinaryModel::support_vector_count(self : BinaryModel) -> Int {
self.support_rows.length()
}
///|
pub fn BinaryModel::support_vectors(self : BinaryModel) -> Array[Array[Double]] {
copy_matrix(self.support_rows)
}
///|
pub fn BinaryModel::support_labels(self : BinaryModel) -> Array[Int] {
self.support_class_labels.copy()
}
///|
pub fn BinaryModel::support_alphas(self : BinaryModel) -> Array[Double] {
self.support_alpha_values.copy()
}
///|
pub fn BinaryModel::convergence(self : BinaryModel) -> ConvergenceReport {
self.convergence_data
}
///|
fn checked_prediction_row(
row : Array[Double],
expected : Int,
) -> Result[Unit, SvmError] {
if row.length() != expected {
return Err(PredictionDimensionMismatch(expected, row.length()))
}
for column, value in row {
if !finite_double(value) {
return Err(NonFiniteFeature(0, column))
}
}
Ok(())
}
///|
/// Returns the signed decision value; positive values select the higher class.
pub fn BinaryModel::decision_value(
self : BinaryModel,
row : Array[Double],
) -> Result[Double, SvmError] {
match checked_prediction_row(row, self.input_columns) {
Err(error) => return Err(error)
Ok(_) => ()
}
let mut total = self.bias_value
for index = 0; index < self.support_rows.length(); index = index + 1 {
let value = match
kernel_value(self.model_kernel, self.support_rows[index], row) {
Err(error) => return Err(error)
Ok(value) => value
}
total = total + self.signed_coefficients[index] * value
}
if !finite_double(total) {
return Err(NumericFailure("binary decision"))
}
Ok(total)
}
///|
pub fn BinaryModel::predict(
self : BinaryModel,
row : Array[Double],
) -> Result[Int, SvmError] {
match self.decision_value(row) {
Err(error) => Err(error)
Ok(value) =>
Ok(if value >= 0.0 { self.upper_class } else { self.lower_class })
}
}
///|
pub fn BinaryModel::predict_batch(
self : BinaryModel,
rows : Array[Array[Double]],
) -> Result[Array[Int], SvmError] {
let predictions : Array[Int] = []
for row in rows {
match self.predict(row) {
Err(error) => return Err(error)
Ok(value) => predictions.push(value)
}
}
Ok(predictions)
}