📄 reductperformancefilter.cpp
字号:
stream << "%" << endl; stream << "% Note that the indices below are 0-based." << endl << endl; } // Ugly hack, to make stream accessible from Remove and CalculateStatistics method. static_stream = &stream; // Do the filtering. Handle<Structure> result = Filter::Apply(structure); if (use_parent_rg) self->SetRGDecisionTable(Handle<DecisionTable>(NULL)); if (use_parent_bc) self->SetBCDecisionTable(Handle<DecisionTable>(NULL)); // Calculate and print statistics. CalculateStatistics(); // Clean up ugly hack. static_stream = NULL; // Clean up in general. (self->scores_).erase((self->scores_).begin(), (self->scores_).end()); (self->only_scores_).erase((self->only_scores_).begin(), (self->only_scores_).end()); return result.Release();}//-------------------------------------------------------------------// Methods inherited from Filter.//===================================================================//-------------------------------------------------------------------// Method........: Remove// Author........: Aleksander 豩rn// Date..........:// Description...: Returns true if the specified reduct should be removed// from the reduct set.// Comments......:// Revisions.....://===================================================================boolReductPerformanceFilter::Remove(const Structures &structures, int i) const { if (!structures.IsA(REDUCTS)) return false; Handle<Reducts> reducts = dynamic_cast(Reducts *, const_cast(Structures *, &structures)); // Duplicate the specified reduct only. Handle<Reducts> reduct = dynamic_cast(Reducts *, reducts->DuplicateStructure(i)); if (reduct == NULL) { Message::Error("Failed to duplicate reduct number " + String::Format(i) + " from reduct set."); return false; } // Generate rules from the reduct, using RG table. GetRuleGenerator()->SetDecisionTable(GetRGDecisionTable()); Handle<Rules> rules = dynamic_cast(Rules *, reduct->Apply(*GetRuleGenerator())); GetRuleGenerator()->SetDecisionTable(Handle<DecisionTable>(NULL)); if (rules == NULL) { Message::Error("Failed to generate rules from reduct number " + String::Format(i) + "."); return false; } // How many rules are there? int no_rules = rules->GetNoRules(); // Apply BC to BC table, using generated set of rules. if (!GetBatchClassifier()->SetRules(rules.GetPointer())) { Message::Error("Failed to pass rules generated from reduct number " + String::Format(i) + " to BatchClassifier.\n" "Are you sure the BatchClassifier has been assigned a rule-based Classifier?"); return false; } Handle<BatchClassification> batchclassification = dynamic_cast(BatchClassification *, GetBCDecisionTable()->Apply(*GetBatchClassifier())); GetBatchClassifier()->SetRules(NULL); if (batchclassification == NULL) { Message::Error("Failed to generate confusion matrix from reduct number " + String::Format(i) + "."); return false; } float value; bool index_ok = true; // Extract specified value from confusion matrix. switch (GetCriterion()) { case CRITERION_DIAGONAL: value = batchclassification->GetConfusionMatrix().GetDiagonalRatio(); break; case CRITERION_ROW: if (GetIndex() >= batchclassification->GetConfusionMatrix().GetDimension()) { Message::Error("Specified index larger than dimension of confusion matrix for reduct number " + String::Format(i) + "."); index_ok = false; } else { value = batchclassification->GetConfusionMatrix().GetRowRatio(GetIndex()); } break; case CRITERION_COLUMN: if (GetIndex() >= batchclassification->GetConfusionMatrix().GetDimension()) { Message::Error("Specified index larger than dimension of confusion matrix for reduct number " + String::Format(i) + "."); index_ok = false; } else { value = batchclassification->GetConfusionMatrix().GetColumnRatio(GetIndex()); } break; default: Message::Error("Specified performance criterion not implemented."); index_ok = false; } if (!index_ok) return false; if (value == Undefined::Float()) { Message::Warning("Score for reduct number " + String::Format(i) + " is undefined.", false); return false; } // Get ROC area (if any). float roc_area = batchclassification->GetROCArea(); String formatted_r; bool masked = true; // Format reduct. if (!reducts->GetReduct(i)->Format(formatted_r, dynamic_cast(DecisionTable *, reducts->FindParent(DECISIONTABLE)), masked)) formatted_r = Undefined::String(); // We need to update the mutable bookkeeping stuff. ReductPerformanceFilter *self = const_cast(ReductPerformanceFilter *, this); ReductScore score; // Store values for summary rankings/statistics. score.score_ = value; score.auc_ = batchclassification->GetROCArea(); score.reduct_ = formatted_r; score.index_ = i; (self->scores_).push_back(score); (self->only_scores_).push_back(score.score_); // Make removal decision. bool remove = (value <= GetThreshold()); // Dump information to logfile, if open. if (static_stream != NULL) { String formatted_m; String indent(' ', 5); // Format matrix. if (!batchclassification->GetConfusionMatrix().Format(formatted_m, indent)) formatted_m = Undefined::String(); // Write log file entry. *static_stream << "Reduct #" << score.index_ << ":" << endl; *static_stream << indent << score.reduct_ << endl; *static_stream << "#Rules:" << endl; *static_stream << indent << no_rules << endl; if (roc_area != Undefined::Float()) { *static_stream << "Area under ROC curve:" << endl; *static_stream << indent << score.auc_ << endl; } *static_stream << "Performance:" << endl; *static_stream << formatted_m << endl; } // Return removal decision. return remove;}//-------------------------------------------------------------------// Local methods.//===================================================================//-------------------------------------------------------------------// Method........: CalculateStatistics// Author........: Aleksander 豩rn// Date..........:// Description...:// Comments......:// Revisions.....://===================================================================voidReductPerformanceFilter::CalculateStatistics() const { if (only_scores_.empty()) return; float mean = MathKit::Mean(only_scores_); float median = MathKit::Median(only_scores_); float stddev = MathKit::StandardDeviation(only_scores_); float minimum = MathKit::Minimum(only_scores_); float maximum = MathKit::Maximum(only_scores_); String name; // Extract name of score quantity. switch (GetCriterion()) { case CRITERION_DIAGONAL: name = "Diagonal"; break; case CRITERION_ROW: name = "Row[" + String::Format(GetIndex()) + "]"; break; case CRITERION_COLUMN: name = "Column[" + String::Format(GetIndex()) + "]"; break; default: name = "Score"; } Message message; message.Notify(name + ".Mean = " + (mean == Undefined::Float() ? Undefined::String() : String::Format(mean))); message.Notify(name + ".Median = " + (median == Undefined::Float() ? Undefined::String() : String::Format(median))); message.Notify(name + ".StdDev = " + (stddev == Undefined::Float() ? Undefined::String() : String::Format(stddev))); message.Notify(name + ".Minimum = " + (minimum == Undefined::Float() ? Undefined::String() : String::Format(minimum))); message.Notify(name + ".Maximum = " + (maximum == Undefined::Float() ? Undefined::String() : String::Format(maximum))); String indent(' ', 5); // Write to log file. if (static_stream != NULL) { // Write summary statistics. *static_stream << "Statistics:" << endl; *static_stream << indent << name + ".Mean = " + (mean == Undefined::Float() ? Undefined::String() : String::Format(mean)) << endl; *static_stream << indent << name + ".Median = " + (median == Undefined::Float() ? Undefined::String() : String::Format(median)) << endl; *static_stream << indent << name + ".StdDev = " + (stddev == Undefined::Float() ? Undefined::String() : String::Format(stddev)) << endl; *static_stream << indent << name + ".Minimum = " + (minimum == Undefined::Float() ? Undefined::String() : String::Format(minimum)) << endl; *static_stream << indent << name + ".Maximum = " + (maximum == Undefined::Float() ? Undefined::String() : String::Format(maximum)) << endl << endl; // Any scores present? If not, we're done. if (scores_.empty()) return; // We need to update (sort) the mutable bookkeeping stuff. ReductPerformanceFilter *self = const_cast(ReductPerformanceFilter *, this); ReductScoreComparator1 comparator1; message.Notify("Sorting scores..."); // Sort by performance scores. std::sort((self->scores_).begin(), (self->scores_).end(), comparator1); message.Notify("Saving ranking to log..."); *static_stream << "Ranking:" << endl; int i; bool sort_by_auc = false; // Write rankings. for (i = 0; i < scores_.size(); i++) { String formatted_i; String formatted_v; String formatted_r; // Format output. formatted_i = "Reduct #" + String::Format(scores_[i].index_); formatted_v = String::Format(scores_[i].score_); formatted_v.Pad(' ', 11); formatted_r = scores_[i].reduct_; // Write to stream. *static_stream << indent << formatted_v << formatted_i << " = " << formatted_r << endl; if (scores_[i].auc_ != Undefined::Float()) sort_by_auc = true; } // Write ranked AUC values, too, or are we done? if (!sort_by_auc) return; ReductScoreComparator2 comparator2; message.Notify("Sorting AUC scores..."); // Sort by AUC. std::sort((self->scores_).begin(), (self->scores_).end(), comparator2); message.Notify("Saving ranking to log..."); *static_stream << endl << "ROC areas:" << endl; // Write ROC areas. for (i = 0; i < scores_.size(); i++) { String formatted_i; String formatted_v; String formatted_r; // Format output. formatted_i = "Reduct #" + String::Format(scores_[i].index_); formatted_v = String::Format(scores_[i].auc_); formatted_v.Pad(' ', 11); formatted_r = scores_[i].reduct_; // Write to stream. *static_stream << indent << formatted_v << formatted_i << " = " << formatted_r << endl; } }}//-------------------------------------------------------------------// Method........: GetString// Author........: Aleksander 豩rn// Date..........:// Description...:// Comments......:// Revisions.....://===================================================================StringReductPerformanceFilter::GetString(ReductPerformanceFilter::Criterion criterion) { switch (criterion) { case CRITERION_ROW: return "Row"; case CRITERION_COLUMN: return "Column"; case CRITERION_DIAGONAL: return "Diagonal"; default: return Undefined::String(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -