double SegmentorOTSU::sig_func (VectorDouble k, kkint32 nbins, const VectorDouble& P, kkint32 numClasses ) { kkint32 x = 0, y = 0; // muT = sum((1:nbins).*P); double muT = 0.0; for (x = 0, y = 1; x < nbins; ++x, ++y) muT += y * P[x]; //sigma2T = sum(((1:nbins)-muT).^2.*P); double sigma2T = 0.0; for (x = 0, y = 1; x < nbins; ++x, ++y) sigma2T += (pow ((y - muT), 2.0) * P[x]); //k = round(k*(nbins-1)+1); for (x = 0; x < (kkint32)k.size (); ++x) k[x] = floor (k[x] * (nbins - 1) + 1.0 + 0.5); //k = sort(k); sort (k.begin (), k.end ()); //if any(k<1 | k>nbins), y = 1; return, end if ((k[0] < 1.0) || (k[k.size () - 1] > nbins)) return 1.0; //k = [0 k nbins]; % Puts '0' at beginning and 'nbins' at the end. k.insert (k.begin (), 0.0); k.push_back (nbins); // sigma2B = 0; double sigma2B = 0.0; //for j = 1:numClasses for (kkint32 j = 0; j < numClasses; ++j) { //wj = sum(P(k(j)+1:k(j+1))); double wj = SumSubSet (P, (kkint32)(k[j] + 1), (kkint32)k[j + 1]); //if wj==0, y = 1; return, end if (wj == 0.0) return 1.0; //muj = sum((k(j)+1:k(j+1)).*P(k(j)+1:k(j+1)))/wj; kkint32 idxStart = (kkint32)(k[j] + 1); kkint32 idxEnd = (kkint32)(k[j + 1]); double muj = 0.0; for (kkint32 i = idxStart; i <= idxEnd; ++i) muj += (i * P[i] / wj); //sigma2B = sigma2B + wj*(muj-muT)^2; sigma2B = sigma2B + wj * pow ((muj - muT), 2.0); } //y = 1-sigma2B/sigma2T; % within the range [0 1] return 1.0 - sigma2B / sigma2T; } /* sig_func */
bool BernoulliRBM::predict_(VectorDouble &inputData,VectorDouble &outputData){ if( !trained ){ errorLog << "predict_(VectorDouble &inputData,VectorDouble &outputData) - Failed to run prediction - the model has not been trained." << endl; return false; } if( inputData.size() != numVisibleUnits ){ errorLog << "predict_(VectorDouble &inputData,VectorDouble &outputData) - Failed to run prediction - the input data size (" << inputData.size() << ")"; errorLog << " does not match the number of visible units (" << numVisibleUnits << "). " << endl; return false; } if( outputData.size() != numHiddenUnits ){ outputData.resize( numHiddenUnits ); } //Scale the data if needed if( useScaling ){ for(UINT i=0; i<numVisibleUnits; i++){ inputData[i] = scale(inputData[i],ranges[i].minValue,ranges[i].maxValue,0,1); } } //Propagate the data up through the RBM double x = 0.0; for(UINT i=0; i<numHiddenUnits; i++){ for(UINT j=0; j<numVisibleUnits; j++) { x += weightsMatrix[i][j] * inputData[j]; } outputData[i] = sigmoid( x + hiddenLayerBias[i] ); } return true; }
void SegmentorOTSU::NdGrid (const VectorDouble& x, const VectorDouble& y, Matrix& xm, Matrix& ym ) { kkuint32 xLen = (kkuint32)x.size (); kkuint32 yLen = (kkuint32)y.size (); xm.ReSize (xLen, xLen); ym.ReSize (yLen, yLen); kkuint32 row, col; for (row = 0; row < xLen; ++row) { for (col = 0; col < yLen; ++col) xm[row][col] = x[row]; } for (row = 0; row < xLen; ++row) { for (col = 0; col < yLen; ++col) ym[row][col] = y[col]; } }
VectorDouble MatrixDouble::multiple(const VectorDouble &b) const{ const unsigned int M = rows; const unsigned int N = cols; const unsigned int K = (unsigned int)b.size(); if( N != K ){ warningLog << "multiple(vector b) - The size of b (" << b.size() << ") does not match the number of columns in this matrix (" << N << ")" << std::endl; return VectorDouble(); } VectorDouble c(M); const double *pb = &b[0]; double *pc = &c[0]; unsigned int i,j = 0; for(i=0; i<rows; i++){ pc[i] = 0; for(j=0; j<cols; j++){ pc[i] += dataPtr[i*cols+j]*pb[j]; } } return c; }
VectorDouble stddev(VectorDouble v) { double sum = std::accumulate(v.begin(), v.end(), 0.0); double mean = sum / v.size(); double sq_sum = std::inner_product(v.begin(), v.end(), v.begin(), 0.0); double stdev = std::sqrt(sq_sum / v.size() - mean * mean); return VectorDouble(1, stdev); }
VectorDouble SegmentorOTSU::Round (const VectorDouble& v) { VectorDouble r (v.size (), 0.0); for (kkuint32 x = 0; x < v.size (); ++x) { r[x] = (kkint32)(v[x] + 0.5f); } return r; } /* Round */
VectorDouble operator* (double left, const VectorDouble& right ) { VectorDouble result (right.size (), 0.0); for (kkuint32 x = 0; x < right.size (); ++x) result[x] = left * right[x]; return result; }
VectorDouble operator* (const VectorDouble& left, double right ) { VectorDouble result (left.size (), 0.0); for (kkuint32 x = 0; x < left.size (); ++x) result[x] = left[x] * right; return result; }
int main (int argc, const char * argv[]) { //Load the example data ClassificationData data; if( !data.loadDatasetFromFile("WiiAccShakeData.txt") ){ cout << "ERROR: Failed to load data from file!\n"; return EXIT_FAILURE; } //The variables used to initialize the zero crossing counter feature extraction UINT searchWindowSize = 20; double deadZoneThreshold = 0.01; UINT numDimensions = data.getNumDimensions(); UINT featureMode = ZeroCrossingCounter::INDEPENDANT_FEATURE_MODE; //This could also be ZeroCrossingCounter::COMBINED_FEATURE_MODE //Create a new instance of the ZeroCrossingCounter feature extraction ZeroCrossingCounter zeroCrossingCounter(searchWindowSize,deadZoneThreshold,numDimensions,featureMode); //Loop over the accelerometer data, at each time sample (i) compute the features using the new sample and then write the results to a file for(UINT i=0; i<data.getNumSamples(); i++){ //Compute the features using this new sample zeroCrossingCounter.computeFeatures( data[i].getSample() ); //Write the data to the file cout << "InputVector: "; for(UINT j=0; j<data.getNumDimensions(); j++){ cout << data[i].getSample()[j] << "\t"; } //Get the latest feature vector VectorDouble featureVector = zeroCrossingCounter.getFeatureVector(); //Write the features to the file cout << "FeatureVector: "; for(UINT j=0; j<featureVector.size(); j++){ cout << featureVector[j]; if( j != featureVector.size()-1 ) cout << "\t"; } cout << endl; } //Save the zero crossing counter settings to a file zeroCrossingCounter.saveModelToFile("ZeroCrossingCounterSettings.txt"); //You can then load the settings again if you need them zeroCrossingCounter.loadModelFromFile("ZeroCrossingCounterSettings.txt"); return EXIT_SUCCESS; }
VectorDouble SegmentorOTSU::DotMult (const VectorDouble& left, const VectorDouble& right ) { kkuint32 lenMax = (kkuint32)Max (left.size (), right.size ()); kkuint32 lenMin = (kkuint32)Min (left.size (), right.size ()); VectorDouble r (lenMax, 0.0); for (kkuint32 x = 0; x < lenMin; ++x) r[x] = left[x] * right[x]; return r; } /* DotMult */
bool LabelledRegressionData::addSample(const VectorDouble &inputVector,const VectorDouble &targetVector){ if( inputVector.size() == numInputDimensions && targetVector.size() == numTargetDimensions ){ data.push_back( LabelledRegressionSample(inputVector,targetVector) ); totalNumSamples++; //The dataset has changed so flag that any previous cross validation setup will now not work crossValidationSetup = false; crossValidationIndexs.clear(); return true; } errorLog << "addSample(const VectorDouble &inputVector,const VectorDouble &targetVector) - The inputVector size or targetVector size does not match the size of the numInputDimensions or numTargetDimensions" << endl; return false; }
bool SVM::predictSVM(VectorDouble &inputVector){ if( !trained || inputVector.size() != numInputDimensions ) return false; svm_node *x = NULL; //Copy the input data into the SVM format x = new svm_node[numInputDimensions+1]; for(UINT j=0; j<numInputDimensions; j++){ x[j].index = (int)j+1; x[j].value = inputVector[j]; } //The last value in the input vector must be set to -1 x[numInputDimensions].index = -1; x[numInputDimensions].value = 0; //Scale the input data if required if( useScaling ){ for(UINT i=0; i<numInputDimensions; i++) x[i].value = scale(x[i].value,ranges[i].minValue,ranges[i].maxValue,SVM_MIN_SCALE_RANGE,SVM_MAX_SCALE_RANGE); } //Perform the SVM prediction double predict_label = svm_predict(model,x); //We can't do null rejection without the probabilities, so just set the predicted class predictedClassLabel = (UINT)predict_label; //Clean up the memory delete[] x; return true; }
bool RegressionTree::predict_(VectorDouble &inputVector){ if( !trained ){ Regressifier::errorLog << "predict_(VectorDouble &inputVector) - Model Not Trained!" << endl; return false; } if( tree == NULL ){ Regressifier::errorLog << "predict_(VectorDouble &inputVector) - Tree pointer is null!" << endl; return false; } if( inputVector.size() != numInputDimensions ){ Regressifier::errorLog << "predict_(VectorDouble &inputVector) - The size of the input vector (" << inputVector.size() << ") does not match the num features in the model (" << numInputDimensions << endl; return false; } if( useScaling ){ for(UINT n=0; n<numInputDimensions; n++){ inputVector[n] = scale(inputVector[n], inputVectorRanges[n].minValue, inputVectorRanges[n].maxValue, 0, 1); } } if( !tree->predict( inputVector, regressionData ) ){ Regressifier::errorLog << "predict_(VectorDouble &inputVector) - Failed to predict!" << endl; return false; } return true; }
bool Classifier::setNullRejectionThresholds(VectorDouble newRejectionThresholds){ if( newRejectionThresholds.size() == getNumClasses() ){ nullRejectionThresholds = newRejectionThresholds; return true; } return false; }
void DTW::smoothData(VectorDouble &data,UINT smoothFactor,VectorDouble &resultsData){ const UINT M = (UINT)data.size(); const UINT N = (UINT) floor(double(M)/double(smoothFactor)); resultsData.resize(N,0); for(UINT i=0; i<N; i++) resultsData[i]=0.0; if(smoothFactor==1 || M<smoothFactor){ resultsData = data; return; } for(UINT i=0; i<N; i++){ double mean = 0.0; UINT index = i*smoothFactor; for(UINT x=0; x<smoothFactor; x++){ mean += data[index+x]; } resultsData[i] = mean/smoothFactor; } //Add on the data that does not fit into the window if(M%smoothFactor!=0.0){ double mean = 0.0; for(UINT i=N*smoothFactor; i<M; i++) mean += data[i]; mean/=M-(N*smoothFactor); //Add one to the end of the vector VectorDouble tempVector(N+1); for(UINT i=0; i<N; i++) tempVector[i] = resultsData[i]; tempVector[N] = mean; resultsData = tempVector; } }
UINT KMeansQuantizer::quantize(const VectorDouble &inputVector){ if( !trained ){ errorLog << "computeFeatures(const VectorDouble &inputVector) - The quantizer has not been trained!" << endl; return 0; } if( inputVector.size() != numInputDimensions ){ errorLog << "computeFeatures(const VectorDouble &inputVector) - The size of the inputVector (" << inputVector.size() << ") does not match that of the filter (" << numInputDimensions << ")!" << endl; return 0; } //Find the minimum cluster double minDist = numeric_limits<double>::max(); UINT quantizedValue = 0; for(UINT k=0; k<numClusters; k++){ //Compute the squared Euclidean distance quantizationDistances[k] = 0; for(UINT i=0; i<numInputDimensions; i++){ quantizationDistances[k] += SQR( inputVector[i]-clusters[k][i] ); } if( quantizationDistances[k] < minDist ){ minDist = quantizationDistances[k]; quantizedValue = k; } } featureVector[0] = quantizedValue; featureDataReady = true; return quantizedValue; }
VectorDouble TimeseriesBuffer::update(const VectorDouble &x){ #ifdef GRT_SAFE_CHECKING if( !initialized ){ errorLog << "update(const VectorDouble &x) - Not Initialized!" << endl; return VectorDouble(); } if( x.size() != numInputDimensions ){ errorLog << "update(const VectorDouble &x)- The Number Of Input Dimensions (" << numInputDimensions << ") does not match the size of the input vector (" << x.size() << ")!" << endl; return VectorDouble(); } #endif //Add the new data to the buffer dataBuffer.push_back( x ); //Search the buffer for the zero crossing features UINT colIndex = 0; for(UINT j=0; j<numInputDimensions; j++){ for(UINT i=0; i<dataBuffer.getSize(); i++){ featureVector[ colIndex++ ] = dataBuffer[i][j]; } } //Flag that the feature data has been computed if( dataBuffer.getBufferFilled() ){ featureDataReady = true; }else featureDataReady = false; return featureVector; }
bool LinearRegression::predict(VectorDouble inputVector){ if( !trained ){ errorLog << "predict(VectorDouble inputVector) - Model Not Trained!" << endl; return false; } if( !trained ) return false; if( inputVector.size() != numFeatures ){ errorLog << "predict(VectorDouble inputVector) - The size of the input vector (" << inputVector.size() << ") does not match the num features in the model (" << numFeatures << endl; return false; } if( useScaling ){ for(UINT n=0; n<numFeatures; n++){ inputVector[n] = scale(inputVector[n], inputVectorRanges[n].minValue, inputVectorRanges[n].maxValue, 0, 1); } } regressionData[0] = w0; for(UINT j=0; j<numFeatures; j++){ regressionData[0] += inputVector[j] * w[j]; } regressionData[0] = sigmoid( regressionData[0] ); if( useScaling ){ for(UINT n=0; n<numOutputDimensions; n++){ regressionData[n] = scale(regressionData[n], 0, 1, targetVectorRanges[n].minValue, targetVectorRanges[n].maxValue); } } return true; }
VectorDouble Derivative::computeDerivative(const VectorDouble &x){ #ifdef GRT_SAFE_CHECKING if( !initialized ){ errorLog << "computeDerivative(const VectorDouble &x) - Not Initialized!" << endl; return vector<double>(); } if( x.size() != numInputDimensions ){ errorLog << "computeDerivative(const VectorDouble &x) - The Number Of Input Dimensions (" << numInputDimensions << ") does not match the size of the input vector (" << x.size() << ")!" << endl; return vector<double>(); } #endif VectorDouble y; if( filterData ){ y = filter.filter( x ); }else y = x; for(UINT n=0; n<numInputDimensions; n++){ processedData[n] = (y[n]-yy[n])/delta; yy[n] = y[n]; } if( derivativeOrder == SECOND_DERIVATIVE ){ double tmp = 0; for(UINT n=0; n<numInputDimensions; n++){ tmp = processedData[n]; processedData[n] = (processedData[n]-yyy[n])/delta; yyy[n] = tmp; } } return processedData; }
UINT RBMQuantizer::quantize(const VectorDouble &inputVector){ if( !trained ){ errorLog << "quantize(const VectorDouble &inputVector) - The quantizer model has not been trained!" << endl; return 0; } if( inputVector.size() != numInputDimensions ){ errorLog << "quantize(const VectorDouble &inputVector) - The size of the inputVector (" << inputVector.size() << ") does not match that of the filter (" << numInputDimensions << ")!" << endl; return 0; } if( !rbm.predict( inputVector ) ){ errorLog << "quantize(const VectorDouble &inputVector) - Failed to quantize input!" << endl; return 0; } quantizationDistances = rbm.getOutputData(); //Search for the neuron with the maximum output UINT quantizedValue = 0; double maxValue = 0; for(UINT k=0; k<numClusters; k++){ if( quantizationDistances[k] > maxValue ){ maxValue = quantizationDistances[k]; quantizedValue = k; } } featureVector[0] = quantizedValue; featureDataReady = true; return quantizedValue; }
VectorDouble MovingAverageFilter::filter(const VectorDouble &x){ //If the filter has not been initialised then return 0, otherwise filter x and return y if( !initialized ){ errorLog << "filter(const VectorDouble &x) - The filter has not been initialized!" << endl; return VectorDouble(); } if( x.size() != numInputDimensions ){ errorLog << "filter(const VectorDouble &x) - The size of the input vector (" << x.size() << ") does not match that of the number of dimensions of the filter (" << numInputDimensions << ")!" << endl; return VectorDouble(); } if( ++inputSampleCounter > filterSize ) inputSampleCounter = filterSize; //Add the new value to the buffer dataBuffer.push_back( x ); for(unsigned int j=0; j<numInputDimensions; j++){ processedData[j] = 0; for(unsigned int i=0; i<inputSampleCounter; i++) { processedData[j] += dataBuffer[i][j]; } processedData[j] /= double(inputSampleCounter); } return processedData; }
bool SVM::predict_(VectorDouble &inputVector){ if( !trained ){ errorLog << "predict_(VectorDouble &inputVector) - The SVM model has not been trained!" << endl; return false; } if( inputVector.size() != numInputDimensions ){ errorLog << "predict_(VectorDouble &inputVector) - The size of the input vector (" << inputVector.size() << ") does not match the number of features of the model (" << numInputDimensions << ")" << endl; return false; } if( param.probability == 1 ){ if( !predictSVM( inputVector, maxLikelihood, classLikelihoods ) ){ errorLog << "predict(VectorDouble inputVector) - Prediction Failed!" << endl; return false; } }else{ if( !predictSVM( inputVector ) ){ errorLog << "predict(VectorDouble inputVector) - Prediction Failed!" << endl; return false; } } return true; }
VectorDouble HighPassFilter::filter(const VectorDouble &x){ #ifdef GRT_SAFE_CHECKING if( !initialized ){ errorLog << "filter(const VectorDouble &x) - Not Initialized!" << endl; return VectorDouble(); } if( x.size() != numInputDimensions ){ errorLog << "filter(const VectorDouble &x) - The Number Of Input Dimensions (" << numInputDimensions << ") does not match the size of the input vector (" << x.size() << ")!" << endl; return VectorDouble(); } #endif for(UINT n=0; n<numInputDimensions; n++){ //Compute the new output processedData[n] = filterFactor * (yy[n] + x[n] - xx[n]) * gain; //Store the current input xx[n] = x[n]; //Store the current output yy[n] = processedData[n]; } return processedData; }
bool RandomForests::predict(VectorDouble inputVector){ if( !trained ){ errorLog << "predict(VectorDouble inputVector) - Model Not Trained!" << endl; return false; } predictedClassLabel = 0; maxLikelihood = -10000; if( !trained ) return false; if( inputVector.size() != numInputDimensions ){ errorLog << "predict(VectorDouble inputVector) - The size of the input vector (" << inputVector.size() << ") does not match the num features in the model (" << numInputDimensions << endl; return false; } if( useScaling ){ for(UINT n=0; n<numInputDimensions; n++){ inputVector[n] = scale(inputVector[n], ranges[n].minValue, ranges[n].maxValue, 0, 1); } } if( classLikelihoods.size() != numClasses ) classLikelihoods.resize(numClasses,0); if( classDistances.size() != numClasses ) classDistances.resize(numClasses,0); for(UINT j=0; j<numClasses; j++){ classDistances[j] = 0; } VectorDouble y; for(UINT i=0; i<forestSize; i++){ if( !forest[i]->predict(inputVector, y) ){ errorLog << "predict(VectorDouble inputVector) - Tree " << i << " failed prediction!" << endl; return false; } for(UINT j=0; j<numClasses; j++){ classDistances[j] += y[j]; } } maxLikelihood = 0; bestDistance = 0; UINT bestIndex = 0; for(UINT k=0; k<numClasses; k++){ classLikelihoods[k] = classDistances[k] / double(forestSize); if( classLikelihoods[k] > maxLikelihood ){ maxLikelihood = classLikelihoods[k]; bestDistance = classDistances[k]; bestIndex = k; } } predictedClassLabel = classLabels[ bestIndex ]; return true; }
bool HMM::predict_discrete( VectorDouble &inputVector ){ predictedClassLabel = 0; maxLikelihood = -10000; if( !trained ){ errorLog << "predict_(VectorDouble &inputVector) - The HMM classifier has not been trained!" << endl; return false; } if( inputVector.size() != numInputDimensions ){ errorLog << "predict_(VectorDouble &inputVector) - The size of the input vector (" << inputVector.size() << ") does not match the num features in the model (" << numInputDimensions << endl; return false; } if( classLikelihoods.size() != numClasses ) classLikelihoods.resize(numClasses,0); if( classDistances.size() != numClasses ) classDistances.resize(numClasses,0); double sum = 0; bestDistance = -99e+99; UINT bestIndex = 0; UINT newObservation = (UINT)inputVector[0]; if( newObservation >= numSymbols ){ errorLog << "predict_(VectorDouble &inputVector) - The new observation is not a valid symbol! It should be in the range [0 numSymbols-1]" << endl; return false; } for(UINT k=0; k<numClasses; k++){ classDistances[k] = discreteModels[k].predict( newObservation ); //Set the class likelihood as the antilog of the class distances classLikelihoods[k] = antilog( classDistances[k] ); //The loglikelihood values are negative so we want the values closest to 0 if( classDistances[k] > bestDistance ){ bestDistance = classDistances[k]; bestIndex = k; } sum += classLikelihoods[k]; } //Turn the class distances into proper likelihoods for(UINT k=0; k<numClasses; k++){ classLikelihoods[k] /= sum; } maxLikelihood = classLikelihoods[ bestIndex ]; predictedClassLabel = classLabels[ bestIndex ]; if( useNullRejection ){ if( maxLikelihood > nullRejectionThresholds[ bestIndex ] ){ predictedClassLabel = classLabels[ bestIndex ]; }else predictedClassLabel = GRT_DEFAULT_NULL_CLASS_LABEL; } return true; }
bool MinDist::predict_(VectorDouble &inputVector){ if( !trained ){ errorLog << "predict_(VectorDouble &inputVector) - MinDist Model Not Trained!" << endl; return false; } predictedClassLabel = 0; maxLikelihood = 0; if( !trained ) return false; if( inputVector.size() != numInputDimensions ){ errorLog << "predict_(VectorDouble &inputVector) - The size of the input vector (" << inputVector.size() << ") does not match the num features in the model (" << numInputDimensions << endl; return false; } if( useScaling ){ for(UINT n=0; n<numInputDimensions; n++){ inputVector[n] = scale(inputVector[n], ranges[n].minValue, ranges[n].maxValue, 0, 1); } } if( classLikelihoods.size() != numClasses ) classLikelihoods.resize(numClasses,0); if( classDistances.size() != numClasses ) classDistances.resize(numClasses,0); double sum = 0; double minDist = numeric_limits<double>::max(); for(UINT k=0; k<numClasses; k++){ //Compute the distance for class k classDistances[k] = models[k].predict( inputVector ); //Keep track of the best value if( classDistances[k] < minDist ){ minDist = classDistances[k]; predictedClassLabel = k; } //Set the class likelihoods as 1.0 / dist[k], the small number is to stop divide by zero classLikelihoods[k] = 1.0 / (classDistances[k] + 0.0001); sum += classLikelihoods[k]; } //Normalize the classlikelihoods if( sum != 0 ){ for(UINT k=0; k<numClasses; k++){ classLikelihoods[k] /= sum; } maxLikelihood = classLikelihoods[predictedClassLabel]; }else maxLikelihood = classLikelihoods[predictedClassLabel]; if( useNullRejection ){ //Check to see if the best result is greater than the models threshold if( minDist <= models[predictedClassLabel].getRejectionThreshold() ) predictedClassLabel = models[predictedClassLabel].getClassLabel(); else predictedClassLabel = GRT_DEFAULT_NULL_CLASS_LABEL; }else predictedClassLabel = models[predictedClassLabel].getClassLabel(); return true; }
bool BAG::setWeights(const VectorDouble &weights){ if( this->weights.size() != weights.size() ){ return false; } this->weights = weights; return true; }
bool Softmax::predict_(VectorDouble &inputVector){ if( !trained ){ errorLog << "predict_(VectorDouble &inputVector) - Model Not Trained!" << endl; return false; } predictedClassLabel = 0; maxLikelihood = -10000; if( !trained ) return false; if( inputVector.size() != numInputDimensions ){ errorLog << "predict_(VectorDouble &inputVector) - The size of the input vector (" << inputVector.size() << ") does not match the num features in the model (" << numInputDimensions << endl; return false; } if( useScaling ){ for(UINT n=0; n<numInputDimensions; n++){ inputVector[n] = scale(inputVector[n], ranges[n].minValue, ranges[n].maxValue, 0, 1); } } if( classLikelihoods.size() != numClasses ) classLikelihoods.resize(numClasses,0); if( classDistances.size() != numClasses ) classDistances.resize(numClasses,0); //Loop over each class and compute the likelihood of the input data coming from class k. Pick the class with the highest likelihood double sum = 0; double bestEstimate = numeric_limits<double>::min(); UINT bestIndex = 0; for(UINT k=0; k<numClasses; k++){ double estimate = models[k].compute( inputVector ); if( estimate > bestEstimate ){ bestEstimate = estimate; bestIndex = k; } classDistances[k] = estimate; classLikelihoods[k] = estimate; sum += estimate; } if( sum > 1.0e-5 ){ for(UINT k=0; k<numClasses; k++){ classLikelihoods[k] /= sum; } }else{ //If the sum is less than the value above then none of the models found a positive class maxLikelihood = bestEstimate; predictedClassLabel = GRT_DEFAULT_NULL_CLASS_LABEL; return true; } maxLikelihood = classLikelihoods[bestIndex]; predictedClassLabel = classLabels[bestIndex]; return true; }
bool MinDist::predict(VectorDouble inputVector){ if( !trained ){ errorLog << "predict(VectorDouble inputVector) - MinDist Model Not Trained!" << endl; return false; } predictedClassLabel = 0; maxLikelihood = 0; if( !trained ) return false; if( inputVector.size() != numFeatures ){ errorLog << "predict(VectorDouble inputVector) - The size of the input vector (" << inputVector.size() << ") does not match the num features in the model (" << numFeatures << endl; return false; } if( useScaling ){ for(UINT n=0; n<numFeatures; n++){ inputVector[n] = scale(inputVector[n], ranges[n].minValue, ranges[n].maxValue, 0, 1); } } if( classLikelihoods.size() != numClasses ) classLikelihoods.resize(numClasses,0); if( classDistances.size() != numClasses ) classDistances.resize(numClasses,0); double classLikelihoodsSum = 0; double minDist = numeric_limits<double>::max(); for(UINT k=0; k<numClasses; k++){ classDistances[k] = models[k].predict( inputVector ); //At this point the class likelihoods and class distances are the same thing classLikelihoods[k] = classDistances[k]; classLikelihoodsSum += classDistances[k]; //Keep track of the best value if( classDistances[k] < minDist ){ minDist = classDistances[k]; predictedClassLabel = k; } } //Normalize the classlikelihoods if( classLikelihoodsSum != 0 ){ for(UINT k=0; k<numClasses; k++){ classLikelihoods[k] = (classLikelihoodsSum-classLikelihoods[k])/classLikelihoodsSum; } maxLikelihood = classLikelihoods[predictedClassLabel]; }else maxLikelihood = classLikelihoods[predictedClassLabel]; if( useNullRejection ){ //Check to see if the best result is greater than the models threshold if( minDist <= models[predictedClassLabel].getRejectionThreshold() ) predictedClassLabel = models[predictedClassLabel].getClassLabel(); else predictedClassLabel = GRT_DEFAULT_NULL_CLASS_LABEL; }else predictedClassLabel = models[predictedClassLabel].getClassLabel(); return true; }
bool SwipeDetector::predict_(VectorDouble &inputVector) { predictedClassLabel = 0; maxLikelihood = 0; swipeDetected = false; if( !trained ) { errorLog << "predict_(VectorDouble &inputVector) - SwipeDetector Model Not Trained!" << std::endl; return false; } if( inputVector.size() != numInputDimensions ) { errorLog << "predict_(VectorDouble &inputVector) - The size of the input vector (" << inputVector.size() << ") does not match the num features in the model (" << numInputDimensions << ")" << std::endl; return false; } if( useScaling ) { for(UINT n=0; n<numInputDimensions; n++) { inputVector[n] = scale(inputVector[n], ranges[n].minValue, ranges[n].maxValue, 0, 1); } } if( classLikelihoods.size() != numClasses ) classLikelihoods.resize(numClasses,0); if( classDistances.size() != numClasses ) classDistances.resize(numClasses,0); //Compute the integrated movement velocity for the none-swipe dimensions if( !firstSample ) { movementVelocity *= movementIntegrationCoeff; for(unsigned int i=0; i<numInputDimensions; i++) { if( i != swipeIndex ) movementVelocity += GRT::SQR(inputVector[i]-lastX[i]); } } else firstSample = false; lastX = inputVector; //Compute the integrated swipe velocity and update the threshold detector swipeVelocity = (swipeVelocity*swipeIntegrationCoeff) + inputVector[swipeIndex]; thresholdDetector.update( swipeVelocity ); //Filter the context contextFilteredValue = contextFilter.filter( contextInput ? 1 : 0 ); //Check if a swipe has been detected swipeDetected = thresholdDetector.getThresholdCrossingDetected() && movementVelocity < movementThreshold && contextFilteredValue == 1; if( swipeDetected ) { predictedClassLabel = 1; classLikelihoods[0] = 1.0; classDistances[1] = 0; } else { predictedClassLabel = 2; classLikelihoods[0] = 0.0; classDistances[1] = 1; } return true; }