/// <summary> /// Classifies the value as belonging to either class -1 or class 1. /// </summary> public int Classify(TValue value) { var sum = SupportVectors.Sum( s => s.Alpha * s.Observation.Label * _kernel.Compute(s.Observation.Value, value)); sum -= _b; return(sum < 0 ? -1 : 1); }
private int TakeStep(int i1, int i2) { if (i1 == i2) { return(0); } double alpha1 = _alphas[i1]; int y1 = _trainingSet[i1].Label; double E1; if (alpha1 > 0 && alpha1 < C) { E1 = _errorCache[i1]; } else { E1 = SvmOutput(i1) - y1; } int s = y1 * _y2; double L, H; if (s == 1) { L = Math.Max(0, alpha1 + _alpha2 - C); H = Math.Min(C, alpha1 + _alpha2); } else { L = Math.Max(0, _alpha2 - alpha1); H = Math.Min(C, C + _alpha2 - alpha1); } if (Math.Abs(L - H) < 10E-9) { return(0); } double k11 = _k.Compute(_trainingSet[i1].Value, _trainingSet[i1].Value); double k12 = _k.Compute(_trainingSet[i1].Value, _trainingSet[i2].Value); double k22 = _k.Compute(_trainingSet[i2].Value, _trainingSet[i2].Value); double eta = 2 * k12 - k11 - k22; double newAlpha2; double Lobj, Hobj; if (eta < 0) { newAlpha2 = _alpha2 - _y2 * (E1 - _e2) / eta; if (newAlpha2 < L) { newAlpha2 = L; } else if (newAlpha2 > H) { newAlpha2 = H; } } else { double c1 = eta / 2; double c2 = _y2 * (E1 - _e2) - eta * _alpha2; Lobj = c1 * L * L + c2 * L; Hobj = c1 * H * H + c2 * H; if (Lobj > Hobj + Eps) { newAlpha2 = L; } else if (Lobj < Hobj - Eps) { newAlpha2 = H; } else { newAlpha2 = _alpha2; } } if (Math.Abs(newAlpha2 - _alpha2) < Eps * (newAlpha2 + _alpha2 + Eps)) { return(0); } var newAlpha1 = alpha1 - s * (newAlpha2 - _alpha2); if (newAlpha1 < 0) { newAlpha2 += s * newAlpha1; newAlpha1 = 0; } else if (newAlpha1 > C) { newAlpha2 += s * (newAlpha1 - C); newAlpha1 = C; } double bNew; if (newAlpha1 > 0 && newAlpha1 < C) { bNew = _b + E1 + y1 * (newAlpha1 - alpha1) * k11 + _y2 * (newAlpha2 - _alpha2) * k12; } else { if (newAlpha2 > 0 && newAlpha2 < C) { bNew = _b + _e2 + y1 * (newAlpha1 - alpha1) * k12 + _y2 * (newAlpha2 - _alpha2) * k22; } else { var b1 = _b + E1 + y1 * (newAlpha1 - alpha1) * k11 + _y2 * (newAlpha2 - _alpha2) * k12; var b2 = _b + _e2 + y1 * (newAlpha1 - alpha1) * k12 + _y2 * (newAlpha2 - _alpha2) * k22; bNew = (b1 + b2) / 2; } } var deltaB = _b - bNew; _b = bNew; double t1 = y1 * (newAlpha1 - alpha1); double t2 = _y2 * (newAlpha2 - _alpha2); for (int i = 0; i < _errorCache.Length; i++) { if (_alphas[i] > 0 && _alphas[i] < C) { _errorCache[i] += t1 * _k.Compute(_trainingSet[i1].Value, _trainingSet[i].Value) + t2 * _k.Compute(_trainingSet[i2].Value, _trainingSet[i].Value) + deltaB; } } _errorCache[i1] = _errorCache[i2] = 0; _alphas[i1] = newAlpha1; _alphas[i2] = newAlpha2; return(1); }