28 RegisterRegressifierModule< LinearRegression > LinearRegression::registerModule(
"LinearRegression");
30 LinearRegression::LinearRegression(
bool useScaling)
32 this->useScaling = useScaling;
36 classType =
"LinearRegression";
37 regressifierType = classType;
38 debugLog.setProceedingText(
"[DEBUG LinearRegression]");
39 errorLog.setProceedingText(
"[ERROR LinearRegression]");
40 trainingLog.setProceedingText(
"[TRAINING LinearRegression]");
41 warningLog.setProceedingText(
"[WARNING LinearRegression]");
44 LinearRegression::~LinearRegression(
void)
59 bool LinearRegression::deepCopyFrom(
const Regressifier *regressifier){
61 if( regressifier == NULL )
return false;
71 return copyBaseVariables( regressifier );
82 trainingResults.clear();
85 errorLog <<
"train_(RegressionData &trainingData) - Training data has zero samples!" << endl;
90 errorLog <<
"train_(RegressionData &trainingData) - The number of target dimensions is not 1!" << endl;
94 numInputDimensions = N;
95 numOutputDimensions = 1;
96 inputVectorRanges.clear();
97 targetVectorRanges.clear();
108 trainingData.
scale(inputVectorRanges,targetVectorRanges,0.0,1.0);
115 for(UINT j=0; j<N; j++){
120 double lastError = 0;
123 bool keepTraining =
true;
124 vector< UINT > randomTrainingOrder(M);
126 trainingResults.reserve(M);
131 for(UINT i=0; i<M; i++){
132 randomTrainingOrder[i] = i;
134 std::random_shuffle(randomTrainingOrder.begin(), randomTrainingOrder.end());
137 while( keepTraining ){
140 totalSquaredTrainingError = 0;
141 for(UINT m=0; m<M; m++){
144 UINT i = randomTrainingOrder[m];
147 VectorDouble x = trainingData[i].getInputVector();
148 VectorDouble y = trainingData[i].getTargetVector();
150 for(UINT j=0; j<N; j++){
154 totalSquaredTrainingError += SQR( error );
157 for(UINT j=0; j<N; j++){
158 w[j] += learningRate * error * x[j];
160 w0 += learningRate * error;
164 delta = fabs( totalSquaredTrainingError-lastError );
165 lastError = totalSquaredTrainingError;
168 if( delta <= minChange ){
169 keepTraining =
false;
172 if( grt_isinf( totalSquaredTrainingError ) || grt_isnan( totalSquaredTrainingError ) ){
173 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." << endl;
177 if( ++iter >= maxNumEpochs ){
178 keepTraining =
false;
182 rootMeanSquaredTrainingError = sqrt( totalSquaredTrainingError /
double(M) );
183 result.
setRegressionResult(iter,totalSquaredTrainingError,rootMeanSquaredTrainingError,
this);
184 trainingResults.push_back( result );
187 trainingResultsObserverManager.notifyObservers( result );
189 trainingLog <<
"Epoch: " << iter <<
" SSE: " << totalSquaredTrainingError <<
" Delta: " << delta << endl;
193 regressionData.resize(1,0);
198 bool LinearRegression::predict_(VectorDouble &inputVector){
201 errorLog <<
"predict_(VectorDouble &inputVector) - Model Not Trained!" << endl;
205 if( !trained )
return false;
207 if( inputVector.size() != numInputDimensions ){
208 errorLog <<
"predict_(VectorDouble &inputVector) - The size of the input vector (" << int( inputVector.size() ) <<
") does not match the num features in the model (" << numInputDimensions << endl;
213 for(UINT n=0; n<numInputDimensions; n++){
214 inputVector[n] = scale(inputVector[n], inputVectorRanges[n].minValue, inputVectorRanges[n].maxValue, 0, 1);
218 regressionData[0] = w0;
219 for(UINT j=0; j<numInputDimensions; j++){
220 regressionData[0] += inputVector[j] * w[j];
224 for(UINT n=0; n<numOutputDimensions; n++){
225 regressionData[n] = scale(regressionData[n], 0, 1, targetVectorRanges[n].minValue, targetVectorRanges[n].maxValue);
232 bool LinearRegression::saveModelToFile(fstream &file)
const{
236 errorLog <<
"loadModelFromFile(fstream &file) - The file is not open!" << endl;
241 file<<
"GRT_LINEAR_REGRESSION_MODEL_FILE_V2.0\n";
244 if( !Regressifier::saveBaseSettingsToFile(file) ){
245 errorLog <<
"saveModelToFile(fstream &file) - Failed to save Regressifier base settings to file!" << endl;
252 for(UINT j=0; j<numInputDimensions; j++){
261 bool LinearRegression::loadModelFromFile(fstream &file){
267 errorLog <<
"loadModelFromFile( fstream &file ) - Could not open file to load model" << endl;
277 if( word ==
"GRT_LINEAR_REGRESSION_MODEL_FILE_V1.0" ){
278 return loadLegacyModelFromFile( file );
281 if( word !=
"GRT_LINEAR_REGRESSION_MODEL_FILE_V2.0" ){
282 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find Model File Header" << endl;
287 if( !Regressifier::loadBaseSettingsFromFile(file) ){
288 errorLog <<
"loadModelFromFile( fstream &file ) - Failed to save Regressifier base settings to file!" << endl;
295 w.resize(numInputDimensions);
299 if(word !=
"Weights:"){
300 errorLog <<
"loadModelFromFile( fstream &file ) - Could not find the Weights!" << endl;
305 for(UINT j=0; j<numInputDimensions; j++){
314 bool LinearRegression::setMaxNumIterations(
const UINT maxNumIterations){
315 return setMaxNumEpochs( maxNumIterations );
318 UINT LinearRegression::getMaxNumIterations()
const{
319 return getMaxNumEpochs();
322 bool LinearRegression::loadLegacyModelFromFile( fstream &file ){
327 if(word !=
"NumFeatures:"){
328 errorLog <<
"loadLegacyModelFromFile( fstream &file ) - Could not find NumFeatures!" << endl;
331 file >> numInputDimensions;
334 if(word !=
"NumOutputDimensions:"){
335 errorLog <<
"loadLegacyModelFromFile( fstream &file ) - Could not find NumOutputDimensions!" << endl;
338 file >> numOutputDimensions;
341 if(word !=
"UseScaling:"){
342 errorLog <<
"loadLegacyModelFromFile( fstream &file ) - Could not find UseScaling!" << endl;
350 inputVectorRanges.resize(numInputDimensions);
351 targetVectorRanges.resize(numOutputDimensions);
355 if(word !=
"InputVectorRanges:"){
357 errorLog <<
"loadLegacyModelFromFile( fstream &file ) - Failed to find InputVectorRanges!" << endl;
360 for(UINT j=0; j<inputVectorRanges.size(); j++){
361 file >> inputVectorRanges[j].minValue;
362 file >> inputVectorRanges[j].maxValue;
366 if(word !=
"OutputVectorRanges:"){
368 errorLog <<
"loadLegacyModelFromFile( fstream &file ) - Failed to find OutputVectorRanges!" << endl;
371 for(UINT j=0; j<targetVectorRanges.size(); j++){
372 file >> targetVectorRanges[j].minValue;
373 file >> targetVectorRanges[j].maxValue;
378 w.resize(numInputDimensions);
382 if(word !=
"Weights:"){
383 errorLog <<
"loadLegacyModelFromFile( fstream &file ) - Could not find the Weights!" << endl;
388 for(UINT j=0; j<numInputDimensions; j++){
394 regressionData.resize(1,0);
This class implements the Linear Regression algorithm. Linear Regression is a simple but effective re...
bool setRegressionResult(unsigned int trainingIteration, double totalSquaredTrainingError, double rootMeanSquaredTrainingError, MLBase *trainer)
vector< MinMax > getInputRanges() const
UINT getNumSamples() const
string getRegressifierType() const
vector< MinMax > getTargetRanges() const
double getRandomNumberUniform(double minRange=0.0, double maxRange=1.0)
UINT getNumTargetDimensions() const
UINT getNumInputDimensions() const
bool scale(const double minTarget, const double maxTarget)