39 #include <unordered_map>
44 const std::vector<double> &class_prior)
45 : alpha(alpha_param), fit_prior(fit_prior_param),
46 class_log_prior(class_prior.begin(), class_prior.end()) {
53 const std::vector<std::string> &labels) {
55 for (
const auto &label : labels) {
56 class_probs[label] += 1.0;
60 for (
size_t i = 0; i < data.size(); ++i) {
61 const std::string &label = labels[i];
62 const std::vector<double> &features = data[i];
64 class_probs[label] += 1.0;
67 if (feature_probs.find(label) == feature_probs.end()) {
68 feature_probs[label] = std::vector<double>(features.size(), 0.0);
71 for (
size_t j = 0; j < features.size(); ++j) {
72 feature_probs[label][j] += features[j];
77 double smoothing_factor = alpha * 2.0;
78 for (
const auto &entry : class_probs) {
79 const std::string &label = entry.first;
80 double class_count = entry.second;
84 (class_count + alpha) / (data.size() + smoothing_factor);
87 for (
size_t j = 0; j < feature_probs[label].size(); ++j) {
88 feature_probs[label][j] = (feature_probs[label][j] + alpha) /
89 (class_count + smoothing_factor);
95 double total = std::accumulate(
99 [](
double sum,
const auto &entry) { return sum + entry.second; });
101 for (
auto &entry : class_probs) {
102 entry.second /= total;
108 class_log_prior.begin(),
109 [total](
const auto &entry) { return log(entry.second); });
115 double max_prob = -std::numeric_limits<double>::infinity();
116 std::string predicted_class;
118 for (
const auto &entry : class_probs) {
119 const std::string &label = entry.first;
120 double probability = log(entry.second);
122 for (
size_t j = 0; j < new_data.size(); ++j) {
123 probability += new_data[j] * log(feature_probs.at(label).at(j));
126 if (probability > max_prob) {
127 max_prob = probability;
128 predicted_class = label;
132 return predicted_class;
136 std::cout <<
"Class Probabilities:\n";
137 for (
const auto &entry : class_probs) {
138 std::cout << entry.first <<
": " << entry.second <<
"\n";
141 std::cout <<
"\nFeature Probabilities:\n";
142 for (
const auto &class_entry : feature_probs) {
143 std::cout << class_entry.first <<
":\n";
144 for (
size_t j = 0; j < class_entry.second.size(); ++j) {
145 std::cout <<
" Feature " << j <<
": " << class_entry.second[j]
150 std::cout <<
"\nClass Log Priors:\n";
151 for (
const auto &logPrior : class_log_prior) {
152 std::cout << logPrior <<
"\n";
156 const std::vector<std::vector<size_t>> &data,
157 const std::vector<std::string> &labels) {
158 size_t numInstances = data.size();
159 size_t num_feats = data[0].size();
161 for (
size_t i = 0; i < numInstances; ++i) {
162 std::string classLabel = labels[i];
165 class_probs[classLabel] += 1.0;
168 for (
size_t j = 0; j < num_feats; ++j) {
169 feat_probs[classLabel][j] += data[i][j];
174 double smoothing_factor = alpha * 2.0;
175 for (
auto &entry : class_probs) {
177 (entry.second + alpha) / (numInstances + smoothing_factor);
180 for (
auto &class_entry : feat_probs) {
181 for (
auto &feat_entry : class_entry.second) {
183 (feat_entry.second + alpha) /
184 (class_probs[class_entry.first] + smoothing_factor);
192 double max_prob = -std::numeric_limits<double>::infinity();
193 std::string predicted_class;
195 for (
const auto &class_entry : class_probs) {
196 double probability = log(class_entry.second);
198 for (
size_t i = 0; i < new_data.size(); ++i) {
200 new_data[i] * log(feat_probs.at(class_entry.first).at(i));
203 if (probability > max_prob) {
204 max_prob = probability;
205 predicted_class = class_entry.first;
209 return predicted_class;
213 std::cout <<
"Class Probabilities:\n";
214 for (
const auto &entry : class_probs) {
215 std::cout << entry.first <<
": " << entry.second <<
"\n";
218 std::cout <<
"\nFeature Probabilities:\n";
219 for (
const auto &class_entry : feat_probs) {
220 std::cout << class_entry.first <<
":\n";
221 for (
const auto &feat_entry : class_entry.second) {
222 std::cout <<
" Feature " << feat_entry.first <<
": "
223 << feat_entry.second <<
"\n";
229 const std::vector<std::string> &labels) {
231 for (
const auto &label : labels) {
232 class_probs[label] += 1.0;
236 mean_and_var(data, labels);
239 double total_instances =
static_cast<double>(data.size());
240 for (
auto &entry : class_probs) {
241 entry.second /= total_instances;
246 const std::vector<std::vector<double>> &data,
247 const std::vector<std::string> &labels) {
248 size_t num_features = data[0].size();
250 for (
size_t i = 0; i < data.size(); ++i) {
251 const std::string &label = labels[i];
252 const std::vector<double> &features = data[i];
254 class_probs[label] += 1.0;
257 if (mean.find(label) == mean.end()) {
258 mean[label] = std::vector<double>(num_features, 0.0);
259 variance[label] = std::vector<double>(num_features, 0.0);
263 for (
size_t j = 0; j < num_features; ++j) {
264 mean[label][j] += features[j];
269 for (
auto &entry : mean) {
270 const std::string &label = entry.first;
271 double class_count = class_probs[label];
273 for (
size_t j = 0; j < num_features; ++j) {
274 entry.second[j] /= class_count;
279 for (
size_t i = 0; i < data.size(); ++i) {
280 const std::string &label = labels[i];
281 const std::vector<double> &features = data[i];
283 for (
size_t j = 0; j < num_features; ++j) {
284 variance[label][j] += std::pow(features[j] - mean[label][j], 2);
288 for (
auto &entry : variance) {
289 const std::string &label = entry.first;
290 double class_count = class_probs[label];
292 for (
size_t j = 0; j < num_features; ++j) {
293 entry.second[j] /= class_count;
300 double max_prob = -std::numeric_limits<double>::infinity();
301 std::string predicted_class;
303 for (
const auto &entry : class_probs) {
304 const std::string &label = entry.first;
305 double probability = log(entry.second);
307 for (
size_t j = 0; j < newData.size(); ++j) {
309 0.5 * (std::log(2 * M_PI * variance.at(label).at(j)) +
310 std::pow(newData[j] - mean.at(label).at(j), 2) /
311 (2 * variance.at(label).at(j)));
314 if (probability > max_prob) {
315 max_prob = probability;
316 predicted_class = label;
320 return predicted_class;
324 std::cout <<
"Class Probabilities:\n";
325 for (
const auto &entry : class_probs) {
326 std::cout << entry.first <<
": " << entry.second <<
"\n";
329 std::cout <<
"\nMean and Variance:\n";
330 for (
const auto &class_entry : mean) {
331 std::cout << class_entry.first <<
":\n";
332 std::cout <<
" Mean: ";
333 for (
size_t j = 0; j < class_entry.second.size(); ++j) {
334 std::cout << class_entry.second[j] <<
" ";
336 std::cout <<
"\n Variance: ";
337 for (
size_t j = 0; j < variance.at(class_entry.first).size(); ++j) {
338 std::cout << variance.at(class_entry.first).at(j) <<
" ";
345 bool fit_prior_param,
346 const std::vector<double> &class_prior)
347 : alpha(alpha_param), fit_prior(fit_prior_param),
348 class_log_prior(class_prior.begin(), class_prior.end()) {
355 const std::vector<std::vector<size_t>> &data,
356 const std::vector<std::string> &labels) {
357 size_t num_instances = data.size();
358 size_t num_features = data[0].size();
361 for (
const auto &label : labels) {
362 class_probs[label] += 1.0;
366 for (
size_t i = 0; i < num_instances; ++i) {
367 const std::string &label = labels[i];
368 const std::vector<size_t> &features = data[i];
370 class_probs[label] += 1.0;
373 if (feature_probs.find(label) == feature_probs.end()) {
374 feature_probs[label] = std::vector<double>(num_features, 0.0);
377 for (
size_t j = 0; j < num_features; ++j) {
378 feature_probs[label][j] += features[j];
383 double smoothing_factor = alpha * num_features;
384 for (
const auto &entry : class_probs) {
385 const std::string &label = entry.first;
386 double class_count = entry.second;
390 (class_count + alpha) / (num_instances + smoothing_factor);
393 for (
size_t j = 0; j < feature_probs[label].size(); ++j) {
394 feature_probs[label][j] = (feature_probs[label][j] + alpha) /
395 (class_count + smoothing_factor);
401 double total = std::accumulate(
405 [](
double sum,
const auto &entry) { return sum + entry.second; });
407 for (
auto &entry : class_probs) {
408 entry.second /= total;
414 class_log_prior.begin(),
415 [total](
const auto &entry) { return log(entry.second); });
421 double max_prob = -std::numeric_limits<double>::infinity();
422 std::string predicted_class;
424 for (
const auto &entry : class_probs) {
425 const std::string &label = entry.first;
426 double probability = log(entry.second);
428 for (
size_t j = 0; j < new_data.size(); ++j) {
429 probability += new_data[j] * log(feature_probs.at(label).at(j));
432 if (probability > max_prob) {
433 max_prob = probability;
434 predicted_class = label;
438 return predicted_class;
442 std::cout <<
"Class Probabilities:\n";
443 for (
const auto &entry : class_probs) {
444 std::cout << entry.first <<
": " << entry.second <<
"\n";
447 std::cout <<
"\nFeature Probabilities:\n";
448 for (
const auto &class_entry : feature_probs) {
449 std::cout << class_entry.first <<
":\n";
450 for (
size_t j = 0; j < class_entry.second.size(); ++j) {
451 std::cout <<
" Feature " << j <<
": " << class_entry.second[j]
456 std::cout <<
"\nClass Log Priors:\n";
457 for (
const auto &log_prior : class_log_prior) {
458 std::cout << log_prior <<
"\n";
void train(const std::vector< std::vector< size_t >> &data, const std::vector< std::string > &labels)
Train the classifier with a set of labeled data.
void display() const
Display the learned probabilities.
std::string predict(const std::vector< size_t > &newData) const
Predict the class of a new data point.
~BayesClf()
Destructor for BayesClf class.
void train(const std::vector< std::vector< double >> &data, const std::vector< std::string > &labels)
Train the classifier with a set of labeled data.
void display() const
Display the learned probabilities.
std::string predict(const std::vector< double > &newData) const
Predict the class of a new data point.
BayesClf(double alpha_param=1.0, bool fit_prior_param=true, const std::vector< double > &class_prior={})
Constructor for BayesClf class.
void display() const
Display the learned probabilities.
void mean_and_var(const std::vector< std::vector< double >> &data, const std::vector< std::string > &labels)
Calculate the mean and variance for each class.
std::string predict(const std::vector< double > &newData) const
Predict the class of a new data point.
void train(const std::vector< std::vector< double >> &data, const std::vector< std::string > &labels)
Train the classifier with a set of labeled data.
void train(const std::vector< std::vector< size_t >> &data, const std::vector< std::string > &labels)
Train the classifier with a set of labeled data.
std::string predict(const std::vector< size_t > &new_data) const
Predict the class of a new data point.
~BayesMultiNom()
Destructor for BayesMultiNom class.
void display() const
Display the learned probabilities.
BayesMultiNom(double alpha_param=1.0, bool fit_prior_param=true, const std::vector< double > &class_prior={})
Constructor for BayesMultiNom class.