template<class LearnerInput> struct BaggedConfiguration { BaggedConfiguration() {} BaggedConfiguration(UINT _BagCount, UINT _BagSize, BinaryClassifierFactory<LearnerInput> *_Factory) { BagCount = _BagCount; BagSize = _BagSize; Factory = _Factory; } UINT BagCount, BagSize; BinaryClassifierFactory<LearnerInput> *Factory; }; template<class LearnerInput> class BinaryClassifierBagged : public BinaryClassifier<LearnerInput> { public: BinaryClassifierBagged() { _Configured = false; } BinaryClassifierBagged(const BaggedConfiguration<LearnerInput> &Config) { _Configured = true; _Config = Config; } void Configure(const BaggedConfiguration<LearnerInput> &Config) { _Configured = true; _Config = Config; } void Train(const Dataset &Examples, UINT Class0Index, UINT Class1Index) { Console::WriteLine(String("Training bagged classifier, ") + String(Examples.Entries().Length()) + String(" examples, ") + String(_Config.BagCount) + String(" bags")); _Class0Index = Class0Index; _Class1Index = Class1Index; Dataset NewDataset; _BaseClassifiers.Allocate(_Config.BagCount); for(UINT ClassifierIndex = 0; ClassifierIndex < _Config.BagCount; ClassifierIndex++) { NewDataset.SampleFromDataset(Examples, _Config.BagSize); BinaryClassifier<LearnerInput> *NewClassifier = _Config.Factory->MakeClassifier(); NewClassifier->Train(NewDataset, Class0Index, Class1Index); _BaseClassifiers[ClassifierIndex] = NewClassifier; } } void Evaluate(const LearnerInput &Input, UINT &Class, double &ProbabilityClass0) const { const UINT ClassCount = 2; UINT ClassVotes[ClassCount] = {0, 0}; for(UINT ClassifierIndex = 0; ClassifierIndex < _Config.BagCount; ClassifierIndex++) { const BinaryClassifier<LearnerInput> &CurClassifier = *(_BaseClassifiers[ClassifierIndex]); UINT LocalClass; double LocalProbabilityClass0; CurClassifier.Evaluate(Input, LocalClass, LocalProbabilityClass0); if(LocalProbabilityClass0 > 0.5) { ClassVotes[0]++; } else { ClassVotes[1]++; } } ProbabilityClass0 = double(ClassVotes[0]) / _Config.BagCount; if(ProbabilityClass0 > 0.5) { Class = _Class0Index; } else { Class = _Class1Index; } } UINT Class0Index() const { return _Class0Index; } UINT Class1Index() const { return _Class1Index; } private: UINT _Class0Index, _Class1Index; Vector<BinaryClassifier<LearnerInput>*> _BaseClassifiers; bool _Configured; BaggedConfiguration<LearnerInput> _Config; }; template<class LearnerInput> class BinaryClassifierFactoryBagged : public BinaryClassifierFactory<LearnerInput> { public: BinaryClassifierFactoryBagged(const BaggedConfiguration<LearnerInput> &Config) { _Config = Config; } BinaryClassifier<LearnerInput>* MakeClassifier() const { BinaryClassifierBagged<LearnerInput> *Result = new BinaryClassifierBagged<LearnerInput>(_Config); return Result; } private: BaggedConfiguration<LearnerInput> _Config; };