predict method

  1. @override
int predict(
  1. List<double> X
)
override

Implementation of sklearn.svm.SVC.predict.

Implementation

@override
int predict(List<double> X) {
  List<double> kernels;
  List<int> starts = List<int>.filled(classes.length, 0);
  List<int> ends = List.generate(classes.length, ((index) => index));
  if (kernel == "rbf")
    kernels = rbf(X);
  else if (kernel == "linear")
    kernels = linear(X);
  else if (kernel == "sigmoid")
    kernels = sigmoid(X);
  else if (kernel == "poly")
    kernels = sigmoid(X);
  else
    throw InvalidSVMKernelException(
        "Unsupported kernel $kernel, supported are: ${_supported.join(", ")}");

  for (int i = 1; i < classes.length; i++) {
    int start = 0;
    for (int j = 0; j < i; j++) {
      final e = nSupport[j];
      if (e is String) {
        start += int.parse(e);
      } else if (e is int) {
        start += e;
      }
    }
    starts[i] = start;
  }
  classes.asMap().forEach((i, v) => ends[i] = nSupport[i] + starts[i]);

  if (classes.length == 2) {
    for (int i = 0; i < kernels.length; i++) {
      kernels[i] = -kernels[i];
    }

    double decision = 0.0;
    for (int k = starts[1]; k < ends[1]; k++) {
      decision += kernels[k] * dualCoef[0][k];
    }
    for (int k = starts[0]; k < ends[0]; k++) {
      decision += kernels[k] * dualCoef[0][k];
    }
    decision += intercept[0];
  }

  List<double> decisions = List.generate(
    intercept.length,
    ((index) => index.toDouble()),
  );
  for (int i = 0, d = 0, l = classes.length; i < l; i++) {
    for (int j = i + 1; j < l; j++) {
      double tmp = 0.0;
      for (int k = starts[j]; k < ends[j]; k++) {
        tmp += dualCoef[i][k] * kernels[k];
      }
      for (int k = starts[i]; k < ends[i]; k++) {
        tmp += dualCoef[j - 1][k] * kernels[k];
      }
      decisions[d] = tmp + intercept[d];
      d++;
    }
  }

  List<int> votes = List.generate(intercept.length, (index) => index);
  for (int i = 0, d = 0, l = classes.length; i < l; i++) {
    for (int j = i + 1; j < l; j++) {
      votes[d] = decisions[d] > 0 ? i : j;
      d++;
    }
  }
  List<int> amounts = List<int>.filled(classes.length, 0);
  votes.asMap().forEach((i, v) => amounts[votes[i]] += 1);

  int classVal = -1;
  int idx = -1;
  for (int i = 0, l = amounts.length; i < l; i++) {
    if (amounts[i] > classVal) {
      classVal = amounts[i];
      idx = i;
    }
  }

  return classes[idx];
}