[mlpack-svn] r14889 - mlpack/trunk/src/mlpack/core/dists
fastlab-svn at coffeetalk-1.cc.gatech.edu
fastlab-svn at coffeetalk-1.cc.gatech.edu
Wed Apr 10 17:09:46 EDT 2013
Author: rcurtin
Date: 2013-04-10 17:09:46 -0400 (Wed, 10 Apr 2013)
New Revision: 14889
Modified:
mlpack/trunk/src/mlpack/core/dists/gaussian_distribution.cpp
Log:
Put in checks for non-invertible covariances after training; add perturbation to
avoid them where necessary. Also avoid dividing by zero.
Modified: mlpack/trunk/src/mlpack/core/dists/gaussian_distribution.cpp
===================================================================
--- mlpack/trunk/src/mlpack/core/dists/gaussian_distribution.cpp 2013-04-10 19:41:43 UTC (rev 14888)
+++ mlpack/trunk/src/mlpack/core/dists/gaussian_distribution.cpp 2013-04-10 21:09:46 UTC (rev 14889)
@@ -22,8 +22,6 @@
*/
void GaussianDistribution::Estimate(const arma::mat& observations)
{
- // Calculate the mean and covariance with each point. Because this is a
- // std::vector and not a matrix, this is a little more difficult.
if (observations.n_cols > 0)
{
mean.zeros(observations.n_rows);
@@ -33,6 +31,7 @@
{
mean.zeros(0);
covariance.zeros(0);
+ return;
}
// Calculate the mean.
@@ -52,6 +51,17 @@
// Finish estimating the covariance by normalizing, with the (1 / (n - 1)) so
// that it is the unbiased estimator.
covariance /= (observations.n_cols - 1);
+
+ // Ensure that there are no zeros on the diagonal.
+ for (size_t d = 0; d < covariance.n_rows; ++d)
+ {
+ if (covariance(d, d) == 0.0)
+ {
+ Log::Debug << "GaussianDistribution::Estimate(): covariance diagonal "
+ << "element " << d << " is 0; adding perturbation." << std::endl;
+ covariance(d, d) = 1e-50;
+ }
+ }
}
/**
@@ -71,6 +81,7 @@
{
mean.zeros(0);
covariance.zeros(0);
+ return;
}
double sumProb = 0;
@@ -83,6 +94,14 @@
sumProb += probabilities[i];
}
+ if (sumProb == 0)
+ {
+ // Nothing in this Gaussian! At least set the covariance so that it's
+ // invertible.
+ covariance.diag() += 1e-50;
+ return;
+ }
+
// Normalize.
mean /= sumProb;
@@ -96,6 +115,16 @@
// This is probably biased, but I don't know how to unbias it.
covariance /= sumProb;
+ // Ensure that there are no zeros on the diagonal.
+ for (size_t d = 0; d < covariance.n_rows; ++d)
+ {
+ if (covariance(d, d) == 0.0)
+ {
+ Log::Debug << "GaussianDistribution::Estimate(): covariance diagonal "
+ << "element " << d << " is 0; adding perturbation." << std::endl;
+ covariance(d, d) = 1e-50;
+ }
+ }
}
/**
More information about the mlpack-svn
mailing list