コード例 #1
0
ファイル: SolverNu.cs プロジェクト: antlypls/LibSvmSharp
 public override void Solve(int length, QMatrix Q, double[] p, sbyte[] y,
  double[] alpha, double Cp, double Cn, double eps,
  SolutionInfo si, bool shrinking)
 {
     _si = si;
       base.Solve(length, Q, p, y, alpha, Cp, Cn, eps, si, shrinking);
 }
コード例 #2
0
ファイル: Svm.cs プロジェクト: samueldjack/LibSvmSharp
        private static void solve_one_class(SvmProblem prob, SvmParameter param, double[] alpha, SolutionInfo si)
        {
            int l = prob.Lenght;
              double[] zeros = new double[l];
              sbyte[] ones = new sbyte[l];
              int i;

              int n = (int)(param.Nu * prob.Lenght);	// # of alpha's at upper bound

              for (i = 0; i < n; i++)
            alpha[i] = 1;
              if (n < prob.Lenght)
            alpha[n] = param.Nu * prob.Lenght - n;
              for (i = n + 1; i < l; i++)
            alpha[i] = 0;

              for (i = 0; i < l; i++)
              {
            zeros[i] = 0;
            ones[i] = 1;
              }

              var s = new Solver();
              s.Solve(l, new OneClassQ(prob, param), zeros, ones,
            alpha, 1.0, 1.0, param.Eps, si, param.Shrinking);
        }
