#include "MLLinReg.h" #include "SystemConfig.h" #include #include #include MLLinReg::MLLinReg(CappedStorage *storage) : MLAnalyzer(storage) { criticalResidualCurrent = SystemConfig::getFloatConfigParameter("crit_residual_current"); criticalTimeRangeSec = SystemConfig::getIntConfigParameter("crit_residual_timerange") * SECONDS_IN_WEEK; Theta.resize(2, 1); } MLAlert MLLinReg::updateModel() { if(t0 == 0 && data->getX().rows() != 0) {LOG(INFO) << std::setprecision(12) << std::fixed << "t_0 = " << (data->getX())(0, 1); t0 = (data->getX())(0, 1);} if(++updateCounter < updateRate) return MLAlert(CustomAlertTypes::NO_ALERT, ""); updateCounter = 0; LOG(INFO) << "Update Linear Regression Model"; normalEquation(); bool error = checkCritical(); if(error){ //Return an alert object if tendency is critical std::stringstream ans; ans << "Received critical tendency in the next " << std::round(criticalTimeRangeSec/SECONDS_IN_WEEK) << " seconds"; //LOG(INFO) << "Theta values: " << Theta(0) << " " << Theta(1); //if(first){ // std::ofstream file; // std::stringstream ss; // file.open("debug_lin_reg.txt", std::ios::out); // if(file.is_open()){ // file << std::setprecision(12) << std::fixed << "Theta: " << Theta(0) << " " << Theta(1) << std::endl; // file << std::setprecision(12) << std::fixed << "X: " << data->getX()(data->getX().rows()-1, 1) << std::endl; // file << std::setprecision(12) << std::fixed << "y: " << data->getY()(data->getY().rows()-1) << std::endl; // file << std::setprecision(12) << std::fixed << "t0: " << t0 << std::endl; // file << std::setprecision(12) << std::fixed << std::endl; // file.close(); // } // first = false; //} return MLAlert(CustomAlertTypes::CRIT_RCM_TENDENCY, ans.str()); } else return MLAlert(CustomAlertTypes::NO_ALERT, ""); } bool MLLinReg::checkCritical(){ //Check, if the critical value is reached within the specified time range if(data->getM() == 0) return false; //Offset, to avoid checking with little data and receive faulty results if(data->getM() < 100) return false; return (Theta(0) + Theta(1) * ((data->getX())((data->getX()).rows()-1, 1) + criticalTimeRangeSec)) >= criticalResidualCurrent; } //Numerical approach to solve univariate Linear Regression Model void MLLinReg::normalEquation() { Theta = Eigen::MatrixXd::Zero(2, 1); Theta = (data->getX().transpose() * data->getX()).inverse() * data->getX().transpose() * data->getY(); if(data->getX().rows() > 500){ LOG(INFO) << Theta(0) << " " << Theta(1); LOG(INFO) << data->getX().rows(); } }