
Comments and Discussions



hi,
I am new to HMM.
first of all nice code and documentation, it helped me to understand HMM better.
however I have some questions on states.
in the spreadsheet, rows 5,6 & 7 have three different digits/Events in sequence.
00022212222222 A 2(states)
01111222222212 B 2(States)
11111022222222 B 2(states)
1)how to decide that states outcome is 2, and not 3?
2)is it because the output is has higher probability to be either 2 out of the 3 classes?
3)if so, could I increase states according to the probability percentage, instead of hard coded? example, if all 3 distinct values have equal support of (33.33%), states will be set to 3.
thanks





Awesome code examples!
I was looking through the evaluation function and started to wonder what actually happens when you calculate the probability of the model generating a sequence of symbols. For me, it seems natural to use the alpha variable as defined by the forward algorithm, and add the value of the alpha variable for each state, with t = (length of sequence).
Instead, it seems like you multiply a number n of coefficients, where n is the length of the sequence.
Can you help me, I am bit confused about what those coefficients mean, and how multiplying them (adding in log space) calculates the likelihood of the sequence?





Hi there!
Thanks for the interest and for the nice feedback! However, I have to say that article is a bit outdated; it has been superseded by Sequence Classifiers in C#  Part I: Hidden Markov Models[^]. Also, the latest version of the code is also available in GitHub[^] if you would like to take a look.
In any case, also please let me explain what is going on the code. One problem when evaluating hidden Markov models is that their evaluation might involve multiplying lots of very small numbers, that become even smaller as the length of the sequence grows. As such, at some point, we start getting lots of precision errors because our computer have only finite precision for double numbers.
The implementation shown in the article was made using the scaling technique. This technique basically consists at, at each step of the forward algorithm, normalize the obtained probabilities so they sum up to one. However, we keep track of the normalization constants that we used at each step using the coefficients vector shown above. In the end, to get the probability of the sequence, we multiply those coefficients.
This is wellknown technique, but it is not the best one. That is why in the latest version of the Accord.NET Framework[^] this computation is done using logprobabilities instead. The idea is to first transform every probability in the forward matrix into the log domain, then use summations instead of multiplications at each step. This avoids getting very small numbers in the computations, and also avoids the need for normalizing at each step.
Hope it helps!
Best regards,
Cesar





Is the code somewhere available on GitHub?
I would like to make some contributions improving the performance of the algorithm.






Since the diff is too long, I can't comment on it on GitHub. Something quite strange is that when one evaluates a sequence with length zero, the result is double.NegativeInfinity . One would expect one, since such sequence is always "represented" in the hidden Markov model, and furthermore if one uses the real probability, an exp operation should be applied on it resulting in zero.
What is the rationale behind this decision?





Boas César !
I have a question.
You did this in your code: B[i, observations[0]].
If the value of "observations[0]" is negative or its value is greater than the column size of B, we will have an error.
So, why did you do this?
Thank you in advance.





Hello there!
Thanks for the interest in the code! In the discrete case, symbols can be represented by integer labels ranging from 0 to the number of symbols. For example, if you have observations "Sunny", "Cloudy", "Rain", you can easily replace them by 0, 1 and 2. And that is exactly what the HMM is expecting: a vector of integers ranging from 0 to the number of symbols. Thus, observations cannot be negative nor greater than the size of B. The number of symbols must be passed on the HMM's constructor so it can build the forward and emission matrices appropriately.
However, if you really need negative observations, which may imply that your observations are not discrete or cannot be translated into a set of integer symbols, then you can use the generic version of the hidden Markov models which can accept even realvalued variables[^]. For a more detailed explanation, please also take a look at the main article I submitted some years after this one, Sequence Classifiers in C#  Part I: Hidden Markov Models[^]. I hope it helps!
If you have more questions, don't hesitate to ask.
Best regards,
Cesar





Boas Cesar!
Muito obrigado.
It became more clear.
I would like to ask you another question. I have these observations, all negatives:
(62,58,46,41)
(53,56,46,40)
(50,55,41,37)
(61,53,46,38)
(60,55,40,42)
...
(52,49,46,37)
Each sequence represents a position in 2D, I mean (X,Y).
How can I infer the estimated values of X and Y from these observations using HMM?
I am a little confused all to deal with, so your help is greatly appreciated.
Thank you in advance for your help.





