/// <summary> /// Predicts the specified elements. /// </summary> /// <remarks>Use some optimization for RBF kernel</remarks> /// <param name="elements">The elements.</param> /// <returns>array of predicted labels</returns> public override float[] Predict(SparseVec[] elements) { if (!IsInitialized) { throw new ApplicationException("Evaluator is not initialized. Call init method"); } float[] predictions = new float[elements.Length]; Parallel.For(0, elements.Length, i => { //for (int i = 0; i < elements.Length; i++) //{ float x1Squere = elements[i].DotProduct(); // linKernel.Product(elements[i], elements[i]);//linKernel.DiagonalDotCache[i]; float sum = 0; int index = -1; for (int k = 0; k < TrainedModel.SupportElementsIndexes.Length; k++) { //support vector squere float x2Squere = linKernel.DiagonalDotCache[k]; float dot = linKernel.Product(elements[i], TrainedModel.SupportElements[k]); float rbfVal = (float)Math.Exp(-gamma * (x1Squere + x2Squere - 2 * dot)); index = TrainedModel.SupportElementsIndexes[k]; sum += TrainedModel.Alpha[index] * TrainedModel.Y[k] * rbfVal; } sum -= TrainedModel.Bias; predictions[i] = sum < 0 ? -1 : 1; } ); return(predictions); }
public override float Product(int element1, int element2) { if (element1 >= problemElements.Length) { throw new IndexOutOfRangeException("element1 out of range"); } if (element2 >= problemElements.Length) { throw new IndexOutOfRangeException("element2 out of range"); } float x1Squere = 0f, x2Squere = 0f, dot = 0f, prod = 0f; if (element1 == element2) { if (DiagonalDotCacheBuilded) { return(DiagonalDotCache[element1]); } else { //all parts are the same // x1Squere = x2Squere = dot = linKernel.Product(element1, element1); //prod = (float)Math.Exp(-Gamma * (x1Squere + x2Squere - 2 * dot)); // (x1Squere + x2Squere - 2 * dot)==0 this expresion is equal zero //so we can prod set to 1 beceause exp(0)==1 prod = 1f; } } else { //when element1 and element2 are different we have to compute all parts x1Squere = linKernel.Product(element1, element1); x2Squere = linKernel.Product(element2, element2); dot = linKernel.Product(element1, element2); prod = (float)Math.Exp(-Gamma * (x1Squere + x2Squere - 2 * dot)); } return(prod); }