示例#1
0
    public static double k_function(svm_node[] x, svm_node[] y,
            svm_parameter param) {
      switch (param.kernel_type) {
        case svm_parameter.LINEAR:
          return dot(x, y);
        case svm_parameter.POLY:
          return powi(param.gamma * dot(x, y) + param.coef0, param.degree);
        case svm_parameter.RBF: {
            double sum = 0;
            int xlen = x.Length;
            int ylen = y.Length;
            int i = 0;
            int j = 0;
            while (i < xlen && j < ylen) {
              if (x[i].index == y[j].index) {
                double d = x[i++].value - y[j++].value;
                sum += d * d;
              } else if (x[i].index > y[j].index) {
                sum += y[j].value * y[j].value;
                ++j;
              } else {
                sum += x[i].value * x[i].value;
                ++i;
              }
            }

            while (i < xlen) {
              sum += x[i].value * x[i].value;
              ++i;
            }

            while (j < ylen) {
              sum += y[j].value * y[j].value;
              ++j;
            }

            return Math.Exp(-param.gamma * sum);
          }
        case svm_parameter.SIGMOID:
          return Math.Tanh(param.gamma * dot(x, y) + param.coef0);
        case svm_parameter.PRECOMPUTED:
          return x[(int)(y[0].value)].value;
        default:
          return 0;	// java
      }
    }
示例#2
0
 public object Clone() {
   var clone = new svm_node();
   clone.index = index;
   clone.value = value;
   return clone;
 }
示例#3
0
    public static double svm_predict_probability(svm_model model, svm_node[] x, double[] prob_estimates) {
      if ((model.param.svm_type == svm_parameter.C_SVC || model.param.svm_type == svm_parameter.NU_SVC) &&
          model.probA != null && model.probB != null) {
        int i;
        int nr_class = model.nr_class;
        double[] dec_values = new double[nr_class * (nr_class - 1) / 2];
        svm_predict_values(model, x, dec_values);

        double min_prob = 1e-7;
        double[][] pairwise_prob = new double[nr_class][];

        int k = 0;
        for (i = 0; i < nr_class; i++)
          pairwise_prob[i] = new double[nr_class];
        for (int j = i + 1; j < nr_class; j++) {
          pairwise_prob[i][j] =
            Math.Min(Math.Max(sigmoid_predict(dec_values[k], model.probA[k], model.probB[k]), min_prob), 1 - min_prob);
          pairwise_prob[j][i] = 1 - pairwise_prob[i][j];
          k++;
        }
        multiclass_probability(nr_class, pairwise_prob, prob_estimates);

        int prob_max_idx = 0;
        for (i = 1; i < nr_class; i++)
          if (prob_estimates[i] > prob_estimates[prob_max_idx])
            prob_max_idx = i;
        return model.label[prob_max_idx];
      } else
        return svm_predict(model, x);
    }
示例#4
0
 static double dot(svm_node[] x, svm_node[] y) {
   double sum = 0;
   int xlen = x.Length;
   int ylen = y.Length;
   int i = 0;
   int j = 0;
   while (i < xlen && j < ylen) {
     if (x[i].index == y[j].index)
       sum += x[i++].value * y[j++].value;
     else {
       if (x[i].index > y[j].index)
         ++j;
       else
         ++i;
     }
   }
   return sum;
 }
示例#5
0
 public static double svm_predict(svm_model model, svm_node[] x) {
   int nr_class = model.nr_class;
   double[] dec_values;
   if (model.param.svm_type == svm_parameter.ONE_CLASS ||
       model.param.svm_type == svm_parameter.EPSILON_SVR ||
       model.param.svm_type == svm_parameter.NU_SVR)
     dec_values = new double[1];
   else
     dec_values = new double[nr_class * (nr_class - 1) / 2];
   double pred_result = svm_predict_values(model, x, dec_values);
   return pred_result;
 }
示例#6
0
    public static double svm_predict_values(svm_model model, svm_node[] x, double[] dec_values) {
      int i;
      if (model.param.svm_type == svm_parameter.ONE_CLASS ||
          model.param.svm_type == svm_parameter.EPSILON_SVR ||
          model.param.svm_type == svm_parameter.NU_SVR) {
        double[] sv_coef = model.sv_coef[0];
        double sum = 0;
        for (i = 0; i < model.l; i++)
          sum += sv_coef[i] * Kernel.k_function(x, model.SV[i], model.param);
        sum -= model.rho[0];
        dec_values[0] = sum;

        if (model.param.svm_type == svm_parameter.ONE_CLASS)
          return (sum > 0) ? 1 : -1;
        else
          return sum;
      } else {
        int nr_class = model.nr_class;
        int l = model.l;

        double[] kvalue = new double[l];
        for (i = 0; i < l; i++)
          kvalue[i] = Kernel.k_function(x, model.SV[i], model.param);

        int[] start = new int[nr_class];
        start[0] = 0;
        for (i = 1; i < nr_class; i++)
          start[i] = start[i - 1] + model.nSV[i - 1];

        int[] vote = new int[nr_class];
        for (i = 0; i < nr_class; i++)
          vote[i] = 0;

        int p = 0;
        for (i = 0; i < nr_class; i++)
          for (int j = i + 1; j < nr_class; j++) {
            double sum = 0;
            int si = start[i];
            int sj = start[j];
            int ci = model.nSV[i];
            int cj = model.nSV[j];

            int k;
            double[] coef1 = model.sv_coef[j - 1];
            double[] coef2 = model.sv_coef[i];
            for (k = 0; k < ci; k++)
              sum += coef1[si + k] * kvalue[si + k];
            for (k = 0; k < cj; k++)
              sum += coef2[sj + k] * kvalue[sj + k];
            sum -= model.rho[p];
            dec_values[p] = sum;

            if (dec_values[p] > 0)
              ++vote[i];
            else
              ++vote[j];
            p++;
          }

        int vote_max_idx = 0;
        for (i = 1; i < nr_class; i++)
          if (vote[i] > vote[vote_max_idx])
            vote_max_idx = i;

        return model.label[vote_max_idx];
      }
    }
示例#7
0
    public Kernel(int l, svm_node[][] x_, svm_parameter param) {
      this.kernel_type = param.kernel_type;
      this.degree = param.degree;
      this.gamma = param.gamma;
      this.coef0 = param.coef0;

      x = (svm_node[][])x_.Clone();

      if (kernel_type == svm_parameter.RBF) {
        x_square = new double[l];
        for (int i = 0; i < l; i++)
          x_square[i] = dot(x[i], x[i]);
      } else x_square = null;
    }
示例#8
0
    //
    // Interface functions
    //
    public static svm_model svm_train(svm_problem prob, svm_parameter param) {
      svm_model model = new svm_model();
      model.param = param;

      if (param.svm_type == svm_parameter.ONE_CLASS ||
          param.svm_type == svm_parameter.EPSILON_SVR ||
          param.svm_type == svm_parameter.NU_SVR) {
        // regression or one-class-svm
        model.nr_class = 2;
        model.label = null;
        model.nSV = null;
        model.probA = null;
        model.probB = null;
        model.sv_coef = new double[1][];

        if (param.probability == 1 &&
            (param.svm_type == svm_parameter.EPSILON_SVR ||
             param.svm_type == svm_parameter.NU_SVR)) {
          model.probA = new double[1];
          model.probA[0] = svm_svr_probability(prob, param);
        }

        decision_function f = svm_train_one(prob, param, 0, 0);
        model.rho = new double[1];
        model.rho[0] = f.rho;

        int nSV = 0;
        int i;
        for (i = 0; i < prob.l; i++)
          if (Math.Abs(f.alpha[i]) > 0) ++nSV;
        model.l = nSV;
        model.SV = new svm_node[nSV][];
        model.sv_coef[0] = new double[nSV];
        int j = 0;
        for (i = 0; i < prob.l; i++)
          if (Math.Abs(f.alpha[i]) > 0) {
            model.SV[j] = prob.x[i];
            model.sv_coef[0][j] = f.alpha[i];
            ++j;
          }
      } else {
        // classification
        int l = prob.l;
        int[] tmp_nr_class = new int[1];
        int[][] tmp_label = new int[1][];
        int[][] tmp_start = new int[1][];
        int[][] tmp_count = new int[1][];
        int[] perm = new int[l];

        // group training data of the same class
        svm_group_classes(prob, tmp_nr_class, tmp_label, tmp_start, tmp_count, perm);
        int nr_class = tmp_nr_class[0];
        int[] label = tmp_label[0];
        int[] start = tmp_start[0];
        int[] count = tmp_count[0];

        if (nr_class == 1)
          svm.info("WARNING: training data in only one class. See README for details." + Environment.NewLine);

        svm_node[][] x = new svm_node[l][];
        int i;
        for (i = 0; i < l; i++)
          x[i] = prob.x[perm[i]];

        // calculate weighted C

        double[] weighted_C = new double[nr_class];
        for (i = 0; i < nr_class; i++)
          weighted_C[i] = param.C;
        for (i = 0; i < param.nr_weight; i++) {
          int j;
          for (j = 0; j < nr_class; j++)
            if (param.weight_label[i] == label[j])
              break;
          if (j == nr_class)
            Console.Error.WriteLine("WARNING: class label " + param.weight_label[i] +
                                    " specified in weight is not found");
          else
            weighted_C[j] *= param.weight[i];
        }

        // train k*(k-1)/2 models

        bool[] nonzero = new bool[l];
        for (i = 0; i < l; i++)
          nonzero[i] = false;
        decision_function[] f = new decision_function[nr_class * (nr_class - 1) / 2];

        double[] probA = null, probB = null;
        if (param.probability == 1) {
          probA = new double[nr_class * (nr_class - 1) / 2];
          probB = new double[nr_class * (nr_class - 1) / 2];
        }

        int p = 0;
        for (i = 0; i < nr_class; i++)
          for (int j = i + 1; j < nr_class; j++) {
            svm_problem sub_prob = new svm_problem();
            int si = start[i], sj = start[j];
            int ci = count[i], cj = count[j];
            sub_prob.l = ci + cj;
            sub_prob.x = new svm_node[sub_prob.l][];
            sub_prob.y = new double[sub_prob.l];
            int k;
            for (k = 0; k < ci; k++) {
              sub_prob.x[k] = x[si + k];
              sub_prob.y[k] = +1;
            }
            for (k = 0; k < cj; k++) {
              sub_prob.x[ci + k] = x[sj + k];
              sub_prob.y[ci + k] = -1;
            }

            if (param.probability == 1) {
              double[] probAB = new double[2];
              svm_binary_svc_probability(sub_prob, param, weighted_C[i], weighted_C[j], probAB);
              probA[p] = probAB[0];
              probB[p] = probAB[1];
            }

            f[p] = svm_train_one(sub_prob, param, weighted_C[i], weighted_C[j]);
            for (k = 0; k < ci; k++)
              if (!nonzero[si + k] && Math.Abs(f[p].alpha[k]) > 0)
                nonzero[si + k] = true;
            for (k = 0; k < cj; k++)
              if (!nonzero[sj + k] && Math.Abs(f[p].alpha[ci + k]) > 0)
                nonzero[sj + k] = true;
            ++p;
          }

        // build output

        model.nr_class = nr_class;

        model.label = new int[nr_class];
        for (i = 0; i < nr_class; i++)
          model.label[i] = label[i];

        model.rho = new double[nr_class * (nr_class - 1) / 2];
        for (i = 0; i < nr_class * (nr_class - 1) / 2; i++)
          model.rho[i] = f[i].rho;

        if (param.probability == 1) {
          model.probA = new double[nr_class * (nr_class - 1) / 2];
          model.probB = new double[nr_class * (nr_class - 1) / 2];
          for (i = 0; i < nr_class * (nr_class - 1) / 2; i++) {
            model.probA[i] = probA[i];
            model.probB[i] = probB[i];
          }
        } else {
          model.probA = null;
          model.probB = null;
        }

        int nnz = 0;
        int[] nz_count = new int[nr_class];
        model.nSV = new int[nr_class];
        for (i = 0; i < nr_class; i++) {
          int nSV = 0;
          for (int j = 0; j < count[i]; j++)
            if (nonzero[start[i] + j]) {
              ++nSV;
              ++nnz;
            }
          model.nSV[i] = nSV;
          nz_count[i] = nSV;
        }

        svm.info("Total nSV = " + nnz + Environment.NewLine);

        model.l = nnz;
        model.SV = new svm_node[nnz][];
        p = 0;
        for (i = 0; i < l; i++)
          if (nonzero[i]) model.SV[p++] = x[i];

        int[] nz_start = new int[nr_class];
        nz_start[0] = 0;
        for (i = 1; i < nr_class; i++)
          nz_start[i] = nz_start[i - 1] + nz_count[i - 1];

        model.sv_coef = new double[nr_class - 1][];
        for (i = 0; i < nr_class - 1; i++)
          model.sv_coef[i] = new double[nnz];

        p = 0;
        for (i = 0; i < nr_class; i++)
          for (int j = i + 1; j < nr_class; j++) {
            // classifier (i,j): coefficients with
            // i are in sv_coef[j-1][nz_start[i]...],
            // j are in sv_coef[i][nz_start[j]...]

            int si = start[i];
            int sj = start[j];
            int ci = count[i];
            int cj = count[j];

            int q = nz_start[i];
            int k;
            for (k = 0; k < ci; k++)
              if (nonzero[si + k])
                model.sv_coef[j - 1][q++] = f[p].alpha[k];
            q = nz_start[j];
            for (k = 0; k < cj; k++)
              if (nonzero[sj + k])
                model.sv_coef[i][q++] = f[p].alpha[ci + k];
            ++p;
          }
      }
      return model;
    }
示例#9
0
 /// <summary>
 /// Transforms the input array based upon the values provided.
 /// </summary>
 /// <param name="input">The input array</param>
 /// <returns>A scaled array</returns>
 public svm_node[] Transform(svm_node[] input) {
   svm_node[] output = new svm_node[input.Length];
   for (int i = 0; i < output.Length; i++) {
     int index = input[i].index;
     double value = input[i].value;
     output[i] = new svm_node() { index = index, value = Transform(value, index) };
   }
   return output;
 }