ts-aggregator/project_template/Vovk.cpp
2022-12-13 12:36:06 +04:00

216 lines
7.3 KiB
C++

#include "StdAfx.h"
#include "Vovk.h"
#include "Dsa.h"
#include "Fuzzy.h"
#include "FuzzyWithSets.h"
#include "NoTrendNoSeasonality.h"
#include "NoTrendNoSeasonality.h"
#include "NoTrendAddSeasonality.h"
#include "NoTrendMultSeasonality.h"
#include "AddTrendNoSeasonality.h"
#include "AddTrendAddSeasonality.h"
#include "AddTrendMultSeasonality.h"
#include "MultTrendNoSeasonality.h"
#include "MultTrendAddSeasonality.h"
#include "MultTrendMultSeasonality.h"
#include "DATrendNoSeasonality.h"
#include "DATrendAddSeasonality.h"
#include "DATrendMultSeasonality.h"
#include "DMTrendNoSeasonality.h"
#include "DMTrendAddSeasonality.h"
#include "DMTrendMultSeasonality.h"
#include "TrackingControlSignal.h"
#include <iostream>
//Set ts at constructor, get first forecast
//add value(update) ts
//recalculate weights
Vovk::Vovk(vector<double> _timeSeria, int _forecastHorizont, Method **m) {
prep = new Preparator(true, true);
useSingleTrashhold = false;
forecastHorizont = 1;
singleTrashhold = 0.35;
useModelTrashhold = false;
modelTrashhold = 0;
activeExpertsCount = 0;
beta = 0.5;
step = 0;
forecast = 0;
addWeightFromSleepEx = 0.0;
timeSeria = _timeSeria;
calculateTimeSeriaDiff(_timeSeria);
int n = 29; // êîëè÷åñòâî ìåòîäîâ, ÷òîá ëèøíåãî ïàìÿòè íå æðàòü
expertsCount = n;
forecastHorizont = _forecastHorizont;
/*int p = 1;
double alpha = 0.4;
double delta = 0.9;
double gamma = 0.4;
double phi = 0.1;*/
int countRulesIn = 1;
int countFuzzyParts = 40;
models = m;
//models[0] = new NoTrendNoSeasonality(_timeSeria, _forecastHorizont);
//models[1] = new NoTrendAddSeasonality(_timeSeria, _forecastHorizont);
//models[2] = new NoTrendMultSeasonality(_timeSeria, _forecastHorizont);
//models[3] = new AddTrendNoSeasonality(_timeSeria, _forecastHorizont);
//models[4] = new MultTrendNoSeasonality(_timeSeria, _forecastHorizont);
//models[5] = new DATrendNoSeasonality(_timeSeria, _forecastHorizont);
//models[6] = new DMTrendNoSeasonality(_timeSeria, _forecastHorizont);
//models[7] = new AddTrendAddSeasonality(_timeSeria, _forecastHorizont);
//models[8] = new MultTrendAddSeasonality(_timeSeria, _forecastHorizont);
//models[9] = new DATrendAddSeasonality(_timeSeria, _forecastHorizont);
//models[10] = new DMTrendAddSeasonality(_timeSeria, _forecastHorizont);
//models[11] = new AddTrendMultSeasonality(_timeSeria, _forecastHorizont);
//models[12] = new MultTrendMultSeasonality(_timeSeria, _forecastHorizont);
//models[13] = new DATrendMultSeasonality(_timeSeria, _forecastHorizont);
//models[14] = new DMTrendMultSeasonality(_timeSeria, _forecastHorizont);
//models[15] = new Dsa(_timeSeria, _forecastHorizont);
//models[16] = new Fuzzy("None", "None", _timeSeria, _forecastHorizont);
//models[17] = new Fuzzy("Add", "None", _timeSeria, _forecastHorizont);
//models[18] = new Fuzzy("None", "Add", _timeSeria, _forecastHorizont);
//models[19] = new Fuzzy("Add", "Add", _timeSeria, _forecastHorizont);
//models[20] = new FuzzyWithSets("None", "None", _timeSeria, _forecastHorizont);
//models[21] = new FuzzyWithSets("None", "Add", _timeSeria, _forecastHorizont);
//models[22] = new FuzzyWithSets("None", "Mult", _timeSeria, _forecastHorizont);
//models[23] = new FuzzyWithSets("Add", "None", _timeSeria, _forecastHorizont);
//models[24] = new FuzzyWithSets("Add", "Add", _timeSeria, _forecastHorizont);
//models[25] = new FuzzyWithSets("Add", "Mult", _timeSeria, _forecastHorizont);
//models[26] = new FuzzyWithSets("Mult", "None", _timeSeria, _forecastHorizont);
//models[27] = new FuzzyWithSets("Mult", "Add", _timeSeria, _forecastHorizont);
//models[28] = new FuzzyWithSets("Mult", "Mult", _timeSeria, _forecastHorizont);
////add models
//for (int i = 0; i < 29; i++) {
// // ñîçäàåì ìîäåëü äëÿ òåñòèðîâàíèÿ ïðè ïîìîùè âûáðàííîãî ìåòîäà
// // çàäàåì ïàðàìåòðû
// models[i]->setParam("alpha", alpha);
// models[i]->setParam("gamma", gamma);
// models[i]->setParam("delta", delta);
// models[i]->setParam("p", p);
// models[i]->setParam("phi", phi);
// models[i]->setParam("countRulesIn", countRulesIn);
// models[i]->setParam("countFuzzyParts", countFuzzyParts);
// models[i]->setParam("w", 0.5);
// // ñ íóæíî îïðåäåëÿòü êàê îòíîñèòåëüíóþ âåëè÷èíó, áåç ïðèâÿçêè ê çíà÷åíèÿì ðÿäà
// // ëèøü ïîòîì ìàñøòàáèðîâàòü
// // íàïðèìåð ìîæíî ðàññ÷èòàòü òàê: ïðè êîëè÷åñòâå èíòåðâàëîâ ðàçáèåíèÿ = 20, åñëè çàäàòü c = 20
// // òî òðåóãîëüíèêè áóäóò ïåðåêðûâàòü äðóã äðóãà ðîâíî íà ïîëîâèíó
// models[i]->setParam("c", 20);
// // ñîçäàåì ìîäåëü
// models[i]->createModelForEstimation();
//}
//push models to Vovks object
double check = 0;
//set weights at first time
for (int i = 0; i < expertsCount; i++)
{
models[i]->weight = (1.0 / expertsCount);
check += models[i]->weight;
models[i]->value = models[i]->getForecast()[step];
//cout << models[i]->value << " " << models[i]->weight << " " << forecast << endl;
}
//check experts representation
checkExperts();
//calculate first forecast
for (int i = 0; i < expertsCount; i++)
{
if (models[i]->isActive)
forecast += models[i]->value * (models[i]->weight + addWeightFromSleepEx/activeExpertsCount);
}
getNewExpertsValues();
//step++;
}
void Vovk::setBeta(double _beta){
beta = _beta;
}
Vovk::~Vovk() {
}
void Vovk::calculateTimeSeriaDiff(vector<double> timeSeria){
double diff = 0.0;
for (int i = 0; i < timeSeria.size() - 1; i++){
diff += fabs(timeSeria[i] - timeSeria[i + 1]);
}
timeSeriaDiff = (diff / (timeSeria.size() - 1)) * (1 + singleTrashhold);
}
void Vovk::checkExperts(){
TrackingControlSignal *tcs = new TrackingControlSignal();
activeExpertsCount = expertsCount;
addWeightFromSleepEx = 0.0;
vector<bool> expertsActivity = tcs->HistoricalExpertControl(models, timeSeriaDiff, expertsCount);
for (int i = 0; i < expertsCount; i++)
{
models[i]->isActive = expertsActivity[i];
if (!expertsActivity[i]){
addWeightFromSleepEx += models[i]->weight;
activeExpertsCount--;
}
}
}
void Vovk::getNewExpertsValues(){
for (int i = 0; i < expertsCount; i++){
//for 1 scale forecast
models[i]->value = models[i]->getForecast()[step];
}
step++;
}
//ret gt(x)
double Vovk::recalculateWeights(double nextRealValue){
double weightsSum = 0;
for (int i = 0; i < expertsCount; i++){
models[i]->weight = models[i]->weight * pow(beta, fabs(models[i]->value - nextRealValue));
weightsSum += models[i]->weight;
}
//normalize weights
double check = 0.0;
for (int i = 0; i < expertsCount; i++){
models[i]->weight = models[i]->weight / weightsSum;
check += models[i]->weight;
}
return log(weightsSum) / log(beta);//beta, weightsSum);
}
void Vovk::updateTS(double nextRealValue){
//change models weights with new real value
double gtx = recalculateWeights(nextRealValue);
forecast = 0.0;
//create new forecast from experts
getNewExpertsValues();
checkExperts();
//create aggregated forecast
double check = 0.0;
for (int i = 0; i < expertsCount; i++)
{
/*cout << i << ") ";
if (models[i]->isActive){
cout << "true ";
}
else{
cout << "false ";
}
cout << " " << models[i]->value << " " << models[i]->weight << endl;*/
if (models[i]->isActive){
check += models[i]->weight;
forecast += models[i]->value * (models[i]->weight + addWeightFromSleepEx / activeExpertsCount);
}
}
}
double Vovk::getForecast(){
return forecast;
}
//void Vovk::addMethod(AggModel model){
// models.push_back(model);
//}