Hi Cesar!
I search Hidden markov model in C# and I found in code project. Is it using library ?
I need hidden markov model in C# without library. Can you help me explain concept hidden markov model and Is it must using more algorithm ? (i.e backwardforward, viterbi and baumwelch algorithm)
Thank you.
regards,
ervin





What do you mean with library? A library is simply a collection of source code. All the code to make this algorithm work is opensource (except for the .NET standard library), but these are low level instructions and are well documented...





Hi Cesar!
Great work. I am new to the whole .net thing and im kind of lost on how to get it working.
I installed the Accord.Net, Forge.Net and also SharpDevelop. So im wondering how can i import this in and get it to work? Sorry to bother u on such a simple question. But HMM has been around for a very long time. I did it during my school days using matlab but this is really intriguing.
Hope to hear from you soon.
Cheers,
Keevin





Hi Keevin!
Perhaps you could take a look on Accord.NET's getting started guide[^]. It shows how to add references to some projects. For HMMs, please take a look on the newer article, Sequence Classifiers in C#  Part I: Hidden Markov Models[^]. The assemblies you are looking for are Accord.Statistics and Accord.Math.
You can also download the sample project, which should come with an already working project configuration!
Hope it helps!
Cesar





Hello,
first of all. Thank you. Your code and article helps me a lot.
But I need to ask you something. How to interpreate the result ?
double l1 = hmm.Evaluate(new int[] { 0,1 }); double l2 = hmm.Evaluate(new int[] { 0,1,1,1 });
Why l1 has higher score than l2 ? l2 is much longer and same as l1 it fits to every sequence from sequences
What the result mean ? Is that 99% vs ~92% ?
Second thing I'm checking something and I've created 2 models. Each for diffrent sequence and I want to evaluate a squence and fit it to one of 2 models so I did this
int[][] sequences = new int[][]
{
new int[] { 1,1,1,1,1 },
new int[] { 1,1,1,1,0 },
new int[] { 1,1,1,1,1 },
new int[] { 1,1,1,1,1 },
};
int[][] sequences2 = new int[][]
{
new int[] { 0,0,0,0,0 },
new int[] { 0,0,0,0,0 },
new int[] { 0,0,0,0,1 },
new int[] { 0,0,0,0,0 },
};
HiddenMarkovModel hmm = new HiddenMarkovModel(2, 5, HiddenMarkovModelType.Forward);
HiddenMarkovModel hmm2 = new HiddenMarkovModel(2, 5, HiddenMarkovModelType.Forward);
hmm.Learn(sequences, 0.0001);
hmm2.Learn(sequences, 0.0001);
double l11 = hmm.Evaluate(new int[] { 0, 0, 0, 1, 1 });
double l21 = hmm2.Evaluate(new int[] { 0, 0, 0, 0, 0 });
Console.WriteLine("1) {0}  {1}", l11, l21);
funny thing is that l21 is rly small
1) 1,97215247536716E198  1,11546110202783E197
And I don't get why. The given sequence is like the one from sequnces2. So why isn't it near 1 ?
I hope i wrote is in a clear way
Best regards,
Dawid Pacholczyk
modified 6Jan13 11:48am.





1) Well a hidden Markov model is "trained" such that generating the given sequences (with which it is trained) is the most probable outcome. The Evaluate method calculates what the probability is of generating such sequence. A result is that the longer the sequence is, the less probable it is to generate the sequence, because there are more occasions where the sequence might "fail" to come with the queried one.
2) In the code you provide you both train hmm and hmm2 with the same sequence (sequences ) which is quite the opposite of the queried sequences.





hi, i have problem i have the 6 signal for each action like thinking ,move,calculate for 3 subject and each signal has 2500 sampling how to implement learing and clasification for action





Hi all, I'm a student. I've never used before HMM and I need an help.
I'm working on a project for gesture recognition, this is my application's video:
http://www.youtube.com/watch?v=PDkfgxEV8TI
I'm using DTW (dynamic time warping) for recognition, but this is very slow.
I have ten sequence of movements, I post here an example:
="1.0" ="utf8"
>
<Sequence ID_sequence="10">
<Observation ID_observation="0">
<Joint joint_element="Head">
<X>0,0681642160598825</X>
<Y>0,829331295395237</Y>
</Joint>
<Joint joint_element="HandLeft">
<X>0,704363565952119</X>
<Y>1,60185907740724</Y>
</Joint>
<Joint joint_element="HandRight">
<X>0,681642160598825</X>
<Y>1,67002329346712</Y>
</Joint>
<Joint joint_element="Spine">
<X>0</X>
<Y>0,727084971305413</Y>
</Joint>
<Joint joint_element="FootLeft">
<X>0,261296161562883</X>
<Y>3,73767118061689</Y>
</Joint>
<Joint joint_element="FootRight">
<X>0,261296161562883</X>
<Y>3,70358907258695</Y>
</Joint>
</Observation>
<Observation ID_observation="1">
.......
I work with positive and negative numbers (double) .
Can I create a HMM for these value?
How much states and characters I should use?
(HiddenMarkovModel hmm = new HiddenMarkovModel(2, 2);)
For test I use only the sequence of points for HandLeft (X and Y).







Hi all! I go back to writing for another question.
I have read your link HiddenMarkovClassifierLearning but I have got a problem.
First, I created the sequence for the motion examples with my body points (Head, Hand Left, Hand Right, Spine, Foot Left, Foot Right)
I have a struct with type double[][][]
double[] Head double[] HandLeft
...
double[] FootRight
After, I put these double array in another double array
double[][] action = new double[][]{
Head, HandLeft,
...
FootRight,
};
Finally, I have put this double[][] array in double[][][] for create my library sequences.
double[][][] sequences = new double[][][]
{
new double[][]
{
Head, ....
FootRight,
},
.......
.......
.......
new double[][]
{
Head,
....
FootRight,
}
};
I have wrote this code for HMM's learning.
int size = sequences.Count;
int[] num_labels = { 0, 1, 2, 3, 4,...., sequence.Count1 };
MultivariateNormalDistribution initialDensity = new MultivariateNormalDistribution(size);
HiddenMarkovClassifier<MultivariateNormalDistribution> classifier = new HiddenMarkovClassifier<MultivariateNormalDistribution>(
classes: size, topology: new Forward(size), initial: initialDensity);
HiddenMarkovClassifierLearning<MultivariateNormalDistribution> teacher = new HiddenMarkovClassifierLearning<MultivariateNormalDistribution>(
classifier,
modelIndex => new BaumWelchLearning<MultivariateNormalDistribution>(
classifier.Models[modelIndex])
{
Tolerance = 0.0001,
Iterations = 0,
FittingOptions = new NormalOptions()
{
Diagonal = true, Regularization = 1e5 }
}
);
but when I go to launch the Run method I have a problem
logLikelihood = teacher.Run(sequences, num_labels);
where do I have wrong?
Somebody can help me please? Thanks
modified 15Dec12 13:30pm.





Hi there,
I think you are misunderstanding the concept of a feature vector. Each double[] observation should have the form <Head, Hand Left, Hand Right, Spine, Foot Left, Foot Right>. At a given instant t, your observation should be initialized something like
double[] observation = new double[] { Head[t], HandLeft[t], HandRight[t], Spine[t], FootLeft[t], FootRight[t] };
Besides, you have not told what problem do you have when you are calling the method "Run". If it is giving something like a DimensionMismatchException or an IndexOutOfRange, then it means you are not passing the sequences of observations in the expected form.
Please see if it helps.
Best regards,
Cesar






Hi,
The AggregateException usually shows the actual exception which caused the issue in the InnerExceptions public property. Please take a look at it to see what it reports. But in any case, the problem should likely be the specification of the feature vectors as I mentioned. Did you try changing it to the way I suggested?
Best Regards,
Cesar





I don't understand who I should do with double[] observation...
Cesar, thank you very much for precious advice.
Maybe these can help for understand my structure:
Screen1
Screen2
screen3
modified 15Dec12 18:55pm.





If I understood the example you gave, you were transforming your arrays of head, hands and etc positions as double[][] by doing:
double[][] sequence =
{
Head,
HandLeft,
HandRight,
etc
};
But what you really need to do is to build the feature vectors like this:
double[][] sequence = new double[numberOfObservationsInYourSequence];
for (int i = 0; i < sequence.Length; i++)
sequence[i] = new double[] { Observation[i].Head.X, Observation[i].Head.Y, Observation[i].HandLeft.X, Observation[i].HandLeft.Y, ... };
I hope this makes it more clear.







General News Suggestion Question Bug Answer Joke Rant Admin Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

First Posted  30 Mar 2010 
Views  126,199 
Bookmarked  99 times 

