26 ContinuousHiddenMarkovModel::ContinuousHiddenMarkovModel(
const UINT downsampleFactor,
const UINT delta,
const bool autoEstimateSigma,
const double sigma){
29 this->downsampleFactor = downsampleFactor;
31 this->autoEstimateSigma = autoEstimateSigma;
37 debugLog.setProceedingText(
"[DEBUG ContinuousHiddenMarkovModel]");
38 errorLog.setProceedingText(
"[ERROR ContinuousHiddenMarkovModel]");
39 warningLog.setProceedingText(
"[WARNING ContinuousHiddenMarkovModel]");
40 trainingLog.setProceedingText(
"[TRAINING ContinuousHiddenMarkovModel]");
45 this->downsampleFactor = rhs.downsampleFactor;
49 this->sigma = rhs.sigma;
50 this->autoEstimateSigma = rhs.autoEstimateSigma;
55 this->alpha = rhs.alpha;
58 this->obsSequence = rhs.obsSequence;
61 this->delta = rhs.
delta;
65 const MLBase *basePointer = &rhs;
68 debugLog.setProceedingText(
"[DEBUG ContinuousHiddenMarkovModel]");
69 errorLog.setProceedingText(
"[ERROR ContinuousHiddenMarkovModel]");
70 warningLog.setProceedingText(
"[WARNING ContinuousHiddenMarkovModel]");
71 trainingLog.setProceedingText(
"[TRAINING ContinuousHiddenMarkovModel]");
75 ContinuousHiddenMarkovModel::~ContinuousHiddenMarkovModel(){
82 this->downsampleFactor = rhs.downsampleFactor;
86 this->sigma = rhs.sigma;
87 this->autoEstimateSigma = rhs.autoEstimateSigma;
92 this->alpha = rhs.alpha;
95 this->obsSequence = rhs.obsSequence;
98 this->delta = rhs.
delta;
102 const MLBase *basePointer = &rhs;
112 errorLog <<
"predict_(VectorDouble &x) - The model is not trained!" << endl;
116 if( x.size() != numInputDimensions ){
117 errorLog <<
"predict_(VectorDouble &x) - The input vector size (" << x.size() <<
") does not match the number of input dimensions (" << numInputDimensions <<
")" << endl;
126 for(
unsigned int j=0; j<numInputDimensions; j++){
137 errorLog <<
"predict_( MatrixDouble ×eries ) - The model is not trained!" << endl;
141 if( timeseries.
getNumCols() != numInputDimensions ){
142 errorLog <<
"predict_( MatrixDouble ×eries ) - The matrix column size (" << timeseries.
getNumCols() <<
") does not match the number of input dimensions (" << numInputDimensions <<
")" << endl;
146 unsigned int t,i,j,k,index = 0;
152 const unsigned int T = (int)floor( timeseriesLength /
double(downsampleFactor) );
154 for(j=0; j<numInputDimensions; j++){
159 for(k=0; k<downsampleFactor; k++){
160 if( index < timeseriesLength ){
161 obs[i][j] += timeseries[index++][j];
172 if( (
unsigned int)c.size() != T ) c.resize(T);
181 alpha[t][i] =
pi[i]*gauss(
b,obs,
sigmaStates,i,t,numInputDimensions);
185 if( alpha[t][i] > maxAlpha ){
186 maxAlpha = alpha[t][i];
195 for(i=0; i<
numStates; i++) alpha[t][i] *= c[t];
204 alpha[t][j] += alpha[t-1][i] *
a[i][j];
206 alpha[t][j] *= gauss(
b,obs,
sigmaStates,j,t,numInputDimensions);
210 if( alpha[t][j] > maxAlpha ){
211 maxAlpha = alpha[t][j];
220 for(j=0; j<
numStates; j++) alpha[t][j] *= c[t];
242 numInputDimensions = trainingData.getNumDimensions();
254 b.
resize(numStates, numInputDimensions);
256 unsigned int index = 0;
258 for(
unsigned int j=0; j<numInputDimensions; j++){
263 for(
unsigned int k=0; k<downsampleFactor; k++){
264 if( index < trainingData.getLength() ){
265 b[i][j] += trainingData[index++][j];
275 pi.resize(numStates);
288 if((j<i) || (j>i+delta))
a[i][j] = 0.0;
300 pi[i] = i==0 ? 1 : 0;
304 throw(
"HMM_ERROR: Unkown model type!");
312 if( autoEstimateSigma ){
315 MatrixDouble meanResults( numStates, numInputDimensions );
316 for(
unsigned int j=0; j<numInputDimensions; j++){
322 meanResults[i][j] = 0;
323 for(
unsigned int k=0; k<downsampleFactor; k++){
324 if( index < trainingData.getLength() ){
325 meanResults[i][j] += trainingData[index++][j];
330 meanResults[i][j] /= norm;
339 for(
unsigned int k=0; k<downsampleFactor; k++){
340 if( index < trainingData.getLength() ){
341 sigmaStates[i][j] += SQR( trainingData[index++][j]-meanResults[i][j] );
408 trainingLog <<
"A: " << endl;
411 trainingLog <<
a[i][j] <<
"\t";
416 trainingLog <<
"B: " << endl;
419 trainingLog <<
b[i][j] <<
"\t";
424 trainingLog <<
"Pi: ";
425 for(
size_t i=0; i<
pi.size(); i++){
426 trainingLog <<
pi[i] <<
"\t";
430 trainingLog <<
"SigmaStates: ";
445 if( sum <= 0.99 || sum >= 1.01 ) warningLog <<
"WARNING: A Row " << i <<
" Sum: "<< sum << endl;
454 bool ContinuousHiddenMarkovModel::setDownsampleFactor(
const UINT downsampleFactor){
455 if( downsampleFactor > 0 ){
457 this->downsampleFactor = downsampleFactor;
460 warningLog <<
"setDownsampleFactor(const UINT downsampleFactor) - Failed to set downsample factor, it must be greater than zero!" << endl;
465 if( modelType == HMM_ERGODIC || modelType == HMM_LEFTRIGHT ){
470 warningLog <<
"setModelType(const UINT modelType) - Failed to set model type, unknown type!" << endl;
480 warningLog <<
"setDelta(const UINT delta) - Failed to set delta, it must be greater than zero!" << endl;
484 bool ContinuousHiddenMarkovModel::setSigma(
const double sigma){
488 if( !autoEstimateSigma && trained ){
493 warningLog <<
"setSigma(const double sigma) - Failed to set sigma, it must be greater than zero!" << endl;
497 bool ContinuousHiddenMarkovModel::setAutoEstimateSigma(
const bool autoEstimateSigma){
501 this->autoEstimateSigma = autoEstimateSigma;
506 double ContinuousHiddenMarkovModel::gauss(
const MatrixDouble &x,
const MatrixDouble &y,
const MatrixDouble &sigma,
const unsigned int i,
const unsigned int j,
const unsigned int N ){
508 for(
unsigned int n=0; n<N; n++){
509 z *= (1.0/( sigma[i][n] * SQRT_TWO_PI )) * exp( - SQR(x[i][n]-y[j][n])/(2.0*SQR(sigma[i][n])) );
518 errorLog <<
"saveModelToFile( fstream &file ) - File is not open!" << endl;
523 file <<
"CONTINUOUS_HMM_MODEL_FILE_V1.0\n";
527 errorLog <<
"saveModelToFile(fstream &file) - Failed to save classifier base settings to file!" << endl;
531 file <<
"DownsampleFactor: " << downsampleFactor << endl;
532 file <<
"NumStates: " << numStates << endl;
535 file <<
"Sigma: " << sigma << endl;
536 file <<
"AutoEstimateSigma: " << autoEstimateSigma << endl;
537 file <<
"ModelType: " <<
modelType << endl;
538 file <<
"Delta: " << delta << endl;
546 if( j+1 < numStates ) file <<
"\t";
552 for(UINT j=0; j<numInputDimensions; j++){
554 if( j+1 < numInputDimensions ) file <<
"\t";
561 if( i+1 < numStates ) file <<
"\t";
565 file <<
"SigmaStates: ";
567 for(UINT j=0; j<numInputDimensions; j++){
569 if( j+1 < numInputDimensions ) file <<
"\t";
585 errorLog <<
"loadModelFromFile( fstream &file ) - File is not open!" << endl;
594 if(word !=
"CONTINUOUS_HMM_MODEL_FILE_V1.0"){
595 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find Model File Header!" << endl;
601 errorLog <<
"loadModelFromFile(string filename) - Failed to load base settings from file!" << endl;
606 if(word !=
"DownsampleFactor:"){
607 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the DownsampleFactor header." << endl;
610 file >> downsampleFactor;
613 if(word !=
"NumStates:"){
614 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the NumStates header." << endl;
620 if(word !=
"ClassLabel:"){
621 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the ClassLabel header." << endl;
627 if(word !=
"TimeseriesLength:"){
628 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the TimeseriesLength header." << endl;
634 if(word !=
"Sigma:"){
635 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the Sigma for the header." << endl;
641 if(word !=
"AutoEstimateSigma:"){
642 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the AutoEstimateSigma for the header." << endl;
645 file >> autoEstimateSigma;
648 if(word !=
"ModelType:"){
649 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the ModelType for the header." << endl;
655 if(word !=
"Delta:"){
656 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the Delta for the header." << endl;
662 if(word !=
"Threshold:"){
663 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the Threshold for the header." << endl;
670 b.
resize(numStates,numInputDimensions);
671 pi.resize(numStates);
677 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the A matrix header." << endl;
690 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the B matrix header." << endl;
696 for(UINT j=0; j<numInputDimensions; j++){
703 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the Pi header." << endl;
713 if(word !=
"SigmaStates:"){
714 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the SigmaStates header." << endl;
720 for(UINT j=0; j<numInputDimensions; j++){
727 obsSequence.
resize(timeseriesLength,numInputDimensions);
UINT delta
The number of states a model can move to in a LEFTRIGHT model.
UINT numStates
The number of states for this model.
bool setAllValues(const T &value)
virtual bool predict_(VectorDouble &x)
bool loadBaseSettingsFromFile(fstream &file)
bool saveBaseSettingsToFile(fstream &file) const
unsigned int getNumCols() const
double loglikelihood
The log likelihood of an observation sequence given the modal, calculated by the forward method...
bool copyMLBaseVariables(const MLBase *mlBase)
CircularBuffer< VectorDouble > observationSequence
A buffer to store data for realtime prediction.
virtual bool loadModelFromFile(fstream &file)
MatrixDouble a
The transitions probability matrix.
bool setModelType(const UINT modelType)
bool push_back(const T &value)
virtual bool saveModelToFile(fstream &file) const
double cThreshold
The classification threshold for this model.
bool resize(const unsigned int newBufferSize)
This class implements a continuous Hidden Markov Model.
virtual bool print() const
UINT classLabel
The class label associated with this model.
UINT modelType
The model type (LEFTRIGHT, or ERGODIC)
unsigned int getSize() const
unsigned int getNumRows() const
VectorDouble pi
The state start probability vector.
UINT timeseriesLength
The length of the training timeseries.
MatrixDouble b
The emissions probability matrix.
bool setDelta(const UINT delta)
MatrixDouble sigmaStates
The sigma value for each state.
virtual bool resize(const unsigned int r, const unsigned int c)
vector< UINT > estimatedStates
The estimated states for prediction.