21 #define GRT_DLL_EXPORTS
28 ContinuousHiddenMarkovModel::ContinuousHiddenMarkovModel(
const UINT downsampleFactor,
const UINT delta,
const bool autoEstimateSigma,
const Float sigma){
31 this->downsampleFactor = downsampleFactor;
33 this->autoEstimateSigma = autoEstimateSigma;
39 debugLog.setProceedingText(
"[DEBUG ContinuousHiddenMarkovModel]");
40 errorLog.setProceedingText(
"[ERROR ContinuousHiddenMarkovModel]");
41 warningLog.setProceedingText(
"[WARNING ContinuousHiddenMarkovModel]");
42 trainingLog.setProceedingText(
"[TRAINING ContinuousHiddenMarkovModel]");
47 this->downsampleFactor = rhs.downsampleFactor;
51 this->sigma = rhs.sigma;
52 this->autoEstimateSigma = rhs.autoEstimateSigma;
57 this->alpha = rhs.alpha;
60 this->obsSequence = rhs.obsSequence;
63 this->delta = rhs.
delta;
67 const MLBase *basePointer = &rhs;
70 debugLog.setProceedingText(
"[DEBUG ContinuousHiddenMarkovModel]");
71 errorLog.setProceedingText(
"[ERROR ContinuousHiddenMarkovModel]");
72 warningLog.setProceedingText(
"[WARNING ContinuousHiddenMarkovModel]");
73 trainingLog.setProceedingText(
"[TRAINING ContinuousHiddenMarkovModel]");
77 ContinuousHiddenMarkovModel::~ContinuousHiddenMarkovModel(){
84 this->downsampleFactor = rhs.downsampleFactor;
88 this->sigma = rhs.sigma;
89 this->autoEstimateSigma = rhs.autoEstimateSigma;
94 this->alpha = rhs.alpha;
97 this->obsSequence = rhs.obsSequence;
100 this->delta = rhs.
delta;
104 const MLBase *basePointer = &rhs;
114 errorLog <<
"predict_(VectorFloat &x) - The model is not trained!" << std::endl;
118 if( x.
getSize() != numInputDimensions ){
119 errorLog <<
"predict_(VectorFloat &x) - The input vector size (" << x.
getSize() <<
") does not match the number of input dimensions (" << numInputDimensions <<
")" << std::endl;
128 for(
unsigned int j=0; j<numInputDimensions; j++){
139 errorLog <<
"predict_( MatrixFloat ×eries ) - The model is not trained!" << std::endl;
143 if( timeseries.
getNumCols() != numInputDimensions ){
144 errorLog <<
"predict_( MatrixFloat ×eries ) - The matrix column size (" << timeseries.
getNumCols() <<
") does not match the number of input dimensions (" << numInputDimensions <<
")" << std::endl;
148 unsigned int t,i,j,k,index = 0;
154 const unsigned int T = (int)floor( timeseriesLength / Float(downsampleFactor) );
156 for(j=0; j<numInputDimensions; j++){
161 for(k=0; k<downsampleFactor; k++){
162 if( index < timeseriesLength ){
163 obs[i][j] += timeseries[index++][j];
174 if( (
unsigned int)c.size() != T ) c.
resize(T);
183 alpha[t][i] =
pi[i]*gauss(
b,obs,
sigmaStates,i,t,numInputDimensions);
187 if( alpha[t][i] > maxAlpha ){
188 maxAlpha = alpha[t][i];
197 for(i=0; i<
numStates; i++) alpha[t][i] *= c[t];
206 alpha[t][j] += alpha[t-1][i] *
a[i][j];
208 alpha[t][j] *= gauss(
b,obs,
sigmaStates,j,t,numInputDimensions);
212 if( alpha[t][j] > maxAlpha ){
213 maxAlpha = alpha[t][j];
222 for(j=0; j<
numStates; j++) alpha[t][j] *= c[t];
244 numInputDimensions = trainingData.getNumDimensions();
256 b.
resize(numStates, numInputDimensions);
258 unsigned int index = 0;
260 for(
unsigned int j=0; j<numInputDimensions; j++){
265 for(
unsigned int k=0; k<downsampleFactor; k++){
266 if( index < trainingData.getLength() ){
267 b[i][j] += trainingData[index++][j];
290 if((j<i) || (j>i+delta))
a[i][j] = 0.0;
302 pi[i] = i==0 ? 1 : 0;
306 throw(
"HMM_ERROR: Unkown model type!");
314 if( autoEstimateSigma ){
317 MatrixFloat meanResults( numStates, numInputDimensions );
318 for(
unsigned int j=0; j<numInputDimensions; j++){
324 meanResults[i][j] = 0;
325 for(
unsigned int k=0; k<downsampleFactor; k++){
326 if( index < trainingData.getLength() ){
327 meanResults[i][j] += trainingData[index++][j];
332 meanResults[i][j] /= norm;
341 for(
unsigned int k=0; k<downsampleFactor; k++){
342 if( index < trainingData.getLength() ){
343 sigmaStates[i][j] += SQR( trainingData[index++][j]-meanResults[i][j] );
410 trainingLog <<
"A: " << std::endl;
413 trainingLog <<
a[i][j] <<
"\t";
415 trainingLog << std::endl;
418 trainingLog <<
"B: " << std::endl;
421 trainingLog <<
b[i][j] <<
"\t";
423 trainingLog << std::endl;
426 trainingLog <<
"Pi: ";
427 for(
size_t i=0; i<
pi.size(); i++){
428 trainingLog <<
pi[i] <<
"\t";
430 trainingLog << std::endl;
432 trainingLog <<
"SigmaStates: ";
437 trainingLog << std::endl;
439 trainingLog << std::endl;
447 if( sum <= 0.99 || sum >= 1.01 ) warningLog <<
"WARNING: A Row " << i <<
" Sum: "<< sum << std::endl;
456 bool ContinuousHiddenMarkovModel::setDownsampleFactor(
const UINT downsampleFactor){
457 if( downsampleFactor > 0 ){
459 this->downsampleFactor = downsampleFactor;
462 warningLog <<
"setDownsampleFactor(const UINT downsampleFactor) - Failed to set downsample factor, it must be greater than zero!" << std::endl;
467 if( modelType == HMM_ERGODIC || modelType == HMM_LEFTRIGHT ){
472 warningLog <<
"setModelType(const UINT modelType) - Failed to set model type, unknown type!" << std::endl;
482 warningLog <<
"setDelta(const UINT delta) - Failed to set delta, it must be greater than zero!" << std::endl;
486 bool ContinuousHiddenMarkovModel::setSigma(
const Float sigma){
490 if( !autoEstimateSigma && trained ){
495 warningLog <<
"setSigma(const Float sigma) - Failed to set sigma, it must be greater than zero!" << std::endl;
499 bool ContinuousHiddenMarkovModel::setAutoEstimateSigma(
const bool autoEstimateSigma){
503 this->autoEstimateSigma = autoEstimateSigma;
508 Float ContinuousHiddenMarkovModel::gauss(
const MatrixFloat &x,
const MatrixFloat &y,
const MatrixFloat &sigma,
const unsigned int i,
const unsigned int j,
const unsigned int N ){
510 for(
unsigned int n=0; n<N; n++){
511 z *= (1.0/( sigma[i][n] * SQRT_TWO_PI )) * exp( - SQR(x[i][n]-y[j][n])/(2.0*SQR(sigma[i][n])) );
520 errorLog <<
"save( fstream &file ) - File is not open!" << std::endl;
525 file <<
"CONTINUOUS_HMM_MODEL_FILE_V1.0\n";
529 errorLog <<
"save(fstream &file) - Failed to save classifier base settings to file!" << std::endl;
533 file <<
"DownsampleFactor: " << downsampleFactor << std::endl;
534 file <<
"NumStates: " << numStates << std::endl;
535 file <<
"ClassLabel: " <<
classLabel << std::endl;
537 file <<
"Sigma: " << sigma << std::endl;
538 file <<
"AutoEstimateSigma: " << autoEstimateSigma << std::endl;
539 file <<
"ModelType: " <<
modelType << std::endl;
540 file <<
"Delta: " << delta << std::endl;
541 file <<
"Threshold: " <<
cThreshold << std::endl;
548 if( j+1 < numStates ) file <<
"\t";
554 for(UINT j=0; j<numInputDimensions; j++){
556 if( j+1 < numInputDimensions ) file <<
"\t";
563 if( i+1 < numStates ) file <<
"\t";
567 file <<
"SigmaStates: ";
569 for(UINT j=0; j<numInputDimensions; j++){
571 if( j+1 < numInputDimensions ) file <<
"\t";
587 errorLog <<
"load( fstream &file ) - File is not open!" << std::endl;
596 if(word !=
"CONTINUOUS_HMM_MODEL_FILE_V1.0"){
597 errorLog <<
"load( fstream &file ) - Could not find Model File Header!" << std::endl;
603 errorLog <<
"load(string filename) - Failed to load base settings from file!" << std::endl;
608 if(word !=
"DownsampleFactor:"){
609 errorLog <<
"load( fstream &file ) - Could not find the DownsampleFactor header." << std::endl;
612 file >> downsampleFactor;
615 if(word !=
"NumStates:"){
616 errorLog <<
"load( fstream &file ) - Could not find the NumStates header." << std::endl;
622 if(word !=
"ClassLabel:"){
623 errorLog <<
"load( fstream &file ) - Could not find the ClassLabel header." << std::endl;
629 if(word !=
"TimeseriesLength:"){
630 errorLog <<
"load( fstream &file ) - Could not find the TimeseriesLength header." << std::endl;
636 if(word !=
"Sigma:"){
637 errorLog <<
"load( fstream &file ) - Could not find the Sigma for the header." << std::endl;
643 if(word !=
"AutoEstimateSigma:"){
644 errorLog <<
"load( fstream &file ) - Could not find the AutoEstimateSigma for the header." << std::endl;
647 file >> autoEstimateSigma;
650 if(word !=
"ModelType:"){
651 errorLog <<
"load( fstream &file ) - Could not find the ModelType for the header." << std::endl;
657 if(word !=
"Delta:"){
658 errorLog <<
"load( fstream &file ) - Could not find the Delta for the header." << std::endl;
664 if(word !=
"Threshold:"){
665 errorLog <<
"load( fstream &file ) - Could not find the Threshold for the header." << std::endl;
672 b.
resize(numStates,numInputDimensions);
679 errorLog <<
"load( fstream &file ) - Could not find the A matrix header." << std::endl;
692 errorLog <<
"load( fstream &file ) - Could not find the B matrix header." << std::endl;
698 for(UINT j=0; j<numInputDimensions; j++){
705 errorLog <<
"load( fstream &file ) - Could not find the Pi header." << std::endl;
715 if(word !=
"SigmaStates:"){
716 errorLog <<
"load( fstream &file ) - Could not find the SigmaStates header." << std::endl;
722 for(UINT j=0; j<numInputDimensions; j++){
729 obsSequence.
resize(timeseriesLength,numInputDimensions);
bool saveBaseSettingsToFile(std::fstream &file) const
bool push_back(const T &value)
Vector< UINT > estimatedStates
The estimated states for prediction.
Float cThreshold
The classification threshold for this model.
virtual bool print() const
This class acts as the main interface for using a Hidden Markov Model.
MatrixFloat a
The transitions probability matrix.
virtual bool resize(const unsigned int size)
Float loglikelihood
The log likelihood of an observation sequence given the modal, calculated by the forward method...
VectorFloat pi
The state start probability vector.
UINT modelType
The model type (LEFTRIGHT, or ERGODIC)
bool setDelta(const UINT delta)
bool setAllValues(const T &value)
UINT delta
The number of states a model can move to in a LEFTRIGHT model.
CircularBuffer< VectorFloat > observationSequence
A buffer to store data for realtime prediction.
bool copyMLBaseVariables(const MLBase *mlBase)
This class implements a continuous Hidden Markov Model.
UINT classLabel
The class label associated with this model.
unsigned int getNumRows() const
unsigned int getNumCols() const
MatrixFloat sigmaStates
The sigma value for each state.
bool loadBaseSettingsFromFile(std::fstream &file)
virtual bool load(std::fstream &file)
virtual bool predict_(VectorFloat &x)
virtual bool resize(const unsigned int r, const unsigned int c)
virtual bool save(std::fstream &file) const
MatrixFloat b
The emissions probability matrix.
UINT timeseriesLength
The length of the training timeseries.
unsigned int getSize() const
bool setModelType(const UINT modelType)
bool resize(const unsigned int newBufferSize)
UINT numStates
The number of states for this model.