21 #define GRT_DLL_EXPORTS
31 this->useScaling = useScaling;
35 classType =
"LinearRegression";
36 regressifierType = classType;
37 debugLog.setProceedingText(
"[DEBUG LinearRegression]");
38 errorLog.setProceedingText(
"[ERROR LinearRegression]");
39 trainingLog.setProceedingText(
"[TRAINING LinearRegression]");
40 warningLog.setProceedingText(
"[WARNING LinearRegression]");
60 if( regressifier == NULL )
return false;
81 trainingResults.clear();
84 errorLog <<
"train_(RegressionData &trainingData) - Training data has zero samples!" << std::endl;
89 errorLog <<
"train_(RegressionData &trainingData) - The number of target dimensions is not 1!" << std::endl;
93 numInputDimensions = N;
94 numOutputDimensions = 1;
95 inputVectorRanges.clear();
96 targetVectorRanges.clear();
107 trainingData.
scale(inputVectorRanges,targetVectorRanges,0.0,1.0);
114 for(UINT j=0; j<N; j++){
122 bool keepTraining =
true;
124 TrainingResult result;
125 trainingResults.reserve(M);
130 for(UINT i=0; i<M; i++){
131 randomTrainingOrder[i] = i;
133 std::random_shuffle(randomTrainingOrder.begin(), randomTrainingOrder.end());
136 while( keepTraining ){
139 totalSquaredTrainingError = 0;
140 for(UINT m=0; m<M; m++){
143 UINT i = randomTrainingOrder[m];
149 for(UINT j=0; j<N; j++){
153 totalSquaredTrainingError += SQR( error );
156 for(UINT j=0; j<N; j++){
157 w[j] += learningRate * error * x[j];
159 w0 += learningRate * error;
163 delta = fabs( totalSquaredTrainingError-lastError );
164 lastError = totalSquaredTrainingError;
167 if( delta <= minChange ){
168 keepTraining =
false;
171 if( grt_isinf( totalSquaredTrainingError ) || grt_isnan( totalSquaredTrainingError ) ){
172 errorLog <<
"train_(RegressionData &trainingData) - Training failed! Total squared training error is NAN. If scaling is not enabled then you should try to scale your data and see if this solves the issue." << std::endl;
176 if( ++iter >= maxNumEpochs ){
177 keepTraining =
false;
181 rootMeanSquaredTrainingError = sqrt( totalSquaredTrainingError / Float(M) );
182 result.setRegressionResult(iter,totalSquaredTrainingError,rootMeanSquaredTrainingError,
this);
183 trainingResults.push_back( result );
186 trainingResultsObserverManager.notifyObservers( result );
188 trainingLog <<
"Epoch: " << iter <<
" SSE: " << totalSquaredTrainingError <<
" Delta: " << delta << std::endl;
192 regressionData.
resize(1,0);
200 errorLog <<
"predict_(VectorFloat &inputVector) - Model Not Trained!" << std::endl;
204 if( !trained )
return false;
206 if( inputVector.size() != numInputDimensions ){
207 errorLog <<
"predict_(VectorFloat &inputVector) - The size of the input Vector (" << int( inputVector.size() ) <<
") does not match the num features in the model (" << numInputDimensions << std::endl;
212 for(UINT n=0; n<numInputDimensions; n++){
213 inputVector[n] =
scale(inputVector[n], inputVectorRanges[n].minValue, inputVectorRanges[n].maxValue, 0, 1);
217 regressionData[0] = w0;
218 for(UINT j=0; j<numInputDimensions; j++){
219 regressionData[0] += inputVector[j] * w[j];
223 for(UINT n=0; n<numOutputDimensions; n++){
224 regressionData[n] =
scale(regressionData[n], 0, 1, targetVectorRanges[n].minValue, targetVectorRanges[n].maxValue);
235 errorLog <<
"save(fstream &file) - The file is not open!" << std::endl;
240 file<<
"GRT_LINEAR_REGRESSION_MODEL_FILE_V2.0\n";
244 errorLog <<
"save(fstream &file) - Failed to save Regressifier base settings to file!" << std::endl;
251 for(UINT j=0; j<numInputDimensions; j++){
266 errorLog <<
"load( fstream &file ) - Could not open file to load model" << std::endl;
276 if( word ==
"GRT_LINEAR_REGRESSION_MODEL_FILE_V1.0" ){
280 if( word !=
"GRT_LINEAR_REGRESSION_MODEL_FILE_V2.0" ){
281 errorLog <<
"load( fstream &file ) - Could not find Model File Header" << std::endl;
287 errorLog <<
"load( fstream &file ) - Failed to save Regressifier base settings to file!" << std::endl;
294 w.
resize(numInputDimensions);
298 if(word !=
"Weights:"){
299 errorLog <<
"load( fstream &file ) - Could not find the Weights!" << std::endl;
304 for(UINT j=0; j<numInputDimensions; j++){
326 if(word !=
"NumFeatures:"){
327 errorLog <<
"loadLegacyModelFromFile( fstream &file ) - Could not find NumFeatures!" << std::endl;
330 file >> numInputDimensions;
333 if(word !=
"NumOutputDimensions:"){
334 errorLog <<
"loadLegacyModelFromFile( fstream &file ) - Could not find NumOutputDimensions!" << std::endl;
337 file >> numOutputDimensions;
340 if(word !=
"UseScaling:"){
341 errorLog <<
"loadLegacyModelFromFile( fstream &file ) - Could not find UseScaling!" << std::endl;
349 inputVectorRanges.
resize(numInputDimensions);
350 targetVectorRanges.
resize(numOutputDimensions);
354 if(word !=
"InputVectorRanges:"){
356 errorLog <<
"loadLegacyModelFromFile( fstream &file ) - Failed to find InputVectorRanges!" << std::endl;
359 for(UINT j=0; j<inputVectorRanges.size(); j++){
360 file >> inputVectorRanges[j].minValue;
361 file >> inputVectorRanges[j].maxValue;
365 if(word !=
"OutputVectorRanges:"){
367 errorLog <<
"loadLegacyModelFromFile( fstream &file ) - Failed to find OutputVectorRanges!" << std::endl;
370 for(UINT j=0; j<targetVectorRanges.size(); j++){
371 file >> targetVectorRanges[j].minValue;
372 file >> targetVectorRanges[j].maxValue;
377 w.
resize(numInputDimensions);
381 if(word !=
"Weights:"){
382 errorLog <<
"loadLegacyModelFromFile( fstream &file ) - Could not find the Weights!" << std::endl;
387 for(UINT j=0; j<numInputDimensions; j++){
393 regressionData.
resize(1,0);
This class implements the Linear Regression algorithm. Linear Regression is a simple but effective re...
Float scale(const Float &x, const Float &minSource, const Float &maxSource, const Float &minTarget, const Float &maxTarget, const bool constrain=false)
virtual bool predict_(VectorFloat &inputVector)
LinearRegression(bool useScaling=false)
Vector< MinMax > getInputRanges() const
virtual bool resize(const unsigned int size)
virtual ~LinearRegression(void)
bool copyBaseVariables(const Regressifier *regressifier)
UINT getNumInputDimensions() const
Vector< MinMax > getTargetRanges() const
bool saveBaseSettingsToFile(std::fstream &file) const
bool scale(const Float minTarget, const Float maxTarget)
UINT getMaxNumEpochs() const
UINT getNumTargetDimensions() const
std::string getRegressifierType() const
virtual bool save(std::fstream &file) const
bool loadBaseSettingsFromFile(std::fstream &file)
LinearRegression & operator=(const LinearRegression &rhs)
bool setMaxNumIterations(const UINT maxNumIterations)
virtual bool load(std::fstream &file)
virtual bool train_(RegressionData &trainingData)
Float getRandomNumberUniform(Float minRange=0.0, Float maxRange=1.0)
virtual bool deepCopyFrom(const Regressifier *regressifier)
bool loadLegacyModelFromFile(std::fstream &file)
bool setMaxNumEpochs(const UINT maxNumEpochs)
UINT getMaxNumIterations() const
UINT getNumSamples() const