コード例 #3
0
ファイル: Solver.cs プロジェクト: antlypls/LibSvmSharp
        public virtual void Solve(int length, QMatrix Q, double[] p_, sbyte[] y_,
         double[] alpha_, double Cp, double Cn, double eps, SolutionInfo si, bool shrinking)
        {
            _length = length;
              _q = Q;
              _qd = Q.GetQD();
              _p = (double[]) p_.Clone();
              _y = (sbyte[]) y_.Clone();
              _alpha = (double[]) alpha_.Clone();
              _cp = Cp;
              _cn = Cn;
              _eps = eps;
              _unshrink = false;

              // initialize alpha_status
              _alphaStatus = new BoundType[length];
              for (int i = 0; i < length; i++)
              {
            UpdateAlphaStatus(i);
              }

              // initialize active set (for shrinking)
              _activeSet = new int[length];
              for (int i = 0; i < length; i++)
              {
            _activeSet[i] = i;
              }
              _activeSize = length;

              // initialize gradient
              _g = new double[length];
              _gBar = new double[length];

              for (int i = 0; i < length; i++)
              {
            _g[i] = _p[i];
            _gBar[i] = 0;
              }

              for (int i = 0; i < length; i++)
              {
            if (!IsLowerBound(i))
            {
              double[] Q_i = Q.GetQ(i, length);
              double alpha_i = _alpha[i];

              for (int j = 0; j < length; j++)
              {
            _g[j] += alpha_i * Q_i[j];
              }

              if (IsUpperBound(i))
              {
            for (int j = 0; j < length; j++)
            {
              _gBar[j] += GetC(i) * Q_i[j];
            }
              }
            }
              }

              // optimization step

              int iter = 0;
              int max_iter = Math.Max(10000000, length > int.MaxValue / 100 ? int.MaxValue : 100 * length);
              int counter = Math.Min(length, 1000) + 1;
              int[] working_set = new int[2];

              while (iter < max_iter)
              {
            // show progress and do shrinking

            if (--counter == 0)
            {
              counter = Math.Min(length, 1000);
              if (shrinking) DoShrinking();
              Svm.info(".");
            }

            if (SelectWorkingSet(working_set) != 0)
            {
              // reconstruct the whole gradient
              ReconstructGradient();
              // reset active set size and check
              _activeSize = length;
              Svm.info("*");
              if (SelectWorkingSet(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

            double[] Q_i = Q.GetQ(i, _activeSize);
            double[] Q_j = Q.GetQ(j, _activeSize);

            double C_i = GetC(i);
            double C_j = GetC(j);

            double old_alpha_i = _alpha[i];
            double old_alpha_j = _alpha[j];

            if (_y[i] != _y[j])
            {
              double quad_coef = _qd[i] + _qd[j] + 2*Q_i[j];
              if (quad_coef <= 0)
            quad_coef = 1e-12;
              double delta = (-_g[i] - _g[j])/quad_coef;
              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 quad_coef = _qd[i] + _qd[j] - 2*Q_i[j];
              if (quad_coef <= 0)
            quad_coef = 1e-12;
              double delta = (_g[i] - _g[j])/quad_coef;
              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 < _activeSize; k++)
            {
              _g[k] += Q_i[k]*delta_alpha_i + Q_j[k]*delta_alpha_j;
            }

            // update alpha_status and G_bar
            bool ui = IsUpperBound(i);
            bool uj = IsUpperBound(j);
            UpdateAlphaStatus(i);
            UpdateAlphaStatus(j);
            //int k;
            if (ui != IsUpperBound(i))
            {
              Q_i = Q.GetQ(i, length);
              if (ui)
              {
            for (int k = 0; k < length; k++)
            {
              _gBar[k] -= C_i*Q_i[k];
            }
              }
              else
              {
            for (int k = 0; k < length; k++)
            {
              _gBar[k] += C_i*Q_i[k];
            }
              }
            }

            if (uj != IsUpperBound(j))
            {
              Q_j = Q.GetQ(j, length);
              if (uj)
              {
            for (int k = 0; k < length; k++)
            {
              _gBar[k] -= C_j*Q_j[k];
            }
              }
              else
              {
            for (int k = 0; k < length; k++)
            {
              _gBar[k] += C_j*Q_j[k];
            }
              }
            }
              }

              if (iter >= max_iter)
              {
            if (_activeSize < length)
            {
              // reconstruct the whole gradient to calculate objective value
              ReconstructGradient();
              _activeSize = length;
              Svm.info("*");
            }
            Console.Error.WriteLine("\nWARNING: reaching max number of iterations");
              }

              // calculate rho
              si.Rho = CalculateRho();

              // calculate objective value
              double v = 0;
              for (int i = 0; i < length; i++)
              {
            v += _alpha[i]*(_g[i] + _p[i]);
              }
              si.Obj = v/2;

              // put back the solution
              for (int i = 0; i < length; i++)
              {
            alpha_[_activeSet[i]] = _alpha[i];
              }

              si.UpperBoundP = Cp;
              si.UpperBoundN = Cn;

              Svm.info("\noptimization finished, #iter = " + iter + "\n");
        }
コード例 #4
0
ファイル: Svm.cs プロジェクト: samueldjack/LibSvmSharp
        private static void solve_nu_svc(SvmProblem prob, SvmParameter param, double[] alpha, SolutionInfo si)
        {
            int i;
              int l = prob.Lenght;
              double nu = param.Nu;

              sbyte[] y = new sbyte[l];

              for (i = 0; i < l; i++)
            if (prob.Y[i] > 0)
              y[i] = +1;
            else
              y[i] = -1;

              double sum_pos = nu * l / 2;
              double sum_neg = nu * l / 2;

              for (i = 0; i < l; i++)
            if (y[i] == +1)
            {
              alpha[i] = Math.Min(1.0, sum_pos);
              sum_pos -= alpha[i];
            }
            else
            {
              alpha[i] = Math.Min(1.0, sum_neg);
              sum_neg -= alpha[i];
            }

              double[] zeros = new double[l];

              for (i = 0; i < l; i++)
            zeros[i] = 0;

              var s = new SolverNu();
              s.Solve(l, new SvcQ(prob, param, y), zeros, y,
            alpha, 1.0, 1.0, param.Eps, si, param.Shrinking);
              double r = si.R;

              Svm.info("C = " + 1 / r + "\n");

              for (i = 0; i < l; i++)
            alpha[i] *= y[i] / r;

              si.Rho /= r;
              si.Obj /= (r * r);
              si.UpperBoundP = 1 / r;
              si.UpperBoundN = 1 / r;
        }
コード例 #5
0
ファイル: Svm.cs プロジェクト: samueldjack/LibSvmSharp
        private static void solve_nu_svr(SvmProblem prob, SvmParameter param, double[] alpha, SolutionInfo si)
        {
            int l = prob.Lenght;
              double C = param.C;
              double[] alpha2 = new double[2 * l];
              double[] linear_term = new double[2 * l];
              sbyte[] y = new sbyte[2 * l];
              int i;

              double sum = C * param.Nu * l / 2;
              for (i = 0; i < l; i++)
              {
            alpha2[i] = alpha2[i + l] = Math.Min(sum, C);
            sum -= alpha2[i];

            linear_term[i] = -prob.Y[i];
            y[i] = 1;

            linear_term[i + l] = prob.Y[i];
            y[i + l] = -1;
              }

              var s = new SolverNu();
              s.Solve(2 * l, new SvrQ(prob, param), linear_term, y,
            alpha2, C, C, param.Eps, si, param.Shrinking);

              Svm.info("epsilon = " + (-si.R) + "\n");

              for (i = 0; i < l; i++)
            alpha[i] = alpha2[i] - alpha2[i + l];
        }
コード例 #6
0
ファイル: Svm.cs プロジェクト: samueldjack/LibSvmSharp
        private static void solve_c_svc(SvmProblem prob, SvmParameter param, double[] alpha, SolutionInfo si, double Cp, double Cn)
        {
            int l = prob.Lenght;
              double[] minus_ones = new double[l];
              sbyte[] y = new sbyte[l];

              for (int i = 0; i < l; i++)
              {
            alpha[i] = 0;
            minus_ones[i] = -1;

            if (prob.Y[i] > 0)
            {
              y[i] = +1;
            }
            else
            {
              y[i] = -1;
            }
              }

              Solver s = new Solver();
              s.Solve(l, new SvcQ(prob, param, y), minus_ones, y,
            alpha, Cp, Cn, param.Eps, si, param.Shrinking);

              double sum_alpha = 0;
              for (int i = 0; i < l; i++)
              {
            sum_alpha += alpha[i];
              }

              if (Cp == Cn)
              {
            Svm.info("nu = " + sum_alpha / (Cp * prob.Lenght) + "\n");
              }

              for (int i = 0; i < l; i++)
              {
            alpha[i] *= y[i];
              }
        }
コード例 #7
0
ファイル: Svm.cs プロジェクト: samueldjack/LibSvmSharp
        private static void solve_epsilon_svr(SvmProblem prob, SvmParameter param, double[] alpha, SolutionInfo si)
        {
            int l = prob.Lenght;
              double[] alpha2 = new double[2 * l];
              double[] linear_term = new double[2 * l];
              sbyte[] y = new sbyte[2 * l];
              int i;

              for (i = 0; i < l; i++)
              {
            alpha2[i] = 0;
            linear_term[i] = param.P - prob.Y[i];
            y[i] = 1;

            alpha2[i + l] = 0;
            linear_term[i + l] = param.P + prob.Y[i];
            y[i + l] = -1;
              }

              Solver s = new Solver();
              s.Solve(2 * l, new SvrQ(prob, param), linear_term, y,
            alpha2, param.C, param.C, param.Eps, si, param.Shrinking);

              double sum_alpha = 0;
              for (i = 0; i < l; i++)
              {
            alpha[i] = alpha2[i] - alpha2[i + l];
            sum_alpha += Math.Abs(alpha[i]);
              }
              Svm.info("nu = " + sum_alpha / (param.C * l) + "\n");
        }
コード例 #8
0
ファイル: Solver.cs プロジェクト: FXPAL/LibSvmSharp
        public virtual void Solve(int length, QMatrix Q, double[] p_, sbyte[] y_,
                                  double[] alpha_, double Cp, double Cn, double eps, SolutionInfo si, bool shrinking)
        {
            this._length   = length;
            this._q        = Q;
            _qd            = Q.GetQD();
            _p             = (double[])p_.Clone();
            _y             = (sbyte[])y_.Clone();
            _alpha         = (double[])alpha_.Clone();
            this._cp       = Cp;
            this._cn       = Cn;
            this._eps      = eps;
            this._unshrink = false;

            // initialize alpha_status
            {
                _alphaStatus = new BoundType[length];
                for (int i = 0; i < length; i++)
                {
                    UpdateAlphaStatus(i);
                }
            }

            // initialize active set (for shrinking)
            {
                _activeSet = new int[length];
                for (int i = 0; i < length; i++)
                {
                    _activeSet[i] = i;
                }
                _activeSize = length;
            }

            // initialize gradient
            {
                _g    = new double[length];
                _gBar = new double[length];
                int i;
                for (i = 0; i < length; i++)
                {
                    _g[i]    = _p[i];
                    _gBar[i] = 0;
                }
                for (i = 0; i < length; i++)
                {
                    if (!is_lower_bound(i))
                    {
                        double[] Q_i     = Q.GetQ(i, length);
                        double   alpha_i = _alpha[i];
                        int      j;
                        for (j = 0; j < length; j++)
                        {
                            _g[j] += alpha_i * Q_i[j];
                        }
                        if (is_upper_bound(i))
                        {
                            for (j = 0; j < length; j++)
                            {
                                _gBar[j] += GetC(i) * Q_i[j];
                            }
                        }
                    }
                }
            }

            // optimization step

            int iter     = 0;
            int max_iter = Math.Max(10000000, length > int.MaxValue / 100 ? int.MaxValue : 100 * length);
            int counter  = Math.Min(length, 1000) + 1;

            int[] working_set = new int[2];

            while (iter < max_iter)
            {
                // show progress and do shrinking

                if (--counter == 0)
                {
                    counter = Math.Min(length, 1000);
                    if (shrinking)
                    {
                        do_shrinking();
                    }
                    Svm.info(".");
                }

                if (select_working_set(working_set) != 0)
                {
                    // reconstruct the whole gradient
                    reconstruct_gradient();
                    // reset active set size and check
                    _activeSize = length;
                    Svm.info("*");
                    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

                double[] Q_i = Q.GetQ(i, _activeSize);
                double[] Q_j = Q.GetQ(j, _activeSize);

                double C_i = GetC(i);
                double C_j = GetC(j);

                double old_alpha_i = _alpha[i];
                double old_alpha_j = _alpha[j];

                if (_y[i] != _y[j])
                {
                    double quad_coef = _qd[i] + _qd[j] + 2 * Q_i[j];
                    if (quad_coef <= 0)
                    {
                        quad_coef = 1e-12;
                    }
                    double delta = (-_g[i] - _g[j]) / quad_coef;
                    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 quad_coef = _qd[i] + _qd[j] - 2 * Q_i[j];
                    if (quad_coef <= 0)
                    {
                        quad_coef = 1e-12;
                    }
                    double delta = (_g[i] - _g[j]) / quad_coef;
                    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 < _activeSize; 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);
                UpdateAlphaStatus(i);
                UpdateAlphaStatus(j);
                //int k;
                if (ui != is_upper_bound(i))
                {
                    Q_i = Q.GetQ(i, length);
                    if (ui)
                    {
                        for (int k = 0; k < length; k++)
                        {
                            _gBar[k] -= C_i * Q_i[k];
                        }
                    }
                    else
                    {
                        for (int k = 0; k < length; k++)
                        {
                            _gBar[k] += C_i * Q_i[k];
                        }
                    }
                }

                if (uj != is_upper_bound(j))
                {
                    Q_j = Q.GetQ(j, length);
                    if (uj)
                    {
                        for (int k = 0; k < length; k++)
                        {
                            _gBar[k] -= C_j * Q_j[k];
                        }
                    }
                    else
                    {
                        for (int k = 0; k < length; k++)
                        {
                            _gBar[k] += C_j * Q_j[k];
                        }
                    }
                }
            }

            if (iter >= max_iter)
            {
                if (_activeSize < length)
                {
                    // reconstruct the whole gradient to calculate objective value
                    reconstruct_gradient();
                    _activeSize = length;
                    Svm.info("*");
                }
                Svm.info("\nWARNING: reaching max number of iterations");
            }

            // calculate rho
            si.Rho = calculate_rho();

            // calculate objective value
            double v = 0;

            for (int i = 0; i < length; i++)
            {
                v += _alpha[i] * (_g[i] + _p[i]);
            }
            si.Obj = v / 2;

            // put back the solution
            for (int i = 0; i < length; i++)
            {
                alpha_[_activeSet[i]] = _alpha[i];
            }

            si.UpperBoundP = Cp;
            si.UpperBoundN = Cn;

            Svm.info("\noptimization finished, #iter = " + iter + "\n");
        }
コード例 #9
0
ファイル: Svm.cs プロジェクト: samueldjack/LibSvmSharp
        private static DecisionFunction svm_train_one(SvmProblem prob, SvmParameter param, double Cp, double Cn)
        {
            double[] alpha = new double[prob.Lenght];
              var si = new SolutionInfo();
              switch (param.SvmType)
              {
            case SvmType.C_SVC:
              solve_c_svc(prob, param, alpha, si, Cp, Cn);
              break;
            case SvmType.NU_SVC:
              solve_nu_svc(prob, param, alpha, si);
              break;
            case SvmType.ONE_CLASS:
              solve_one_class(prob, param, alpha, si);
              break;
            case SvmType.EPSILON_SVR:
              solve_epsilon_svr(prob, param, alpha, si);
              break;
            case SvmType.NU_SVR:
              solve_nu_svr(prob, param, alpha, si);
              break;
              }

              Svm.info("obj = " + si.Obj + ", rho = " + si.Rho + "\n");

              // output SVs

              int nSV = 0;
              int nBSV = 0;
              for (int i = 0; i < prob.Lenght; i++)
              {
            if (Math.Abs(alpha[i]) > 0)
            {
              ++nSV;
              if (prob.Y[i] > 0)
              {
            if (Math.Abs(alpha[i]) >= si.UpperBoundP)
              ++nBSV;
              }
              else
              {
            if (Math.Abs(alpha[i]) >= si.UpperBoundN)
              ++nBSV;
              }
            }
              }

              Svm.info("nSV = " + nSV + ", nBSV = " + nBSV + "\n");

              var f = new DecisionFunction(alpha, si.Rho);
              return f;
        }
コード例 #10
0
        private static void solve_nu_svc(SvmProblem prob, SvmParameter param, double[] alpha, SolutionInfo si)
        {
            int    i;
            int    l  = prob.Lenght;
            double nu = param.Nu;

            sbyte[] y = new sbyte[l];

            for (i = 0; i < l; i++)
            {
                if (prob.Y[i] > 0)
                {
                    y[i] = +1;
                }
                else
                {
                    y[i] = -1;
                }
            }

            double sum_pos = nu * l / 2;
            double sum_neg = nu * l / 2;

            for (i = 0; i < l; i++)
            {
                if (y[i] == +1)
                {
                    alpha[i] = Math.Min(1.0, sum_pos);
                    sum_pos -= alpha[i];
                }
                else
                {
                    alpha[i] = Math.Min(1.0, sum_neg);
                    sum_neg -= alpha[i];
                }
            }

            double[] zeros = new double[l];

            for (i = 0; i < l; i++)
            {
                zeros[i] = 0;
            }

            var s = new SolverNu();

            s.Solve(l, new SvcQ(prob, param, y), zeros, y,
                    alpha, 1.0, 1.0, param.Eps, si, param.Shrinking);
            double r = si.R;

            Svm.info("C = " + 1 / r + "\n");

            for (i = 0; i < l; i++)
            {
                alpha[i] *= y[i] / r;
            }

            si.Rho        /= r;
            si.Obj        /= (r * r);
            si.UpperBoundP = 1 / r;
            si.UpperBoundN = 1 / r;
        }
コード例 #11
0
ファイル: svm.cs プロジェクト: geoparsYoti/Sharpkit.Learn
	public virtual void Solve(int l, QMatrix Q, double[] p_, sbyte[] y_,
		   double[] alpha_, double Cp, double Cn, double eps, SolutionInfo si, int shrinking)
	{
		this.l = l;
		this.Q = Q;
		QD = Q.get_QD();
		p = (double[])p_.Clone();
		y = (sbyte[])y_.Clone();
		alpha = (double[])alpha_.Clone();
		this.Cp = Cp;
		this.Cn = Cn;
		this.eps = eps;
		this.unshrink = 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] = p[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 max_iter = Math.Max(10000000, l>int.MaxValue/100 ? int.MaxValue : 100*l);
		int counter = Math.Min(l,1000)+1;
		int[] working_set = new int[2];

		while(iter < max_iter)
		{
			// show progress and do shrinking

			if(--counter == 0)
			{
				counter = Math.Min(l,1000);
				if(shrinking!=0) do_shrinking();
				svm.info(".");
			}

			if(select_working_set(working_set)!=0)
			{
				// reconstruct the whole gradient
				reconstruct_gradient();
				// reset active set size and check
				active_size = l;
				svm.info("*");
				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 quad_coef = QD[i]+QD[j]+2*Q_i[j];
				if (quad_coef <= 0)
					quad_coef = 1e-12;
				double delta = (-G[i]-G[j])/quad_coef;
				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 quad_coef = QD[i]+QD[j]-2*Q_i[j];
				if (quad_coef <= 0)
					quad_coef = 1e-12;
				double delta = (G[i]-G[j])/quad_coef;
				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];
				}
			}

		}
		
		if(iter >= max_iter)
		{
			if(active_size < l)
			{
				// reconstruct the whole gradient to calculate objective value
				reconstruct_gradient();
				active_size = l;
				svm.info("*");
			}
			Console.Error.Write("\nWARNING: reaching max number of iterations\n");
		}

		// 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] + p[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;

		svm.info("\noptimization finished, #iter = "+iter+"\n");
	}
コード例 #12
0
        private static void solve_c_svc(SvmProblem prob, SvmParameter param, double[] alpha, SolutionInfo si, double Cp, double Cn)
        {
            int l = prob.Lenght;

            double[] minus_ones = new double[l];
            sbyte[]  y          = new sbyte[l];

            for (int i = 0; i < l; i++)
            {
                alpha[i]      = 0;
                minus_ones[i] = -1;

                if (prob.Y[i] > 0)
                {
                    y[i] = +1;
                }
                else
                {
                    y[i] = -1;
                }
            }

            Solver s = new Solver();

            s.Solve(l, new SvcQ(prob, param, y), minus_ones, y,
                    alpha, Cp, Cn, param.Eps, si, param.Shrinking);

            double sum_alpha = 0;

            for (int i = 0; i < l; i++)
            {
                sum_alpha += alpha[i];
            }

            if (Cp == Cn)
            {
                Svm.info("nu = " + sum_alpha / (Cp * prob.Lenght) + "\n");
            }

            for (int i = 0; i < l; i++)
            {
                alpha[i] *= y[i];
            }
        }
コード例 #13
0
        private static DecisionFunction svm_train_one(SvmProblem prob, SvmParameter param, double Cp, double Cn)
        {
            double[] alpha = new double[prob.Lenght];
            var      si    = new SolutionInfo();

            switch (param.SvmType)
            {
            case SvmType.C_SVC:
                solve_c_svc(prob, param, alpha, si, Cp, Cn);
                break;

            case SvmType.NU_SVC:
                solve_nu_svc(prob, param, alpha, si);
                break;

            case SvmType.ONE_CLASS:
                solve_one_class(prob, param, alpha, si);
                break;

            case SvmType.EPSILON_SVR:
                solve_epsilon_svr(prob, param, alpha, si);
                break;

            case SvmType.NU_SVR:
                solve_nu_svr(prob, param, alpha, si);
                break;
            }

            Svm.info("obj = " + si.Obj + ", rho = " + si.Rho + "\n");

            // output SVs

            int nSV  = 0;
            int nBSV = 0;

            for (int i = 0; i < prob.Lenght; i++)
            {
                if (Math.Abs(alpha[i]) > 0)
                {
                    ++nSV;
                    if (prob.Y[i] > 0)
                    {
                        if (Math.Abs(alpha[i]) >= si.UpperBoundP)
                        {
                            ++nBSV;
                        }
                    }
                    else
                    {
                        if (Math.Abs(alpha[i]) >= si.UpperBoundN)
                        {
                            ++nBSV;
                        }
                    }
                }
            }

            Svm.info("nSV = " + nSV + ", nBSV = " + nBSV + "\n");

            var f = new DecisionFunction(alpha, si.Rho);

            return(f);
        }
コード例 #14
0
        private static void solve_nu_svr(SvmProblem prob, SvmParameter param, double[] alpha, SolutionInfo si)
        {
            int    l = prob.Lenght;
            double C = param.C;

            double[] alpha2      = new double[2 * l];
            double[] linear_term = new double[2 * l];
            sbyte[]  y           = new sbyte[2 * l];
            int      i;

            double sum = C * param.Nu * l / 2;

            for (i = 0; i < l; i++)
            {
                alpha2[i] = alpha2[i + l] = Math.Min(sum, C);
                sum      -= alpha2[i];

                linear_term[i] = -prob.Y[i];
                y[i]           = 1;

                linear_term[i + l] = prob.Y[i];
                y[i + l]           = -1;
            }

            var s = new SolverNu();

            s.Solve(2 * l, new SvrQ(prob, param), linear_term, y,
                    alpha2, C, C, param.Eps, si, param.Shrinking);

            Svm.info("epsilon = " + (-si.R) + "\n");

            for (i = 0; i < l; i++)
            {
                alpha[i] = alpha2[i] - alpha2[i + l];
            }
        }
コード例 #15
0
        private static void solve_epsilon_svr(SvmProblem prob, SvmParameter param, double[] alpha, SolutionInfo si)
        {
            int l = prob.Lenght;

            double[] alpha2      = new double[2 * l];
            double[] linear_term = new double[2 * l];
            sbyte[]  y           = new sbyte[2 * l];
            int      i;

            for (i = 0; i < l; i++)
            {
                alpha2[i]      = 0;
                linear_term[i] = param.P - prob.Y[i];
                y[i]           = 1;

                alpha2[i + l]      = 0;
                linear_term[i + l] = param.P + prob.Y[i];
                y[i + l]           = -1;
            }

            Solver s = new Solver();

            s.Solve(2 * l, new SvrQ(prob, param), linear_term, y,
                    alpha2, param.C, param.C, param.Eps, si, param.Shrinking);

            double sum_alpha = 0;

            for (i = 0; i < l; i++)
            {
                alpha[i]   = alpha2[i] - alpha2[i + l];
                sum_alpha += Math.Abs(alpha[i]);
            }
            Svm.info("nu = " + sum_alpha / (param.C * l) + "\n");
        }
コード例 #16
0
        private static void solve_one_class(SvmProblem prob, SvmParameter param, double[] alpha, SolutionInfo si)
        {
            int l = prob.Lenght;

            double[] zeros = new double[l];
            sbyte[]  ones  = new sbyte[l];
            int      i;

            int n = (int)(param.Nu * prob.Lenght); // # of alpha's at upper bound

            for (i = 0; i < n; i++)
            {
                alpha[i] = 1;
            }
            if (n < prob.Lenght)
            {
                alpha[n] = param.Nu * prob.Lenght - n;
            }
            for (i = n + 1; i < l; i++)
            {
                alpha[i] = 0;
            }

            for (i = 0; i < l; i++)
            {
                zeros[i] = 0;
                ones[i]  = 1;
            }

            var s = new Solver();

            s.Solve(l, new OneClassQ(prob, param), zeros, ones,
                    alpha, 1.0, 1.0, param.Eps, si, param.Shrinking);
        }