[mlpack-svn] r10525 - mlpack/trunk/src/mlpack/tests
fastlab-svn at coffeetalk-1.cc.gatech.edu
fastlab-svn at coffeetalk-1.cc.gatech.edu
Sat Dec 3 03:06:20 EST 2011
Author: rcurtin
Date: 2011-12-03 03:06:20 -0500 (Sat, 03 Dec 2011)
New Revision: 10525
Modified:
mlpack/trunk/src/mlpack/tests/hmm_test.cpp
Log:
Adapt HMM tests to new API.
Modified: mlpack/trunk/src/mlpack/tests/hmm_test.cpp
===================================================================
--- mlpack/trunk/src/mlpack/tests/hmm_test.cpp 2011-12-03 08:06:00 UTC (rev 10524)
+++ mlpack/trunk/src/mlpack/tests/hmm_test.cpp 2011-12-03 08:06:20 UTC (rev 10525)
@@ -41,14 +41,8 @@
// Now let's take a sequence and find what the most likely state is.
// We'll use the sequence [U U N U U] (U = umbrella, N = no umbrella) like on
// p. 547.
- std::vector<size_t> observation;
- observation.push_back(0);
- observation.push_back(0);
- observation.push_back(1);
- observation.push_back(0);
- observation.push_back(0);
-
- std::vector<size_t> states;
+ arma::mat observation = "0 0 1 0 0";
+ arma::Col<size_t> states;
hmm.Predict(observation, states);
// Check each state.
@@ -79,18 +73,8 @@
HMM<DiscreteDistribution> hmm(transition, emission);
// GGCACTGAA.
- std::vector<size_t> observation(9);
- observation[0] = 2;
- observation[1] = 2;
- observation[2] = 1;
- observation[3] = 0;
- observation[4] = 1;
- observation[5] = 3;
- observation[6] = 2;
- observation[7] = 0;
- observation[8] = 0;
-
- std::vector<size_t> states;
+ arma::mat observation("2 2 1 0 1 3 2 0 0");
+ arma::Col<size_t> states;
hmm.Predict(observation, states);
// Most probable path is HHHLLLLLL.
@@ -112,17 +96,7 @@
*/
BOOST_AUTO_TEST_CASE(ForwardBackwardTwoState)
{
- std::vector<size_t> obs(10);
- obs[0] = 3;
- obs[1] = 3;
- obs[2] = 2;
- obs[3] = 1;
- obs[4] = 1;
- obs[5] = 1;
- obs[6] = 1;
- obs[7] = 3;
- obs[8] = 3;
- obs[9] = 1;
+ arma::mat obs("3 3 2 1 1 1 1 3 3 1");
arma::mat transition("0.1 0.9; 0.4 0.6");
std::vector<DiscreteDistribution> emis(2);
@@ -173,15 +147,16 @@
// Don't yet require a useful distribution. 1 state, 1 emission.
HMM<DiscreteDistribution> hmm(1, DiscreteDistribution(1));
- std::vector<std::vector<size_t> > observations;
- observations.push_back(std::vector<size_t>(8, 0)); // 8 zeros.
- observations.push_back(std::vector<size_t>(7, 0)); // 7 zeros.
- observations.push_back(std::vector<size_t>(12, 0)); // 12 zeros.
- observations.push_back(std::vector<size_t>(10, 0)); // 10 zeros.
+ std::vector<arma::mat> observations;
+ // Different lengths for each observation sequence.
+ observations.push_back("0 0 0 0 0 0 0 0"); // 8 zeros.
+ observations.push_back("0 0 0 0 0 0 0"); // 7 zeros.
+ observations.push_back("0 0 0 0 0 0 0 0 0 0 0 0"); // 12 zeros.
+ observations.push_back("0 0 0 0 0 0 0 0 0 0"); // 10 zeros.
hmm.Train(observations);
- BOOST_REQUIRE_CLOSE(hmm.Emission()[0].Probability(0), 1.0, 1e-5);
+ BOOST_REQUIRE_CLOSE(hmm.Emission()[0].Probability("0"), 1.0, 1e-5);
BOOST_REQUIRE_CLOSE(hmm.Transition()(0, 0), 1.0, 1e-5);
}
@@ -196,21 +171,24 @@
// P(each emission) = 0.5.
// I've been careful to make P(first emission = 0) = P(first emission = 1).
- std::vector<std::vector<size_t> > observations;
- size_t obs[6][12] = {{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
- {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1},
- {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
- {1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0},
- {0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1},
- {1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0}};
+ std::vector<arma::mat> observations;
+ observations.push_back("0 1 0 1 0 1 0 1 0 1 0 1");
+ observations.push_back("0 0 0 0 0 0 1 1 1 1 1 1");
+ observations.push_back("1 1 1 1 1 1 0 0 0 0 0 0");
+ observations.push_back("1 1 1 0 0 0 1 1 1 0 0 0");
+ observations.push_back("0 0 1 1 0 0 0 0 1 1 1 1");
+ observations.push_back("1 1 1 0 0 0 1 1 1 0 0 0");
+ observations.push_back("0 1 0 1 0 1 0 1 0 1 0 1");
+ observations.push_back("0 0 0 0 0 0 1 1 1 1 1 1");
+ observations.push_back("1 1 1 1 1 1 0 0 0 0 0 0");
+ observations.push_back("1 1 1 0 0 0 1 1 1 0 0 0");
+ observations.push_back("0 0 1 1 0 0 0 0 1 1 1 1");
+ observations.push_back("1 1 1 0 0 0 1 1 1 0 0 0");
- for (size_t i = 0; i < 18; i++)
- observations.push_back(std::vector<size_t>(obs[i % 6], obs[i % 6] + 12));
-
hmm.Train(observations);
- BOOST_REQUIRE_CLOSE(hmm.Emission()[0].Probability(0), 0.5, 1e-5);
- BOOST_REQUIRE_CLOSE(hmm.Emission()[0].Probability(1), 0.5, 1e-5);
+ BOOST_REQUIRE_CLOSE(hmm.Emission()[0].Probability("0"), 0.5, 1e-5);
+ BOOST_REQUIRE_CLOSE(hmm.Emission()[0].Probability("1"), 0.5, 1e-5);
BOOST_REQUIRE_CLOSE(hmm.Transition()(0, 0), 1.0, 1e-5);
}
@@ -238,12 +216,12 @@
// [0.5 0.5]]
// Generate observations randomly by hand. This is kinda ugly, but it works.
- std::vector<std::vector<size_t> > observations;
+ std::vector<arma::mat> observations;
size_t obsNum = 250; // Number of observations.
size_t obsLen = 500; // Number of elements in each observation.
for (size_t i = 0; i < obsNum; i++)
{
- std::vector<size_t> observation(obsLen);
+ arma::mat observation(1, obsLen);
size_t state = 0;
size_t emission = 0;
@@ -278,7 +256,7 @@
break;
}
- observation[obs] = emission;
+ observation(0, obs) = emission;
}
observations.push_back(observation);
@@ -292,14 +270,14 @@
BOOST_REQUIRE_CLOSE(hmm.Transition()(0, 1), 0.5, 2.5);
BOOST_REQUIRE_CLOSE(hmm.Transition()(1, 1), 0.5, 2.5);
- BOOST_REQUIRE_CLOSE(hmm.Emission()[0].Probability(0), 0.4, 2.5);
- BOOST_REQUIRE_CLOSE(hmm.Emission()[0].Probability(1), 0.6, 2.5);
- BOOST_REQUIRE_SMALL(hmm.Emission()[0].Probability(2), 2.5);
- BOOST_REQUIRE_SMALL(hmm.Emission()[0].Probability(3), 2.5);
- BOOST_REQUIRE_SMALL(hmm.Emission()[1].Probability(0), 2.5);
- BOOST_REQUIRE_SMALL(hmm.Emission()[1].Probability(1), 2.5);
- BOOST_REQUIRE_CLOSE(hmm.Emission()[1].Probability(2), 0.2, 2.5);
- BOOST_REQUIRE_CLOSE(hmm.Emission()[1].Probability(3), 0.8, 2.5);
+ BOOST_REQUIRE_CLOSE(hmm.Emission()[0].Probability("0"), 0.4, 2.5);
+ BOOST_REQUIRE_CLOSE(hmm.Emission()[0].Probability("1"), 0.6, 2.5);
+ BOOST_REQUIRE_SMALL(hmm.Emission()[0].Probability("2"), 2.5);
+ BOOST_REQUIRE_SMALL(hmm.Emission()[0].Probability("3"), 2.5);
+ BOOST_REQUIRE_SMALL(hmm.Emission()[1].Probability("0"), 2.5);
+ BOOST_REQUIRE_SMALL(hmm.Emission()[1].Probability("1"), 2.5);
+ BOOST_REQUIRE_CLOSE(hmm.Emission()[1].Probability("2"), 0.2, 2.5);
+ BOOST_REQUIRE_CLOSE(hmm.Emission()[1].Probability("3"), 0.8, 2.5);
}
BOOST_AUTO_TEST_CASE(DiscreteHMMLabeledTrainTest)
@@ -321,19 +299,19 @@
size_t obsNum = 250;
size_t obsLen = 800;
- std::vector<std::vector<size_t> > observations(obsNum);
- std::vector<std::vector<size_t> > states(obsNum);
+ std::vector<arma::mat> observations(obsNum);
+ std::vector<arma::Col<size_t> > states(obsNum);
for (size_t n = 0; n < obsNum; n++)
{
- observations[n].resize(obsLen);
- states[n].resize(obsLen);
+ observations[n].set_size(1, obsLen);
+ states[n].set_size(obsLen);
// Random starting state.
states[n][0] = rand() % 3;
// Random starting observation.
- observations[n][0] = emission[states[n][0]].Random();
+ observations[n].col(0) = emission[states[n][0]].Random();
// Now the rest of the observations.
for (size_t t = 1; t < obsLen; t++)
@@ -354,7 +332,7 @@
}
// Decide observation.
- observations[n][t] = emission[states[n][t]].Random();
+ observations[n].col(t) = emission[states[n][t]].Random();
}
}
@@ -373,10 +351,16 @@
0.009);
for (size_t col = 0; col < hmm.Emission().size(); col++)
+ {
for (size_t row = 0; row < hmm.Emission()[col].Probabilities().n_elem;
row++)
- BOOST_REQUIRE_SMALL(hmm.Emission()[col].Probability(row) -
- emission[col].Probability(row), 0.009);
+ {
+ arma::vec obs(1);
+ obs[0] = row;
+ BOOST_REQUIRE_SMALL(hmm.Emission()[col].Probability(obs) -
+ emission[col].Probability(obs), 0.009);
+ }
+ }
}
/**
@@ -391,8 +375,8 @@
HMM<DiscreteDistribution> hmm(2, DiscreteDistribution(4));
// Now generate a really, really long sequence.
- std::vector<size_t> dataSeq;
- std::vector<size_t> stateSeq;
+ arma::mat dataSeq;
+ arma::Col<size_t> stateSeq;
hmm.Generate(100000, dataSeq, stateSeq);
@@ -401,7 +385,7 @@
arma::vec stateProb(2);
for (size_t i = 0; i < 100000; i++)
{
- emissionProb[dataSeq[i]]++;
+ emissionProb[(size_t) dataSeq.col(i)[0] + 0.5]++;
stateProb[stateSeq[i]]++;
}
@@ -419,7 +403,7 @@
BOOST_REQUIRE_CLOSE(stateProb[1], 0.50, 2.0);
}
-/***
+/**
* More complex test for Generate().
*/
BOOST_AUTO_TEST_CASE(DiscreteHMMGenerateTest)
@@ -444,8 +428,8 @@
// We'll create a bunch of sequences.
int numSeq = 400;
int numObs = 3000;
- std::vector<std::vector<size_t> > sequences(numSeq);
- std::vector<std::vector<size_t> > states(numSeq);
+ std::vector<arma::mat> sequences(numSeq);
+ std::vector<arma::Col<size_t> > states(numSeq);
for (int i = 0; i < numSeq; i++)
{
// Random starting state.
@@ -465,9 +449,15 @@
hmm2.Transition()(row, col), 0.005);
for (size_t row = 0; row < 6; row++)
+ {
+ arma::vec obs(1);
+ obs[0] = row;
for (size_t col = 0; col < 4; col++)
- BOOST_REQUIRE_SMALL(hmm.Emission()[col].Probability(row) -
- hmm2.Emission()[col].Probability(row), 0.005);
+ {
+ BOOST_REQUIRE_SMALL(hmm.Emission()[col].Probability(obs) -
+ hmm2.Emission()[col].Probability(obs), 0.005);
+ }
+ }
}
BOOST_AUTO_TEST_CASE(DiscreteHMMLogLikelihoodTest)
@@ -485,44 +475,11 @@
// Now generate some sequences and check that the log-likelihood is the same
// as MATLAB gives for this HMM.
- std::vector<size_t> seq(4);
- seq[0] = 0;
- seq[1] = 1;
- seq[2] = 2;
- seq[3] = 3;
- BOOST_REQUIRE_CLOSE(hmm.LogLikelihood(seq), -4.9887223949, 1e-5);
-
- seq[0] = 1;
- seq[1] = 2;
- seq[2] = 0;
- seq[3] = 0;
- BOOST_REQUIRE_CLOSE(hmm.LogLikelihood(seq), -6.0288487077, 1e-5);
-
- seq[0] = 3;
- seq[1] = 3;
- seq[2] = 3;
- seq[3] = 3;
- BOOST_REQUIRE_CLOSE(hmm.LogLikelihood(seq), -5.5544000018, 1e-5);
-
- seq.resize(17);
- seq[0] = 0;
- seq[1] = 2;
- seq[2] = 2;
- seq[3] = 1;
- seq[4] = 2;
- seq[5] = 3;
- seq[6] = 0;
- seq[7] = 0;
- seq[8] = 1;
- seq[9] = 3;
- seq[10] = 1;
- seq[11] = 0;
- seq[12] = 0;
- seq[13] = 3;
- seq[14] = 1;
- seq[15] = 2;
- seq[16] = 2;
- BOOST_REQUIRE_CLOSE(hmm.LogLikelihood(seq), -24.51556128368, 1e-5);
+ BOOST_REQUIRE_CLOSE(hmm.LogLikelihood("0 1 2 3"), -4.9887223949, 1e-5);
+ BOOST_REQUIRE_CLOSE(hmm.LogLikelihood("1 2 0 0"), -6.0288487077, 1e-5);
+ BOOST_REQUIRE_CLOSE(hmm.LogLikelihood("3 3 3 3"), -5.5544000018, 1e-5);
+ BOOST_REQUIRE_CLOSE(hmm.LogLikelihood("0 2 2 1 2 3 0 0 1 3 1 0 0 3 1 2 2"),
+ -24.51556128368, 1e-5);
}
/**
@@ -549,12 +506,12 @@
HMM<GaussianDistribution> hmm(transition, emission);
// Now, generate some sequences.
- std::vector<arma::vec> observations(1000);
- std::vector<size_t> classes(1000);
+ arma::mat observations(2, 1000);
+ arma::Col<size_t> classes(1000);
// 1000-observations sequence.
classes[0] = 0;
- observations[0] = g1.Random();
+ observations.col(0) = g1.Random();
for (size_t i = 1; i < 1000; i++)
{
double randValue = (double) rand() / (double) RAND_MAX;
@@ -565,13 +522,13 @@
classes[i] = classes[i - 1];
if (classes[i] == 0)
- observations[i] = g1.Random();
+ observations.col(i) = g1.Random();
else
- observations[i] = g2.Random();
+ observations.col(i) = g2.Random();
}
// Now predict the sequence.
- std::vector<size_t> predictedClasses;
+ arma::Col<size_t> predictedClasses;
arma::mat stateProb;
hmm.Predict(observations, predictedClasses);
@@ -611,17 +568,17 @@
"0.4 0.1 0.2");
// Now generate observations.
- std::vector<std::vector<arma::vec> > observations(100);
- std::vector<std::vector<size_t> > states(100);
+ std::vector<arma::mat> observations(100);
+ std::vector<arma::Col<size_t> > states(100);
for (size_t obs = 0; obs < 100; obs++)
{
- observations[obs].resize(1000);
- states[obs].resize(1000);
+ observations[obs].set_size(3, 1000);
+ states[obs].set_size(1000);
// Always start in state zero.
states[obs][0] = 0;
- observations[obs][0] = emission[0].Random();
+ observations[obs].col(0) = emission[0].Random();
for (size_t t = 1; t < 1000; t++)
{
@@ -639,7 +596,7 @@
}
// Now choose the emission.
- observations[obs][t] = emission[states[obs][t]].Random();
+ observations[obs].col(t) = emission[states[obs][t]].Random();
}
}
@@ -724,8 +681,8 @@
hmm.Emission()[2] = GaussianDistribution("-2.0 1.0", "2.0 0.1; 0.1 1.0");
// Now we will generate a long sequence.
- std::vector<std::vector<arma::vec> > observations(1);
- std::vector<std::vector<size_t> > states(1);
+ std::vector<arma::mat> observations(1);
+ std::vector<arma::Col<size_t> > states(1);
// Start in state 1 (no reason).
hmm.Generate(10000, observations[0], states[0], 1);
More information about the mlpack-svn
mailing list