⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reductperformancefilter.cpp

📁 粗糙集应用软件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		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();
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -