void NaiveBayesClassifier<MatType>::Classify(const MatType& data,
                                             arma::Row<size_t>& results)
{
  // Check that the number of features in the test data is same as in the
  // training data.
  Log::Assert(data.n_rows == means.n_rows);

  arma::vec probs = arma::log(probabilities);
  arma::mat invVar = 1.0 / variances;

  arma::mat testProbs = arma::repmat(probs.t(), data.n_cols, 1);

  results.set_size(data.n_cols); // No need to fill with anything yet.

  Log::Info << "Running Naive Bayes classifier on " << data.n_cols
      << " data points with " << data.n_rows << " features each." << std::endl;

  // Calculate the joint probability for each of the data points for each of the
  // means.n_cols.

  // Loop over every class.
  for (size_t i = 0; i < means.n_cols; i++)
  {
    // This is an adaptation of gmm::phi() for the case where the covariance is
    // a diagonal matrix.
    arma::mat diffs = data - arma::repmat(means.col(i), 1, data.n_cols);
    arma::mat rhs = -0.5 * arma::diagmat(invVar.col(i)) * diffs;
    arma::vec exponents(diffs.n_cols);
    for (size_t j = 0; j < diffs.n_cols; ++j) // log(exp(value)) == value
      exponents(j) = arma::accu(diffs.col(j) % rhs.unsafe_col(j));

    // Calculate probability as sum of logarithm to decrease floating point
    // errors.
    testProbs.col(i) += (data.n_rows / -2.0 * log(2 * M_PI) - 0.5 *
        log(arma::det(arma::diagmat(variances.col(i)))) + exponents);
  }

  // Now calculate the label.
  for (size_t i = 0; i < data.n_cols; ++i)
  {
    // Find the index of the class with maximum probability for this point.
    arma::uword maxIndex = 0;
    arma::vec pointProbs = testProbs.row(i).t();
    pointProbs.max(maxIndex);

    results[i] = maxIndex;
  }

  return;
}
예제 #2
0
/**
 * Calculates the multivariate Gaussian probability density function for each
 * data point (column) in the given matrix, with respect to the given mean and
 * variance.
 *
 * @param x List of observations.
 * @param mean Mean of multivariate Gaussian.
 * @param cov Covariance of multivariate Gaussian.
 * @param probabilities Output probabilities for each input observation.
 */
inline void phi(const arma::mat& x,
                const arma::vec& mean,
                const arma::mat& cov,
                arma::vec& probabilities)
{
  // Column i of 'diffs' is the difference between x.col(i) and the mean.
  arma::mat diffs = x - (mean * arma::ones<arma::rowvec>(x.n_cols));

  // Now, we only want to calculate the diagonal elements of (diffs' * cov^-1 *
  // diffs).  We just don't need any of the other elements.  We can calculate
  // the right hand part of the equation (instead of the left side) so that
  // later we are referencing columns, not rows -- that is faster.
  arma::mat rhs = -0.5 * inv(cov) * diffs;
  arma::vec exponents(diffs.n_cols); // We will now fill this.
  for (size_t i = 0; i < diffs.n_cols; i++)
    exponents(i) = exp(accu(diffs.unsafe_col(i) % rhs.unsafe_col(i)));

  probabilities = pow(2 * M_PI, (double) mean.n_elem / -2.0) *
      pow(det(cov), -0.5) * exponents;
}
예제 #3
0
	Eigen::MatrixXd build_exponents(size_t max_exponent,size_t xdimensions)
	{	
		std::vector<size_t> current_exponent_scratch(xdimensions);
		std::vector<std::vector<size_t>> output_list;
		size_t maxtop=1;
		for(size_t k=0;k<xdimensions;k++)
		{
			maxtop*=max_exponent;
		}
		for(size_t ei=0;ei<maxtop;ei++)
		{
			current_exponent_scratch.resize(xdimensions,0);
			size_t cei=ei;
			size_t total=0;
			for(size_t k=0;k<xdimensions;k++)
			{
				size_t remainder=cei % max_exponent;
				current_exponent_scratch[k]=remainder;
				total+=remainder;
				cei/=max_exponent;
				if(cei == 0) break;
			}
			if(total <= max_exponent)
			{
				output_list.emplace_back(current_exponent_scratch);
			}
		}
		
		Eigen::MatrixXd exponents(xdimensions,output_list.size()); //exponent at dimension R for position col C
		for(size_t c=0;c<exponents.cols();c++)
		{
			const vector<double> srcrows&=output_list[c];
			for(size_t r=0;r<exponents.rows();r++)
			{
				exponents(r,c)=srcrows[r];
			}
		}
		return exponents;
	}
예제 #4
0
void SimultaneousMultiplication(Iterator result, const AbstractGroup<Element> &group, const Element &base, ConstIterator expBegin, ConstIterator expEnd)
{
	unsigned int expCount = std::distance(expBegin, expEnd);

	std::vector<WindowSlider<Element> > exponents(expCount);
	unsigned int i;

	bool notDone = false;
	for (i=0; i<expCount; i++)
		notDone = exponents[i].FindFirstWindow(group, *expBegin++) || notDone;

	unsigned int expBitPosition = 0;
	Element g = base;
	while (notDone)
	{
		notDone = false;
		for (i=0; i<expCount; i++)
		{
			if (expBitPosition < exponents[i].expLen && expBitPosition == exponents[i].windowBegin)
			{
				Element &bucket = exponents[i].buckets[exponents[i].nextBucket];
				group.Accumulate(bucket, g);
				exponents[i].FindNextWindow();
			}
			notDone = notDone || exponents[i].windowBegin < exponents[i].expLen;
		}

		if (notDone)
		{
			g = group.Double(g);
			expBitPosition++;
		}
	}

	for (i=0; i<expCount; i++)
	{
		Element &r = *result++;
		std::vector<Element> &buckets = exponents[i].buckets;
		r = buckets[buckets.size()-1];
		if (buckets.size() > 1)
		{
			for (int j = buckets.size()-2; j >= 1; j--)
			{
				group.Accumulate(buckets[j], buckets[j+1]);
				group.Accumulate(r, buckets[j]);
			}
			group.Accumulate(buckets[0], buckets[1]);
			r = group.Add(group.Double(r), buckets[0]);
		}
	}
}