📄 naivebayesclassifier.cpp
字号:
//-------------------------------------------------------------------// Author........: Aleksander 豩rn// Date..........:// Description...:// Revisions.....://===================================================================#include <stdafx.h> // Precompiled headers.#include <copyright.h>#include <kernel/algorithms/naivebayesclassifier.h>#include <kernel/algorithms/keyword.h>#include <kernel/structures/informationvector.h>#include <kernel/structures/classification.h>#include <kernel/structures/decisiontable.h>#include <kernel/structures/dictionary.h>#include <kernel/structures/rules.h>#include <kernel/utilities/creator.h>//-------------------------------------------------------------------// Methods for class NaiveBayesClassifier.//===================================================================//-------------------------------------------------------------------// Constructors/destructor.//===================================================================NaiveBayesClassifier::NaiveBayesClassifier() { decision_attribute_ = Undefined::Integer();}NaiveBayesClassifier::~NaiveBayesClassifier() {}//-------------------------------------------------------------------// Methods inherited from Identifier.//===================================================================IMPLEMENTIDMETHODS(NaiveBayesClassifier, NAIVEBAYESCLASSIFIER, Classifier)//-------------------------------------------------------------------// Methods inherited from Algorithm.//===================================================================//-------------------------------------------------------------------// Method........: GetParameters// Author........: Aleksander 豩rn// Date..........:// Description...:// Comments......:// Revisions.....://===================================================================StringNaiveBayesClassifier::GetParameters() const { String parameters; parameters += Keyword::DecisionTable(); parameters += Keyword::Assignment(); if (GetDecisionTable() != NULL) parameters += GetDecisionTable()->GetName(); else parameters += "NULL"; return parameters;}//-------------------------------------------------------------------// Method........: SetParameter// Author........: Aleksander 豩rn// Date..........:// Description...:// Comments......:// Revisions.....://===================================================================boolNaiveBayesClassifier::SetParameter(const String &keyword, const String &/*value*/) { // The master table cannot currently be set this way. if (keyword == Keyword::DecisionTable()) return false; // Unknown keyword or illegal value. return false;}//-------------------------------------------------------------------// Method........: Apply// Author........: Aleksander 豩rn// Date..........:// Description...:// Comments......: Assumes that library clients use handles.// Revisions.....://===================================================================Structure *NaiveBayesClassifier::Apply(Structure &structure) const { // Check input type. if (!IsApplicable(structure)) return NULL; // Cast to verified type. Handle<InformationVector> inf = dynamic_cast(InformationVector *, &structure); int i, no_attributes = inf->GetNoAttributes(); // Briefly verify compatibility. if (no_attributes != conditionals_.size()) return NULL; if (decision_attribute_ < 0 || decision_attribute_ >= no_attributes) return NULL; // Create result structure. Handle<Classification> classification = Creator::Classification(); PPMap::const_iterator it1; CPMap::const_iterator it2; // Consider each possible decision value in turn. for (it1 = priors_.begin(); it1 != priors_.end(); it1++) { int decision = (*it1).first; double probability = (*it1).second; // Compute product of conditional probabilities. for (i = 0; i < no_attributes; i++) { // Only consider condition attributes. if (i == decision_attribute_) continue; int condition = inf->GetEntry(i); // Skip missing values. if (condition == Undefined::Integer()) continue; IIPair iipair(condition, decision); // Lookup conditional probability. it2 = conditionals_[i].find(iipair); if (it2 == conditionals_[i].end()) { probability = 0.0; break; } probability *= (*it2).second; } if (probability != 0.0) classification->AppendDecisionValue(decision, probability); } if (classification->GetNoDecisionValues() > 0) { classification->SetDecisionAttribute(decision_attribute_); classification->Normalize(); classification->Sort(); return classification.Release(); } return NULL;}//-------------------------------------------------------------------// Methods inherited from Classifier.//===================================================================//-------------------------------------------------------------------// Method........: IsCompatible// Author........: Aleksander 豩rn// Date..........:// Description...: Is this classifier compatible with information vectors// extracted from the given decision table?// Comments......:// Revisions.....://===================================================================boolNaiveBayesClassifier::IsCompatible(const DecisionTable &table, bool masked) const { // Check compatibility between tables. if (GetDecisionTable() == NULL) { Message::Error("No master decision table set.", false); return false; } if (GetDecisionTable().GetPointer() == &table) return true; if (GetDecisionTable()->GetNoAttributes(masked) != table.GetNoAttributes(masked)) { Message::Error("Mismatch in decision table dimensions.", false); return false; } // May the coding schemes be different? if (!table.HasDictionary() && !GetDecisionTable()->HasDictionary()) { // None of the tables have associated dictionaries. return true; } else if ((table.HasDictionary() && !GetDecisionTable()->HasDictionary()) || // Only one table has an associated dictionary. (!table.HasDictionary() && GetDecisionTable()->HasDictionary())) { Message::Warning("The coding schemes used by the decision tables may be different!", false); return true; } else { // Both tables have associated dictionaries. Handle<Dictionary> dict1 = table.GetDictionary(); Handle<Dictionary> dict2 = GetDecisionTable()->GetDictionary(); if (!(dict1->IsCompatible(*dict2))) { Message::Warning("Possibly different coding schemes in use by decision tables.", false); return true; } } return true;}//-------------------------------------------------------------------// Method........: Initialize// Author........: Aleksander 豩rn// Date..........:// Description...: Computes probabilities.//// Comments......: The table given as an argument is the table of// objects to be classified, not the table to// compute probabilities from.// Revisions.....://===================================================================boolNaiveBayesClassifier::Initialize(const DecisionTable &/*table*/, bool masked) { int i, j; // Clear probability data structures. conditionals_.erase(conditionals_.begin(), conditionals_.end()); priors_.erase(priors_.begin(), priors_.end()); Handle<DecisionTable> master = GetDecisionTable(); // Is a table to compute probabilities from provided? if (master == NULL) { Message::Error("No master decision table set.", false); return false; } // Get index of decision attribute. decision_attribute_ = master->GetDecisionAttribute(masked); if (decision_attribute_ == Undefined::Integer()) return false; int no_objects = master->GetNoObjects(masked); int no_attributes = master->GetNoAttributes(masked); // Compute prior counts. for (i = 0; i < no_objects; i++) { int decision = master->GetEntry(i, decision_attribute_, masked); priors_.insert(Pair(const int, double)(decision, 0.0)); priors_[decision] += 1.0; } conditionals_.reserve(no_attributes); // Compute conditional counts and normalize them. for (j = 0; j < no_attributes; j++) { conditionals_.push_back(CPMap()); // Only consider condition attributes. if (j == decision_attribute_) continue; for (i = 0; i < no_objects; i++) { int condition = master->GetEntry(i, j, masked); int decision = master->GetEntry(i, decision_attribute_, masked); IIPair iipair(condition, decision); conditionals_[j].insert(Pair(const IIPair, double)(iipair, 0.0)); conditionals_[j][iipair] += 1.0; } CPMap::iterator it1; for (it1 = conditionals_[j].begin(); it1 != conditionals_[j].end(); it1++) { (*it1).second /= priors_[(*it1).first.second]; } } PPMap::iterator it2; // Normalize prior counts. for (it2 = priors_.begin(); it2 != priors_.end(); it2++) { (*it2).second /= no_objects; } return true;}//-------------------------------------------------------------------// Method........: SetRules// Author........: Aleksander 豩rn// Date..........:// Description...:// Comments......: Overloading this method does not make much sense// since this is not a rule-based classifier, but// this hack should enable this classifier to be used in// the specialized command script language.// Revisions.....://===================================================================boolNaiveBayesClassifier::SetRules(const Rules *rules) { // This ensures that this object does not keep the table unnecessarily alive. // Side effect: GetParameters cannot return the table name. if (rules == NULL) return SetDecisionTable(NULL); // Backtrack to the decision table the rules were derived from. Handle<DecisionTable> table = dynamic_cast(DecisionTable *, rules->FindParent(DECISIONTABLE)); return SetDecisionTable(table);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -