The files have been commented and a README file has been included for assistance
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
The files are the following:
|
||||
1. nbc_main.cc - this is the main which creates an object of the class SimpleNaiveBayesClassifier, trains it, tests it and outputs the results. The executable formed is called "simple_nbc_main".
|
||||
- the parameters taken in by the main are the following:
|
||||
--training_data : the file that contains the training data, the last column being the class of the data point
|
||||
--number_of_classes : the number of classes the data provided has been classified into
|
||||
--testing_data : this file contains the testing data, this still contains its actual labels on the last column, but it is not used.
|
||||
--output_filename : the file into which you want the output to be written into, defaults to "output.csv" (but it does not output in .csv format, it outputs in the "pretty-print" format)
|
||||
|
||||
2. simple_nbc.h - this is the file that contains the definition of the class SimpleNaiveBayesClassifier. The rest of the details are present in the file itself.
|
||||
|
||||
3. phi.h - this contains the function that calculates the value of the univariate Gaussian pdf
|
||||
|
||||
4. math_functions.h - this file contains functions like returning the highest element and its index in an array/vector.
|
||||
|
||||
5. test_simple_nbc_main.cc - this file contains the class which tests the class SimpleNaiveBayesClassifier. The executable formed is "test_simple_nbc_main".
|
||||
- the parameters taken in by this are the following:
|
||||
--training_set : the training set, defaults to the file "trainSet.arff"
|
||||
--training_results : the training results, defaults to the file "trainRes.arff"
|
||||
--testing_set : the testing set, defaults to the file "testSet.arff"
|
||||
--testing_results : the testing results, defaults to the file "testRes.arff"
|
||||
--num_classes : the number of classes in the data, defaults to "2", which in the number of classes of the data present in the default files
|
||||
|
||||
6. the .arff files, whose use has been described above.
|
||||
|
||||
7. build.py - you might want to take a look at them for the purpose of seeing what all files are used where.
|
||||
|
||||
-> An example run would the following:
|
||||
fl-build simple_nbc_main
|
||||
./simple_nbc_main --training_data=trainSet.arff --number_of_classes=2 --testing_data=testSet.arff --output_filename=output_example.csv
|
||||
|
||||
-> An example run of the testing class would be the following:
|
||||
fl-build test_simple_nbc_main
|
||||
./test_simple_nbc_main
|
||||
|
||||
Note: you don't need to give any parameters for testing because it will use the defaults. In case you want to give your own training and test sets, you know how to do it.
|
||||
@@ -3,6 +3,26 @@
|
||||
*
|
||||
* This program test drives the Simple Naive Bayes Classifier
|
||||
*
|
||||
* This classifier does parametric naive bayes classification
|
||||
* assuming that the features are sampled from a Gaussian
|
||||
* distribution.
|
||||
*
|
||||
* PARAMETERS TO BE INPUT:
|
||||
*
|
||||
* --training_data
|
||||
* This is the file that contains the training data
|
||||
*
|
||||
* --number_of_classes
|
||||
* This is the number of classes present in the training data
|
||||
*
|
||||
* --testing_data
|
||||
* This file contains the data points which the trained
|
||||
* classifier would classify
|
||||
*
|
||||
* --output_filename
|
||||
* This file will contain the classes to which the corresponding
|
||||
* data points in the testing data
|
||||
*
|
||||
*/
|
||||
#include "simple_nbc.h"
|
||||
|
||||
@@ -23,6 +43,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
////// SIMPLE NAIVE BAYES CLASSIFICATION ASSUMING THE DATA TO BE UNIFORMLY DISTRIBUTED //////
|
||||
|
||||
////// Declaration of an object of the class SimpleNaiveBayesClassifier
|
||||
SimpleNaiveBayesClassifier nbc;
|
||||
|
||||
struct datanode* nbc_module = fx_submodule(NULL, "simple_nbc", "simple_nbc_module");
|
||||
@@ -31,15 +52,18 @@ int main(int argc, char* argv[]) {
|
||||
////// Timing the training of the Naive Bayes Classifier //////
|
||||
fx_timer_start(nbc_module, "training_classifier");
|
||||
|
||||
////// Calling the function that trains the classifier
|
||||
nbc.InitTrain(training_data, number_of_classes);
|
||||
|
||||
fx_timer_stop(nbc_module, "training_classifier");
|
||||
|
||||
////// Timing the testing of the Naive Bayes Classifier //////
|
||||
////// The variable that contains the result of the classification
|
||||
Vector results;
|
||||
|
||||
fx_timer_start(nbc_module, "testing_classifier");
|
||||
|
||||
////// Calling the function that classifies the test data
|
||||
nbc.Classify(testing_data, &results);
|
||||
|
||||
fx_timer_stop(nbc_module, "testing_classifier");
|
||||
|
||||
@@ -1,23 +1,67 @@
|
||||
/**
|
||||
* @file simple_nbc.h
|
||||
*
|
||||
* A Simple Naive Bayes Classifier assuming that the data
|
||||
* is generated from a gaussian distribution
|
||||
* A Naive Bayes Classifier which parametrically
|
||||
* estimates the distribution of the features.
|
||||
* It is assumed that the features have been
|
||||
* sampled from a Gaussian PDF
|
||||
*
|
||||
*/
|
||||
#ifndef NBC_H
|
||||
#define NBC_H
|
||||
|
||||
#include "fastlib/fastlib.h"
|
||||
#include "phi.h"
|
||||
#include "math_functions.h"
|
||||
|
||||
/**
|
||||
* A classification class. The class labels are assumed
|
||||
* to be positive integers - 0,1,2,....
|
||||
*
|
||||
* This class trains on the data by calculating the
|
||||
* sample mean and variance of the features with
|
||||
* respect to each of the labels, and also the class
|
||||
* probabilities.
|
||||
*
|
||||
* Mathematically, it computes P(X_i = x_i | Y = y_j)
|
||||
* for each feature X_i for each of the labels y_j.
|
||||
* Alongwith this, it also computes the classs probabilities
|
||||
* P( Y = y_j)
|
||||
*
|
||||
* For classifying a data point (x_1, x_2, ..., x_n),
|
||||
* it computes the following:
|
||||
* arg max_y(P(Y = y)*P(X_1 = x_1 | Y = y) * ... * P(X_n = x_n | Y = y))
|
||||
*
|
||||
* Example use:
|
||||
*
|
||||
* @code
|
||||
* SimpleNaiveBayesClassifier nbc;
|
||||
* Vector results;
|
||||
*
|
||||
* nbc.InitTrain(training_data, number_of_classes);
|
||||
* nbc.Classify(testing_data, &results);
|
||||
* @endcode
|
||||
*/
|
||||
class SimpleNaiveBayesClassifier {
|
||||
|
||||
// The class for testing this class is made a friend class
|
||||
friend class TestClassSimpleNBC;
|
||||
|
||||
private:
|
||||
|
||||
// The variables containing the sample mean and variance
|
||||
// for each of the features with respect to each class
|
||||
Matrix means_, variances_;
|
||||
|
||||
// The variable containing the class probabilities
|
||||
ArrayList<double> class_probabilities_;
|
||||
|
||||
// The variable keeping the information about the
|
||||
// number of classes present
|
||||
index_t number_of_classes_;
|
||||
|
||||
public:
|
||||
|
||||
SimpleNaiveBayesClassifier(){
|
||||
means_.Init(0, 0);
|
||||
variances_.Init(0, 0);
|
||||
@@ -32,13 +76,16 @@ class SimpleNaiveBayesClassifier {
|
||||
}
|
||||
|
||||
|
||||
|
||||
// The function that initializes the classifier as per the input
|
||||
// and then trains it by calculating the sample mean and variances
|
||||
void InitTrain(const Matrix& data, int number_of_classes) {
|
||||
|
||||
ArrayList<double> feature_sum, feature_sum_squared;
|
||||
/** the last row are the classes */
|
||||
index_t number_examples = data.n_cols(); // number of examples in the dataset
|
||||
index_t number_features = data.n_rows() - 1; // number of features in each example
|
||||
/** the classes are of the form 0,1,2...,n_classes - 1 */
|
||||
index_t number_examples = data.n_cols();
|
||||
index_t number_features = data.n_rows() - 1;
|
||||
|
||||
// updating the variables, private and local, according to
|
||||
// the number of features and classes present in the data
|
||||
number_of_classes_ = number_of_classes;
|
||||
class_probabilities_.Resize(number_of_classes_);
|
||||
means_.Destruct();
|
||||
@@ -51,8 +98,12 @@ class SimpleNaiveBayesClassifier {
|
||||
feature_sum[k] = 0;
|
||||
feature_sum_squared[k] = 0;
|
||||
}
|
||||
printf("%"LI"d examples with %"LI"d features each\n",number_examples, number_features);
|
||||
// calculating the probablity of occurrence of the individual classes
|
||||
printf("%"LI"d examples with %"LI"d features each\n",
|
||||
number_examples, number_features);
|
||||
|
||||
// calculating the class probabilities as well as the
|
||||
// sample mean and variance for each of the features
|
||||
// with respect to each of the labels
|
||||
for(index_t i = 0; i < number_of_classes_; i++ ) {
|
||||
index_t number_of_occurrences = 0;
|
||||
for (index_t j = 0; j < number_examples; j++) {
|
||||
@@ -66,18 +117,28 @@ class SimpleNaiveBayesClassifier {
|
||||
}
|
||||
}
|
||||
}
|
||||
class_probabilities_[i] = (double)number_of_occurrences / (double)number_examples ;
|
||||
class_probabilities_[i] = (double)number_of_occurrences
|
||||
/ (double)number_examples ;
|
||||
for(index_t k = 0; k < number_features; k++) {
|
||||
means_.set(k, i, (feature_sum[k] / number_of_occurrences));
|
||||
variances_.set(k, i, (feature_sum_squared[k] - (feature_sum[k] * feature_sum[k] / number_of_occurrences)) / (number_of_occurrences - 1));
|
||||
variances_.set(k, i, (feature_sum_squared[k]
|
||||
- (feature_sum[k] * feature_sum[k]
|
||||
/ number_of_occurrences)
|
||||
)/(number_of_occurrences - 1));
|
||||
feature_sum[k] = 0;
|
||||
feature_sum_squared[k] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Given a bunch of data points, this function evaluates the class
|
||||
// of each of those data points, and puts it in the vector 'results'
|
||||
void Classify(const Matrix& test_data, Vector *results){
|
||||
|
||||
// Checking that the number of features in the test data is same
|
||||
// as in the training data
|
||||
DEBUG_ASSERT(test_data.n_rows() - 1 == means_.n_rows());
|
||||
|
||||
ArrayList<double> tmp_vals;
|
||||
double *evaluated_result;
|
||||
index_t number_features = test_data.n_rows() - 1;
|
||||
@@ -85,19 +146,30 @@ class SimpleNaiveBayesClassifier {
|
||||
evaluated_result = (double*)malloc(test_data.n_cols() * sizeof(double));
|
||||
tmp_vals.Init(number_of_classes_);
|
||||
|
||||
printf("%"LI"d test cases with %"LI"d features each\n", test_data.n_cols(), number_features);
|
||||
printf("%"LI"d test cases with %"LI"d features each\n",
|
||||
test_data.n_cols(), number_features);
|
||||
|
||||
// Calculating the joint probability for each of the data points
|
||||
// for each of the classes
|
||||
for (index_t n = 0; n < test_data.n_cols(); n++) {
|
||||
for (index_t i = 0; i < number_of_classes_; i++) {
|
||||
// Using the log values to prevent floating point underflow
|
||||
tmp_vals[i] = log(class_probabilities_[i]);
|
||||
for (index_t j = 0; j < number_features; j++) {
|
||||
tmp_vals[i] += log(phi(test_data.get(j, n), means_.get(j, i), variances_.get(j, i)));
|
||||
tmp_vals[i] += log(phi(test_data.get(j, n),
|
||||
means_.get(j, i),
|
||||
variances_.get(j, i))
|
||||
);
|
||||
}
|
||||
}
|
||||
// Calling a function 'max_element_index' from the file 'math_functions.h
|
||||
// to obtain the index of the maximum element in an array
|
||||
evaluated_result[n] = (double) max_element_index(tmp_vals);
|
||||
}
|
||||
// The result is being put in a vector
|
||||
(*results).Copy(evaluated_result, test_data.n_cols());
|
||||
|
||||
return;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user