?? reductperformancefilter.cpp
字號(hào):
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.....:
//===================================================================
bool
ReductPerformanceFilter::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.....:
//===================================================================
void
ReductPerformanceFilter::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.....:
//===================================================================
String
ReductPerformanceFilter::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();
}
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -