/// <summary> /// Default SVM /// </summary> /// <remarks>The class store svm parameters and create the model. /// This way, you can use it to predict</remarks> public SVM(svm_problem prob, int svm_type, Kernel kernel, double C, double nu, double cache_size, double eps, double p, int shrinking, int probability, int nr_weight, int[] weight_label, double[] weight) : this(prob, new svm_parameter() { svm_type = svm_type, kernel_type = (int)kernel.KernelType, degree = kernel.Degree, C = C, gamma = kernel.Gamma, coef0 = kernel.R, nu = nu, cache_size = cache_size, eps = eps, p = p, shrinking = shrinking, probability = probability, nr_weight = nr_weight, weight_label = weight_label, weight = weight, }) { }
/// <summary> /// Classification SVM /// Supports multi-class classification /// </summary> /// <param name="input_file_name">Path to the training data set file. Has respect the libsvm format</param> /// <param name="kernel">Selected Kernel</param> /// <param name="C">Cost parameter </param> /// <param name="cache_size">Indicates the maximum memory that can use the program</param> public C_SVC(string input_file_name, Kernel kernel, double C, double cache_size = 100) : this(ProblemHelper.ReadProblem(input_file_name), kernel, C, cache_size) { }
/// <summary> /// Classification SVM /// Supports multi-class classification /// </summary> /// <param name="prob">Training Data Set</param> /// <param name="kernel">Selected Kernel</param> /// <param name="C">Cost parameter </param> /// <param name="cache_size">Indicates the maximum memory that can use the program</param> public C_SVC(svm_problem prob, Kernel kernel, double C, double cache_size = 100) : base(SvmType.C_SVC, prob, kernel, C, cache_size) { }
internal override void Solve(int l, Kernel Q, double[] b, sbyte[] y, double[] alpha, double Cp, double Cn, double eps, SolutionInfo si, int shrinking) { this.si = si; base.Solve(l, Q, b, y, alpha, Cp, Cn, eps, si, shrinking); }
internal virtual void Solve(int l, Kernel Q, double[] b_, sbyte[] y_, double[] alpha_, double Cp, double Cn, double eps, SolutionInfo si, int shrinking) { this.l = l; this.Q = Q; b = new double[b_.Length]; b_.CopyTo(b, 0); y = new sbyte[y_.Length]; y_.CopyTo(y, 0); alpha = new double[alpha_.Length]; alpha_.CopyTo(alpha, 0); this.Cp = Cp; this.Cn = Cn; this.eps = eps; this.unshrinked = false; // initialize alpha_status { alpha_status = new sbyte[l]; for (int i = 0; i < l; i++) update_alpha_status(i); } // initialize active set (for shrinking) { active_set = new int[l]; for (int i = 0; i < l; i++) active_set[i] = i; active_size = l; } // initialize gradient { G = new double[l]; G_bar = new double[l]; int i; for (i = 0; i < l; i++) { G[i] = b[i]; G_bar[i] = 0; } for (i = 0; i < l; i++) if (!is_lower_bound(i)) { float[] Q_i = Q.get_Q(i, l); double alpha_i = alpha[i]; int j; for (j = 0; j < l; j++) G[j] += alpha_i * Q_i[j]; if (is_upper_bound(i)) for (j = 0; j < l; j++) G_bar[j] += get_C(i) * Q_i[j]; } } // optimization step int iter = 0; int counter = System.Math.Min(l, 1000) + 1; int[] working_set = new int[2]; while (true) { // show progress and do shrinking if (--counter == 0) { counter = System.Math.Min(l, 1000); if (shrinking != 0) do_shrinking(); System.Console.Error.Write("."); } if (select_working_set(working_set) != 0) { // reconstruct the whole gradient reconstruct_gradient(); // reset active set size and check active_size = l; System.Console.Error.Write("*"); if (select_working_set(working_set) != 0) break; else counter = 1; // do shrinking next iteration } int i = working_set[0]; int j = working_set[1]; ++iter; // update alpha[i] and alpha[j], handle bounds carefully float[] Q_i = Q.get_Q(i, active_size); float[] Q_j = Q.get_Q(j, active_size); double C_i = get_C(i); double C_j = get_C(j); double old_alpha_i = alpha[i]; double old_alpha_j = alpha[j]; if (y[i] != y[j]) { double delta = (- G[i] - G[j]) / System.Math.Max(Q_i[i] + Q_j[j] + 2 * Q_i[j], (float) 0); double diff = alpha[i] - alpha[j]; alpha[i] += delta; alpha[j] += delta; if (diff > 0) { if (alpha[j] < 0) { alpha[j] = 0; alpha[i] = diff; } } else { if (alpha[i] < 0) { alpha[i] = 0; alpha[j] = - diff; } } if (diff > C_i - C_j) { if (alpha[i] > C_i) { alpha[i] = C_i; alpha[j] = C_i - diff; } } else { if (alpha[j] > C_j) { alpha[j] = C_j; alpha[i] = C_j + diff; } } } else { double delta = (G[i] - G[j]) / System.Math.Max(Q_i[i] + Q_j[j] - 2 * Q_i[j], (float) 0); double sum = alpha[i] + alpha[j]; alpha[i] -= delta; alpha[j] += delta; if (sum > C_i) { if (alpha[i] > C_i) { alpha[i] = C_i; alpha[j] = sum - C_i; } } else { if (alpha[j] < 0) { alpha[j] = 0; alpha[i] = sum; } } if (sum > C_j) { if (alpha[j] > C_j) { alpha[j] = C_j; alpha[i] = sum - C_j; } } else { if (alpha[i] < 0) { alpha[i] = 0; alpha[j] = sum; } } } // update G double delta_alpha_i = alpha[i] - old_alpha_i; double delta_alpha_j = alpha[j] - old_alpha_j; for (int k = 0; k < active_size; k++) { G[k] += Q_i[k] * delta_alpha_i + Q_j[k] * delta_alpha_j; } // update alpha_status and G_bar { bool ui = is_upper_bound(i); bool uj = is_upper_bound(j); update_alpha_status(i); update_alpha_status(j); int k; if (ui != is_upper_bound(i)) { Q_i = Q.get_Q(i, l); if (ui) for (k = 0; k < l; k++) G_bar[k] -= C_i * Q_i[k]; else for (k = 0; k < l; k++) G_bar[k] += C_i * Q_i[k]; } if (uj != is_upper_bound(j)) { Q_j = Q.get_Q(j, l); if (uj) for (k = 0; k < l; k++) G_bar[k] -= C_j * Q_j[k]; else for (k = 0; k < l; k++) G_bar[k] += C_j * Q_j[k]; } } } // calculate rho si.rho = calculate_rho(); // calculate objective value { double v = 0; int i; for (i = 0; i < l; i++) v += alpha[i] * (G[i] + b[i]); si.obj = v / 2; } // put back the solution { for (int i = 0; i < l; i++) alpha_[active_set[i]] = alpha[i]; } si.upper_bound_p = Cp; si.upper_bound_n = Cn; //Debug.WriteLine("\noptimization finished, #iter = " + iter + "\n"); }
/// <summary> /// Read and scale inputs, create and train the Epsilon_SVR /// </summary> /// <param name="input_file_name">Training file path</param> /// <param name="kernel">Selected Kernel</param> /// <param name="probability">Specify if probability are needed</param> /// <param name="cache_size">Indicates the maximum memory that can use the program</param> public Epsilon_SVR(string input_file_name, Kernel kernel, double C, double epsilon, bool probability = true, double cache_size = 100) : this(ProblemHelper.ReadAndScaleProblem(input_file_name), kernel, C, epsilon, probability, cache_size) { }
/// <summary> /// Create and train the Epsilon_SV /// </summary> /// <param name="prob">Training Data Set</param> /// <param name="kernel">Selected Kernel</param> /// <param name="probability">Specify if probability are needed</param> /// <param name="cache_size">Indicates the maximum memory that can use the program</param> public Epsilon_SVR(svm_problem prob, Kernel kernel, double C, double epsilon, bool probability = true, double cache_size = 100) : base(SvmType.EPSILON_SVR, prob, kernel, C, epsilon, probability, cache_size) { }
public SVR(SvmType svm_type, svm_problem prob, Kernel kernel, double C, double eps, bool probability, double cache_size) : base(prob, (int)svm_type, kernel, C, 0.0, cache_size, 1e-3, 0.1, 1, probability? 1: 0, 0, new int[0], new double[0]) { }
public SVC(SvmType svm_type, svm_problem prob, Kernel kernel, double C, double cache_size = 100, int probability = 0) : base(prob, (int)svm_type, kernel, C, 0.0, cache_size, 1e-3, 0.1, 1, probability, 0, new int[0], new double[0]) { }