DataSharp/Data/Analysis/SupportVectorMachine.cs
/// <summary>
/// Selects 2nd lagrange multiplier and updates them.
/// </summary>
/// <param name="i"></param>
/// <param name="epsilon"></param>
/// <returns></returns>
Selects 2nd lagrange multiplier and updates them.
Selects 2nd lagrange multiplier and updates them .
private int InnerLoop(int i, double epsilon = 0.00001)
        {
            double errorI = CalculateError(i);
            if (((labels[i] * errorI < -tolerance) && (alphas[i] < C)) ||
                ((labels[i] * errorI > tolerance) && (alphas[i] > 0)))
            {
                int j = Select2ndMultiplier(i, errorI, out double errorJ);
                double alphaIOld = alphas[i];
                double alphaJOld = alphas[j];
                double upperLimit;
                double lowerLimit;
                if (labels[i] != labels[j])
                {
                    upperLimit = Math.Max(0, alphas[j] - alphas[i]);
                    lowerLimit = Math.Min(C, C + alphas[j] - alphas[i]);
                }
                else
                {
                    upperLimit = Math.Max(0, alphas[j] + alphas[i] - C);
                    lowerLimit = Math.Min(C, alphas[j] + alphas[i]);
                }
                if (Math.Abs(upperLimit - lowerLimit) < double.Epsilon)
                    return 0;
                Vector ithRow = dataMatrix.GetRow(i);
                Vector jthRow = dataMatrix.GetRow(j);
                double k11 = kernelValues[i, i];
                double k12 = kernelValues[i, j];
                double k22 = kernelValues[j, j];
                double eta = k11 + k22 - 2 * k12;
                if (eta <= 0)
                    return 0;
                alphas[j] = alphaJOld + labels[j] * (errorI - errorJ) / eta;
                alphas[j] = Clip(alphas[j], upperLimit, lowerLimit);
                UpdateError(j);
                if (Math.Abs(alphas[j] - alphaJOld) < epsilon)
                    return 0;
                alphas[i] = alphaIOld + labels[i] * labels[j] * (alphaJOld - alphas[j]);
                UpdateError(i);
                double b1 = bias - errorI - labels[i] * (alphas[i] - alphaIOld) * k11 - labels[j] * (alphas[j] - alphaJOld) * k12;
                double b2 = bias - errorJ - labels[i] * (alphas[i] - alphaIOld) * k12 - labels[j] * (alphas[j] - alphaJOld) * k22;
                if ((0 < alphas[i]) && (alphas[i] < C))
                    bias = b1;
                else if ((0 < alphas[j]) && (alphas[j] < C))
                    bias = 2;
                else
                    bias = (b1 + b2) / 2;
                return 1;
            }
            else
                return 0;
        }
private int InnerLoop ( int i , double epsilon = 0.00001 ) { double errorI = CalculateError ( i ) ; if ( ( ( labels [ i ] * errorI < - tolerance ) && ( alphas [ i ] < C ) ) || ( ( labels [ i ] * errorI > tolerance ) && ( alphas [ i ] > 0 ) ) ) { int j = Select2ndMultiplier ( i , errorI , out double errorJ ) ; double alphaIOld = alphas [ i ] ; double alphaJOld = alphas [ j ] ; double upperLimit ; double lowerLimit ; if ( labels [ i ] != labels [ j ] ) { upperLimit = Math . Max ( 0 , alphas [ j ] - alphas [ i ] ) ; lowerLimit = Math . Min ( C , C + alphas [ j ] - alphas [ i ] ) ; } else { upperLimit = Math . Max ( 0 , alphas [ j ] + alphas [ i ] - C ) ; lowerLimit = Math . Min ( C , alphas [ j ] + alphas [ i ] ) ; } if ( Math . Abs ( upperLimit - lowerLimit ) < double . Epsilon ) return 0 ; Vector ithRow = dataMatrix . GetRow ( i ) ; Vector jthRow = dataMatrix . GetRow ( j ) ; double k11 = kernelValues [ i , i ] ; double k12 = kernelValues [ i , j ] ; double k22 = kernelValues [ j , j ] ; double eta = k11 + k22 - 2 * k12 ; if ( eta <= 0 ) return 0 ; alphas [ j ] = alphaJOld + labels [ j ] * ( errorI - errorJ ) / eta ; alphas [ j ] = Clip ( alphas [ j ] , upperLimit , lowerLimit ) ; UpdateError ( j ) ; if ( Math . Abs ( alphas [ j ] - alphaJOld ) < epsilon ) return 0 ; alphas [ i ] = alphaIOld + labels [ i ] * labels [ j ] * ( alphaJOld - alphas [ j ] ) ; UpdateError ( i ) ; double b1 = bias - errorI - labels [ i ] * ( alphas [ i ] - alphaIOld ) * k11 - labels [ j ] * ( alphas [ j ] - alphaJOld ) * k12 ; double b2 = bias - errorJ - labels [ i ] * ( alphas [ i ] - alphaIOld ) * k12 - labels [ j ] * ( alphas [ j ] - alphaJOld ) * k22 ; if ( ( 0 < alphas [ i ] ) && ( alphas [ i ] < C ) ) bias = b1 ; else if ( ( 0 < alphas [ j ] ) && ( alphas [ j ] < C ) ) bias = 2 ; else bias = ( b1 + b2 ) / 2 ; return 1 ; } else return 0 ; }
Selects 2nd lagrange multiplier and updates them.
Selects 2nd lagrange multiplier and updates them .
// Get error on i-th sample with current parameters. // Determine whether i-th sample is a support vector. // Get the index of the 2nd lagrange multiplier to optimize. // Cache the old value of the 2 lagrange multipliers. // Calculate upper limit and lower limit of 2nd lagrange multiplier. // No update if upper limit == lower limit. // Calculate values of k11, k12, k22, eta. // This will be cahnged by kernel function. // No optimization if eta <= 0. // Calculate new value of lagrangeMultipliers[j] and update error on j-th sample. // No optimization if the change of j-th lagrange multiplier is not large enough. // Calculate new value of lagrangeMultipliers[i] and update error on i-th sample. // This will be changed by kernel function. // Update bias using formula in the paper. // Return 1 to indicate that there is a pair of lagrange multipliers that has been optimized.
None
i
int
None
epsilon
double
None