203 lines
5.8 KiB
C++
203 lines
5.8 KiB
C++
|
#include "StdAfx.h"
|
|||
|
#include <iostream>
|
|||
|
#include <math.h>
|
|||
|
#include "Aic.h"
|
|||
|
# define M_PI 3.14159265358979323846 /* pi */
|
|||
|
|
|||
|
using namespace std;
|
|||
|
|
|||
|
// критерий Акаике. Наследуется от класса Estimation.
|
|||
|
// реализует метод "получить значение критерия"
|
|||
|
|
|||
|
|
|||
|
Aic::Aic() {
|
|||
|
}
|
|||
|
|
|||
|
Aic::~Aic(){
|
|||
|
}
|
|||
|
/*
|
|||
|
paramsCount - count of model params,
|
|||
|
количество параетров модели
|
|||
|
tsLen - lenght of forecasted estimated time seria,
|
|||
|
длина оцениваемого спрогнозированного временного ряда
|
|||
|
isSecondOrder - AIC second order modification,
|
|||
|
модифицированный АИК второго порядка
|
|||
|
original - values of the predicted time series,
|
|||
|
известные значения прогнозируемого временного ряда
|
|||
|
model - forecasted values of the predicted time series,
|
|||
|
прогнозированные значения прогнозируемого временного ряда
|
|||
|
*/
|
|||
|
//Надо перенести в интерфейс модели, логично если модели будут в последствии
|
|||
|
//разных типов
|
|||
|
//Функция правдоподобия для не линейной модели
|
|||
|
double Aic::logLikNLS(vector<double> forecast, vector<double> weights){
|
|||
|
int n = forecast.size();
|
|||
|
if (weights.size() == 0){
|
|||
|
for (int i = 0; i < n; i++){
|
|||
|
weights.push_back(1);
|
|||
|
}
|
|||
|
}
|
|||
|
//summ log(w)
|
|||
|
double wls = 0;
|
|||
|
//wetghted forecasts
|
|||
|
double wfor = 0;
|
|||
|
for (int i = 0; i < n; i++){
|
|||
|
//zero weights hack
|
|||
|
if (weights[i] != 0){
|
|||
|
wls += log(weights[i]);
|
|||
|
}
|
|||
|
else{
|
|||
|
wls += log((double)1);
|
|||
|
}
|
|||
|
wfor += weights[i] * forecast[i] * forecast[i];
|
|||
|
}
|
|||
|
double res = -n * (log((double)2 * M_PI) + 1 - log((double)n) - wls + log((double)wfor)) / 2;
|
|||
|
return res;
|
|||
|
}
|
|||
|
//Функция правдоподобия для линейной модели
|
|||
|
double Aic::logLikLM(vector<double> forecast, vector<double> weights){
|
|||
|
int n = forecast.size();
|
|||
|
if (weights.size() == 0){
|
|||
|
for (int i = 0; i < n; i++){
|
|||
|
weights.push_back(1);
|
|||
|
}
|
|||
|
}
|
|||
|
else{
|
|||
|
int i = 0;
|
|||
|
while (i < n){
|
|||
|
if (weights[i] == 0){
|
|||
|
forecast.erase(forecast.begin() + i);
|
|||
|
weights.erase(weights.begin() + i);
|
|||
|
n = forecast.size();
|
|||
|
}
|
|||
|
i++;
|
|||
|
}
|
|||
|
}
|
|||
|
//summ log(w)
|
|||
|
double wls = 0;
|
|||
|
//wetghted forecasts
|
|||
|
|
|||
|
double wfor = 0;
|
|||
|
for (int i = 0; i < n; i++){
|
|||
|
wls += log(weights[i]);
|
|||
|
wfor += weights[i] * forecast[i] * forecast[i];
|
|||
|
}
|
|||
|
double res = 0.5 * (wls - n * (log((double)2 * M_PI) + 1 - log((double)n) + log((double)wfor)));
|
|||
|
return res;
|
|||
|
}
|
|||
|
|
|||
|
//Свойство класса модели
|
|||
|
int Aic::getParamsCount(vector<double> model){
|
|||
|
#pragma message ("Need solve where is it must do")
|
|||
|
cout << "log-likelihood function calculate";
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
models with special methods:
|
|||
|
glm, multinom
|
|||
|
+- maxlikeFit, merMod, unmarkedFit, vglm
|
|||
|
*/
|
|||
|
double Aic::getBicValue(int paramsCount,
|
|||
|
vector<double> original, vector<double> model){
|
|||
|
int n = (original.size() > model.size() ? model.size() : original.size());
|
|||
|
double res = 0;
|
|||
|
double lik = 0;
|
|||
|
double lik2 = 0;
|
|||
|
vector<double> e;
|
|||
|
cout << "Bicc " << endl;
|
|||
|
cout << " e sum(lik) sum(lik2)" << endl;
|
|||
|
for (int i = 0; i < n; i++){
|
|||
|
//adderror
|
|||
|
e.push_back(original[i] - model[i]);
|
|||
|
cout << " " << e[i];
|
|||
|
lik += e[i] * e[i];
|
|||
|
cout << " " << lik;
|
|||
|
lik2 += log(fabs(model[i]));
|
|||
|
cout << " " << lik2 << endl;
|
|||
|
// MULT lik += (original[i] - model[i])/ model[i];
|
|||
|
}
|
|||
|
lik = n * log(lik);
|
|||
|
//MULT lik +=2 *lik2;
|
|||
|
res = lik + log((double)n) * paramsCount;
|
|||
|
cout << " " << res << " " << endl;
|
|||
|
return res;
|
|||
|
}
|
|||
|
double Aic::getAiccValue(int paramsCount,
|
|||
|
vector<double> original, vector<double> model){
|
|||
|
int n = (original.size() > model.size() ? model.size() : original.size());
|
|||
|
double res = 0;
|
|||
|
double lik = 0;
|
|||
|
double lik2 = 0;
|
|||
|
vector<double> e;
|
|||
|
cout << "Aicc " << endl;
|
|||
|
cout << " e sum(lik) sum(lik2)" << endl;
|
|||
|
for (int i = 0; i < n; i++){
|
|||
|
//adderror
|
|||
|
e.push_back(original[i] - model[i]);
|
|||
|
cout << " " << e[i];
|
|||
|
lik += e[i] * e[i];
|
|||
|
cout << " " << lik;
|
|||
|
lik2 += log(fabs(model[i]));
|
|||
|
cout << " " << lik2 << endl;
|
|||
|
// MULT lik += (original[i] - model[i])/ model[i];
|
|||
|
}
|
|||
|
lik = n * log(lik);
|
|||
|
//MULT lik +=2 *lik2;
|
|||
|
res = lik + (2 * paramsCount* n)/( n - paramsCount - 1);
|
|||
|
cout << " " << res << " " << endl;
|
|||
|
return res;
|
|||
|
}
|
|||
|
/*
|
|||
|
valide for next models by package:
|
|||
|
aov, clm, clmm, coxme, coxph, gls, lm, lme, lmeik, mer, merMod,
|
|||
|
multinom, nlme, nls, polr, rlm, zeroinfl
|
|||
|
*/
|
|||
|
double Aic::getValue(int paramsCount, // bool isSecondOrder,
|
|||
|
vector<double> original, vector<double> model) {
|
|||
|
//Validate(original, model);
|
|||
|
int n = (original.size() > model.size() ? model.size() : original.size());
|
|||
|
////// R default package
|
|||
|
//double logLik = Aic::logLikNLS(model, RSSweights(original, model));//Aic::logLikLM(model, RSSweights(original, model));
|
|||
|
////R-package version
|
|||
|
//if (true){//isSecondOrder){
|
|||
|
// return -2 * logLik + 2 * paramsCount;
|
|||
|
//}
|
|||
|
//else
|
|||
|
//{
|
|||
|
// return -2 * logLik + 2 * paramsCount *(n / (n - paramsCount - 1));
|
|||
|
//}
|
|||
|
//lm version from paper
|
|||
|
/*double rss = RSS(original, model);
|
|||
|
double res = 2 * paramsCount + n * log(rss / (n - 2));
|
|||
|
return res;*/
|
|||
|
|
|||
|
///forecast 5.6 R package
|
|||
|
double res = 0;
|
|||
|
double lik = 0;
|
|||
|
double lik2 = 0;
|
|||
|
vector<double> e;
|
|||
|
//cout << "Aic " << endl;
|
|||
|
//cout << " e sum(lik) sum(lik2)" << endl;
|
|||
|
for (int i = 0; i < n; i++){
|
|||
|
//adderror
|
|||
|
e.push_back(original[i] - model[i]);
|
|||
|
//cout << " " << e[i];
|
|||
|
lik += e[i] * e[i];
|
|||
|
//cout << " " << lik;
|
|||
|
lik2 += log(fabs(model[i]));
|
|||
|
//cout << " " << lik2 << endl;
|
|||
|
// MULT lik += (original[i] - model[i])/ model[i];
|
|||
|
}
|
|||
|
lik = n * log(lik);
|
|||
|
//MULT lik +=2 *lik2;
|
|||
|
res = lik + 2 * paramsCount;
|
|||
|
//cout << " " << res << " " << endl;
|
|||
|
return res;
|
|||
|
}
|
|||
|
|
|||
|
double Aic::getValue(vector<double> original, vector<double> model) {
|
|||
|
return this->getValue(4, original, model);
|
|||
|
}
|