27 ContinuousHiddenMarkovModel::ContinuousHiddenMarkovModel(
const UINT downsampleFactor,
const UINT delta,
const bool autoEstimateSigma,
const Float sigma){
30 this->downsampleFactor = downsampleFactor;
32 this->autoEstimateSigma = autoEstimateSigma;
38 debugLog.setProceedingText(
"[DEBUG ContinuousHiddenMarkovModel]");
39 errorLog.setProceedingText(
"[ERROR ContinuousHiddenMarkovModel]");
40 warningLog.setProceedingText(
"[WARNING ContinuousHiddenMarkovModel]");
41 trainingLog.setProceedingText(
"[TRAINING ContinuousHiddenMarkovModel]");
46 this->downsampleFactor = rhs.downsampleFactor;
50 this->sigma = rhs.sigma;
51 this->autoEstimateSigma = rhs.autoEstimateSigma;
56 this->alpha = rhs.alpha;
59 this->obsSequence = rhs.obsSequence;
62 this->delta = rhs.
delta;
66 const MLBase *basePointer = &rhs;
69 debugLog.setProceedingText(
"[DEBUG ContinuousHiddenMarkovModel]");
70 errorLog.setProceedingText(
"[ERROR ContinuousHiddenMarkovModel]");
71 warningLog.setProceedingText(
"[WARNING ContinuousHiddenMarkovModel]");
72 trainingLog.setProceedingText(
"[TRAINING ContinuousHiddenMarkovModel]");
76 ContinuousHiddenMarkovModel::~ContinuousHiddenMarkovModel(){
83 this->downsampleFactor = rhs.downsampleFactor;
87 this->sigma = rhs.sigma;
88 this->autoEstimateSigma = rhs.autoEstimateSigma;
93 this->alpha = rhs.alpha;
96 this->obsSequence = rhs.obsSequence;
99 this->delta = rhs.
delta;
103 const MLBase *basePointer = &rhs;
113 errorLog <<
"predict_(VectorFloat &x) - The model is not trained!" << std::endl;
117 if( x.
getSize() != numInputDimensions ){
118 errorLog <<
"predict_(VectorFloat &x) - The input vector size (" << x.
getSize() <<
") does not match the number of input dimensions (" << numInputDimensions <<
")" << std::endl;
127 for(
unsigned int j=0; j<numInputDimensions; j++){
138 errorLog <<
"predict_( MatrixFloat ×eries ) - The model is not trained!" << std::endl;
142 if( timeseries.
getNumCols() != numInputDimensions ){
143 errorLog <<
"predict_( MatrixFloat ×eries ) - The matrix column size (" << timeseries.
getNumCols() <<
") does not match the number of input dimensions (" << numInputDimensions <<
")" << std::endl;
147 unsigned int t,i,j,k,index = 0;
153 const unsigned int T = (int)floor( timeseriesLength / Float(downsampleFactor) );
155 for(j=0; j<numInputDimensions; j++){
160 for(k=0; k<downsampleFactor; k++){
161 if( index < timeseriesLength ){
162 obs[i][j] += timeseries[index++][j];
173 if( (
unsigned int)c.size() != T ) c.
resize(T);
182 alpha[t][i] =
pi[i]*gauss(
b,obs,
sigmaStates,i,t,numInputDimensions);
186 if( alpha[t][i] > maxAlpha ){
187 maxAlpha = alpha[t][i];
196 for(i=0; i<
numStates; i++) alpha[t][i] *= c[t];
205 alpha[t][j] += alpha[t-1][i] *
a[i][j];
207 alpha[t][j] *= gauss(
b,obs,
sigmaStates,j,t,numInputDimensions);
211 if( alpha[t][j] > maxAlpha ){
212 maxAlpha = alpha[t][j];
221 for(j=0; j<
numStates; j++) alpha[t][j] *= c[t];
243 numInputDimensions = trainingData.getNumDimensions();
255 b.
resize(numStates, numInputDimensions);
257 unsigned int index = 0;
259 for(
unsigned int j=0; j<numInputDimensions; j++){
264 for(
unsigned int k=0; k<downsampleFactor; k++){
265 if( index < trainingData.getLength() ){
266 b[i][j] += trainingData[index++][j];
289 if((j<i) || (j>i+delta))
a[i][j] = 0.0;
301 pi[i] = i==0 ? 1 : 0;
305 throw(
"HMM_ERROR: Unkown model type!");
313 if( autoEstimateSigma ){
316 MatrixFloat meanResults( numStates, numInputDimensions );
317 for(
unsigned int j=0; j<numInputDimensions; j++){
323 meanResults[i][j] = 0;
324 for(
unsigned int k=0; k<downsampleFactor; k++){
325 if( index < trainingData.getLength() ){
326 meanResults[i][j] += trainingData[index++][j];
331 meanResults[i][j] /= norm;
340 for(
unsigned int k=0; k<downsampleFactor; k++){
341 if( index < trainingData.getLength() ){
342 sigmaStates[i][j] += SQR( trainingData[index++][j]-meanResults[i][j] );
409 trainingLog <<
"A: " << std::endl;
412 trainingLog <<
a[i][j] <<
"\t";
414 trainingLog << std::endl;
417 trainingLog <<
"B: " << std::endl;
420 trainingLog <<
b[i][j] <<
"\t";
422 trainingLog << std::endl;
425 trainingLog <<
"Pi: ";
426 for(
size_t i=0; i<
pi.size(); i++){
427 trainingLog <<
pi[i] <<
"\t";
429 trainingLog << std::endl;
431 trainingLog <<
"SigmaStates: ";
436 trainingLog << std::endl;
438 trainingLog << std::endl;
446 if( sum <= 0.99 || sum >= 1.01 ) warningLog <<
"WARNING: A Row " << i <<
" Sum: "<< sum << std::endl;
455 bool ContinuousHiddenMarkovModel::setDownsampleFactor(
const UINT downsampleFactor){
456 if( downsampleFactor > 0 ){
458 this->downsampleFactor = downsampleFactor;
461 warningLog <<
"setDownsampleFactor(const UINT downsampleFactor) - Failed to set downsample factor, it must be greater than zero!" << std::endl;
466 if( modelType == HMM_ERGODIC || modelType == HMM_LEFTRIGHT ){
471 warningLog <<
"setModelType(const UINT modelType) - Failed to set model type, unknown type!" << std::endl;
481 warningLog <<
"setDelta(const UINT delta) - Failed to set delta, it must be greater than zero!" << std::endl;
485 bool ContinuousHiddenMarkovModel::setSigma(
const Float sigma){
489 if( !autoEstimateSigma && trained ){
494 warningLog <<
"setSigma(const Float sigma) - Failed to set sigma, it must be greater than zero!" << std::endl;
498 bool ContinuousHiddenMarkovModel::setAutoEstimateSigma(
const bool autoEstimateSigma){
502 this->autoEstimateSigma = autoEstimateSigma;
507 Float ContinuousHiddenMarkovModel::gauss(
const MatrixFloat &x,
const MatrixFloat &y,
const MatrixFloat &sigma,
const unsigned int i,
const unsigned int j,
const unsigned int N ){
509 for(
unsigned int n=0; n<N; n++){
510 z *= (1.0/( sigma[i][n] * SQRT_TWO_PI )) * exp( - SQR(x[i][n]-y[j][n])/(2.0*SQR(sigma[i][n])) );
519 errorLog <<
"saveModelToFile( fstream &file ) - File is not open!" << std::endl;
524 file <<
"CONTINUOUS_HMM_MODEL_FILE_V1.0\n";
528 errorLog <<
"saveModelToFile(fstream &file) - Failed to save classifier base settings to file!" << std::endl;
532 file <<
"DownsampleFactor: " << downsampleFactor << std::endl;
533 file <<
"NumStates: " << numStates << std::endl;
534 file <<
"ClassLabel: " <<
classLabel << std::endl;
536 file <<
"Sigma: " << sigma << std::endl;
537 file <<
"AutoEstimateSigma: " << autoEstimateSigma << std::endl;
538 file <<
"ModelType: " <<
modelType << std::endl;
539 file <<
"Delta: " << delta << std::endl;
540 file <<
"Threshold: " <<
cThreshold << std::endl;
547 if( j+1 < numStates ) file <<
"\t";
553 for(UINT j=0; j<numInputDimensions; j++){
555 if( j+1 < numInputDimensions ) file <<
"\t";
562 if( i+1 < numStates ) file <<
"\t";
566 file <<
"SigmaStates: ";
568 for(UINT j=0; j<numInputDimensions; j++){
570 if( j+1 < numInputDimensions ) file <<
"\t";
586 errorLog <<
"loadModelFromFile( fstream &file ) - File is not open!" << std::endl;
595 if(word !=
"CONTINUOUS_HMM_MODEL_FILE_V1.0"){
596 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find Model File Header!" << std::endl;
602 errorLog <<
"loadModelFromFile(string filename) - Failed to load base settings from file!" << std::endl;
607 if(word !=
"DownsampleFactor:"){
608 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the DownsampleFactor header." << std::endl;
611 file >> downsampleFactor;
614 if(word !=
"NumStates:"){
615 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the NumStates header." << std::endl;
621 if(word !=
"ClassLabel:"){
622 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the ClassLabel header." << std::endl;
628 if(word !=
"TimeseriesLength:"){
629 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the TimeseriesLength header." << std::endl;
635 if(word !=
"Sigma:"){
636 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the Sigma for the header." << std::endl;
642 if(word !=
"AutoEstimateSigma:"){
643 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the AutoEstimateSigma for the header." << std::endl;
646 file >> autoEstimateSigma;
649 if(word !=
"ModelType:"){
650 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the ModelType for the header." << std::endl;
656 if(word !=
"Delta:"){
657 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the Delta for the header." << std::endl;
663 if(word !=
"Threshold:"){
664 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the Threshold for the header." << std::endl;
671 b.
resize(numStates,numInputDimensions);
678 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the A matrix header." << std::endl;
691 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the B matrix header." << std::endl;
697 for(UINT j=0; j<numInputDimensions; j++){
704 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the Pi header." << std::endl;
714 if(word !=
"SigmaStates:"){
715 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the SigmaStates header." << std::endl;
721 for(UINT j=0; j<numInputDimensions; j++){
728 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)
unsigned int getSize() const
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.
virtual bool saveModelToFile(std::fstream &file) const
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 loadModelFromFile(std::fstream &file)
virtual bool predict_(VectorFloat &x)
virtual bool resize(const unsigned int r, const unsigned int c)
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.