📄 serialexecutorloop.cpp
字号:
//-------------------------------------------------------------------
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Revisions.....:
//===================================================================
#include <stdafx.h> // Precompiled headers.
#include <copyright.h>
#include <kernel/algorithms/serialexecutorloop.h>
#include <kernel/algorithms/keyword.h>
#include <kernel/algorithms/batchclassifier.h>
#include <kernel/structures/decisiontable.h>
#include <kernel/structures/rules.h>
#include <kernel/structures/batchclassification.h>
#include <kernel/structures/project.h>
#include <kernel/structures/projectmanager.h>
#include <kernel/utilities/mathkit.h>
#include <kernel/utilities/rng.h>
#include <kernel/utilities/iokit.h>
#include <kernel/utilities/creator.h>
#include <kernel/basic/message.h>
#include <kernel/system/fstream.h>
#include <common/objectmanager.h>
//-------------------------------------------------------------------
// Static methods (file scope)
//===================================================================
//-------------------------------------------------------------------
// Method........: StaticCleanUp
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Cleans up temp. stuff set in the ExecuteCommands
// method.
// Comments......:
// Revisions.....:
//===================================================================
static void
StaticCleanUp(SerialExecutorLoop &executor, Id id) {
// Reset rules.
executor.SetRules(Handle<Rules>(NULL));
// Reset output type.
executor.SetOutputType(id);
}
static void
StaticCleanUp(Project &project, const DecisionTable &table) {
// Remove project from project pool.
ProjectManager::RemoveProject(&project);
// Find child index.
int index = project.FindChild(&table);
// Remove child.
if (index != Undefined::Integer())
project.RemoveChild(index);
}
//-------------------------------------------------------------------
// Method........: StaticGetRules
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns the last rule set derived from the given
// decision table.
//
// Comments......: Current implementation does not test for "lastness"...
// Revisions.....:
//===================================================================
static Handle<Rules>
StaticGetRules(const DecisionTable &table) {
Handle<Rules> rules;
Identifier::Handles rulesets;
bool recursive = true;
// Get all children rulesets. If several, assume that the order in the list is an indication of being "last"...
if (table.GetAllChildren(RULES, rulesets, recursive) && !rulesets.empty())
rules = dynamic_cast(Rules *, rulesets[rulesets.size() - 1].GetPointer());
if (rulesets.size() > 1)
Message::Warning("More than one rule set detected, selecting one.", false);
return rules;
}
//-------------------------------------------------------------------
// Methods for class SerialExecutorLoop
//===================================================================
//-------------------------------------------------------------------
// Constructors/destructor.
//===================================================================
SerialExecutorLoop::SerialExecutorLoop() {
SetN(5);
SetLength(0);
}
SerialExecutorLoop::~SerialExecutorLoop() {
}
//-------------------------------------------------------------------
// Methods inherited from Identifier.
//===================================================================
IMPLEMENTIDMETHODS(SerialExecutorLoop, SERIALEXECUTORLOOP, SerialExecutor)
//-------------------------------------------------------------------
// Methods inherited from Algorithm.
//===================================================================
//-------------------------------------------------------------------
// Method........: GetParameters
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
String
SerialExecutorLoop::GetParameters() const {
String parameters;
// N.
parameters += Keyword::Number();
parameters += Keyword::Assignment();
parameters += String::Format(GetN());
parameters += Keyword::Separator();
// Seed.
parameters += Keyword::Seed();
parameters += Keyword::Assignment();
parameters += String::Format(GetSeed());
parameters += Keyword::Separator();
// Length.
parameters += Keyword::Length();
parameters += Keyword::Assignment();
parameters += String::Format(GetLength());
parameters += Keyword::Separator();
return parameters + SerialExecutor::GetParameters();
}
//-------------------------------------------------------------------
// Method........: SetParameter
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
bool
SerialExecutorLoop::SetParameter(const String &keyword, const String &value) {
// N.
if (keyword == Keyword::Number() && value.IsInteger())
return SetN(value.GetInteger());
// Seed.
if (keyword == Keyword::Seed() && value.IsInteger())
return SetSeed(value.GetInteger());
// Length.
if (keyword == Keyword::Length() && value.IsInteger())
return SetLength(value.GetInteger());
return SerialExecutor::SetParameter(keyword, value);
}
//-------------------------------------------------------------------
// Method........: IsApplicable
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
bool
SerialExecutorLoop::IsApplicable(const Structure &structure, bool /*warn*/) const {
return structure.IsA(DECISIONTABLE);
}
//-------------------------------------------------------------------
// Methods inherited from Executor.
//===================================================================
//-------------------------------------------------------------------
// Method........: ExecuteCommands
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Executes a pipeline with some kind of systematic
// sampling per iteration.
//
// The input pipeline is split into two pipelines,
// one for training and one for testing.
//
// Input is a decision table. For each of the n loop
// iterations, the table is split into a training and a
// testing table.
//
// Starting with the training table, all algorithms in
// the training pipeline are then applied in sequence,
// with the output of one being the input to the next.
// The training pipeline is assumed to produce a set
// of rules along the way.
//
// Then, starting with the testing table, all algorithms
// in the testing pipeline are applied in sequence,
// with the output of one being the input to the next.
// It is assumed that the testing pipeline produces a
// confusion matrix (via a batch classification structure)
// along the way, typically by a batch classifier.
// The rule set from the training pipeline is used by the
// batch classifier.
//
// Various statistics are collected from the resulting
// confusion matrix, and dumped to a log file.
//
// If the desired output type is Undefined::Id(), return
// the input structure unless an error occurs.
//
// Comments......: Currently, the training pipelibne is executed by a
// separate SerialExecutor object, while this object
// excutes the training pipeline.
//
// This method could probably be implemented in a much
// "cleaner" fashion by doing some restructuring
// and using separate SerialExecutor objects for
// both pipelines. That would also eliminate the
// messy temporary project stuff and the clean-up
// methods. However, the current implementation works,
// and "if it ain't broke, don't fix it".
//
// Revisions.....:
//===================================================================
Structure *
SerialExecutorLoop::ExecuteCommands(Structure &structure, const Algorithm::Handles &algorithms, const Vector(String) ¶meters, ofstream &stream) const {
Message message;
// Cast, type verified by IsApplicable method.
Handle<DecisionTable> table = dynamic_cast(DecisionTable *, &structure);
Algorithm::Handles algorithms_training; // Algorithms, training pipeline (must produce a rule set).
Algorithm::Handles algorithms_testing; // Algorithms, testing pipeline (should include a batch classifier).
Vector(String) parameters_training; // Parameters, training pipeline.
Vector(String) parameters_testing; // Parameters, testing pipeline.
// Split pipeline.
if (!SplitCommands(GetLength(), algorithms, parameters, algorithms_training, parameters_training, algorithms_testing, parameters_testing)) {
Message::Error("Failed to split command sequence.");
return NULL;
}
RNG rng(GetSeed());
// Operate on a masked table.
bool masked = true;
// This method is conceptually const only.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -