Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

prediction.cc

Go to the documentation of this file.
00001 
00025 #include <magic/mobject.h>
00026 #include <magic/mtextstream.h>
00027 
00028 #include <inanna/annetwork.h>
00029 #include <inanna/trainer.h>
00030 #include <inanna/rprop.h>
00031 #include <inanna/patternset.h>
00032 #include <inanna/equalization.h>
00033 #include <inanna/annfilef.h>
00034 #include <inanna/prediction.h>
00035 
00036 impl_dynamic (PredictionStrategy, {Object});
00037 impl_dynamic (ZeroDeltaPrediction, {PredictionStrategy});
00038 impl_dynamic (AverageDeltaPrediction, {PredictionStrategy});
00039 impl_dynamic (PreviousYear, {PredictionStrategy});
00040 impl_dynamic (PreviousYearsAvg, {PredictionStrategy});
00041 impl_dynamic (CombinedPrediction, {PredictionStrategy});
00042 impl_dynamic (AbsoluteNeuralPrediction, {PredictionStrategy});
00043 impl_dynamic (SingleNeuralPrediction, {AbsoluteNeuralPrediction});
00044 impl_dynamic (DeltaNeuralPrediction, {PredictionStrategy});
00045 
00046 
00047 /*******************************************************************************
00048  *
00049 **/
00050 Ref<MonthlyDataSet> MonthlyDataSet::sub (int row0, int row1, int col0, int col1) const
00051 {
00052     Ref<MonthlyDataSet> result = new MonthlyDataSet (Matrix::sub (row0, row1, col0, col1));
00053     result->mFirstMonth0 = (mFirstMonth0+row0)%12;
00054     result->mFirstYear = mFirstYear+(mFirstMonth0+row0)/12;
00055     result->mLag = mLag;
00056     return result;
00057 }
00058 
00059 
00061 //   _             | o     o             -----                 ----                    |           //
00062 //  / \            |    |      _           |    ___   ____  |  |   )  ___   ____       |  |   ____ //
00063 // /   \ |   |  ---| | -+- | |/ \   ___    |   /   ) (     -+- |---  /   ) (     |   | | -+- (     //
00064 // |---| |   | (   | |  |  | |   | (   \   |   |---   \__   |  | \   |---   \__  |   | |  |   \__  //
00065 // |   |  \__!  ---| |   \ | |   |  ---/   |    \__  ____)   \ |  \   \__  ____)  \__! |   \ ____) //
00066 //                                  __/                                                            //
00068 
00071 void PredictionTestResults::make (int variables )
00072 {
00073     averageError = 0.0;
00074     MSE = 0.0;
00075     RMSE = 0.0;
00076     averageErrors.make(variables);
00077     MSEs.make(variables);
00078     RMSEs.make(variables);
00079     for (int i=0; i<MSEs.size(); i++) {
00080         averageErrors[i] = 0.0;
00081         MSEs[i] = 0.0;
00082         RMSEs[i] = 0.0;
00083     }
00084     mValues = 0;
00085 }
00086 
00089 void PredictionTestResults::addValue (int variable,
00090                                     double value)
00091 {
00092     averageError += value;
00093     MSE += value*value;
00094     averageErrors[variable] += value;
00095     MSEs[variable] += value*value;
00096 
00097     if (variable==0)
00098         mValues++;
00099 }
00100 
00103 void PredictionTestResults::calculate ()
00104 {
00105     averageError /= mValues * MSEs.size();
00106     MSE /= mValues * MSEs.size();
00107     RMSE = sqrt (MSE);
00108     for (int i=0; i<MSEs.size(); i++) {
00109         averageErrors[i] /= mValues;
00110         MSEs[i] /= mValues;
00111         RMSEs[i] = sqrt (MSEs[i]);
00112     }
00113 }
00114 
00117 OStream& PredictionTestResults::operator>> (OStream& out) const
00118 {
00119     printf ("Average error = %f\n", averageError);
00120     printf ("Mean Squared Error = %f\n", MSE);
00121     printf ("Root of Mean Squared Error = %f\n", RMSE);
00122     printf ("Variable\tavgErr\t\tMSE\t\tRMSE\n");
00123     for (int i=0; i<MSEs.size(); i++)
00124         printf ("%3d\t\t%#5.10g\t%#5.10g\t%5.10g\n",
00125                 i+1, averageErrors[i], MSEs[i], RMSEs[i]);
00126     return out;
00127 }
00128 
00130 //   _             | o     o              ----                                     //
00131 //  / \            |    |      _         (      |       ___   |   ___              //
00132 // /   \ |   |  ---| | -+- | |/ \   ___   ---  -+- |/\  ___| -+- /   )  ___  \   | //
00133 // |---| |   | (   | |  |  | |   | (   \     )  |  |   (   |  |  |---  (   \  \  | //
00134 // |   |  \__!  ---| |   \ | |   |  ---/ ___/    \ |    \__|   \  \__   ---/   \_/ //
00135 //                                  __/                                 __/   \_/  //
00137 
00139 void PredictionStrategy::make (const StringMap& params)
00140 {
00141     mInputMonths    = params["inputMonths"].toInt();
00142 }
00143 
00152 void PredictionStrategy::train (
00153     const Matrix& traindata, 
00154     int           startmonth)
00155 {
00156     MUST_OVERLOAD;
00157 }
00158 
00165 Ref<Matrix> PredictionStrategy::predict (
00166     const Matrix& testdata,
00167     int           startmonth) const
00168 {
00169     MUST_OVERLOAD;
00170     return Ref<Matrix> (NULL);
00171 }
00172 
00186 /*virtual*/ PredictionTestResults* PredictionStrategy::test (
00187     const Matrix& testdata,
00188     int           startmonth) const
00189 {
00190     // Let the strategy do the prediction
00191     Ref<Matrix> testresRef = predict (testdata, startmonth);
00192     Matrix& testres = testresRef;
00193 
00194     /**********************************************/
00195     /* Collect error statistics for each pattern  */
00196 
00197     // Create result storage object
00198     PredictionTestResults* result = new PredictionTestResults ();
00199     result->make (testres.cols);
00200 
00201     // Iterate through test patterns. Skip the mInputMonths, since they are
00202     // not actual test data points.
00203     for (int r=0; r<testres.rows; r++) {
00204         // Calculate error for one test pattern
00205         for (int c=0; c<testres.cols; c++) {
00206             // Calculate error between the desired and predicted value
00207             double error = fabs (testdata.get(r+inputMonths(),c) - testres.get(r,c));
00208             //printf ("row=%d, col=%d, error=%f\n", r, c, error);
00209             
00210             // Add one sample to the statistics calculator
00211             result->addValue (c, error);
00212         }
00213     }
00214 
00215     // Finalize the statistics calculation
00216     result->calculate ();
00217     return result;
00218 }
00219 
00224 void PredictionStrategy::testCurve (const Matrix& testdata, int startmonth, const String& filename) const
00225 {
00226 }
00227 
00236 Ref<Matrix> PredictionStrategy::rowDeltas (const Matrix& matrix)
00237 {
00238     Ref<Matrix> result = new Matrix (matrix.rows-1, matrix.cols);
00239     Matrix& deltas = result.object();
00240 
00241     // Calculate row deltas
00242     for (int r=0; r<deltas.rows; r++)
00243         for (int c=0; c<deltas.cols; c++)
00244             deltas.get(r,c) = matrix.get(r+1,c) - matrix.get(r,c);
00245 
00246     return result;
00247 }
00248 
00250 //    _                                     ___         |           ----     //
00251 //   / \         ___       ___         ___  |  \   ___  |  |   ___  |   )    //
00252 //  /   \ |   | /   ) |/\  ___|  ___  /   ) |   | /   ) | -+-  ___| |---     //
00253 //  |---|  \ /  |---  |   (   | (   \ |---  |   | |---  |  |  (   | |        //
00254 //  |   |   V    \__  |    \__|  ---/  \__  |__/   \__  |   \  \__| |     O  //
00255 //                               __/                                         //
00257 
00258 AverageDeltaPrediction::AverageDeltaPrediction (
00259     const StringMap& params)
00260         : PredictionStrategy ("AverageDelta")
00261 {
00262 }
00263 
00264 /*virtual*/ void AverageDeltaPrediction::train (
00265     const Matrix& traindata, 
00266     int           startmonth )
00267 {
00268     ASSERT ((int(fabs(traindata.get(0,0)-traindata.get(1,0)+0.001))%100) != 1);
00269     //cout << "traindata " << traindata.rows << " rows, startmonth=" << startmonth << "\n";
00270     
00271     // Calculate deltas
00272     Ref<Matrix> deltasRef = rowDeltas (traindata);
00273     Matrix& deltas = deltasRef.object();
00274     
00275     // Initialize average matrix
00276     mMonthAvg.make (12, deltas.cols);
00277     mMonthCnt.make (12);
00278     for (int r=0; r<mMonthAvg.rows; r++) {
00279         for (int c=0; c<mMonthAvg.cols; c++)
00280             mMonthAvg.get(r,c) = 0.0;
00281         mMonthCnt[r] = 0;
00282     }
00283     
00284     // Calculate average deltas for each month
00285     int startmonthi = startmonth%100;
00286     for (int r=0; r<deltas.rows; r++) {
00287         int month = (startmonthi+r-1+1+12)%12;
00288         for (int c=0; c<deltas.cols; c++)
00289             mMonthAvg.get(month,c) = (mMonthAvg.get(month,c)*mMonthCnt[month]
00290                                       + deltas.get(r,c))/ (mMonthCnt[month]+1);
00291         mMonthCnt[month]++;
00292     }
00293 }
00294 
00295 /*virtual*/ Ref<Matrix> AverageDeltaPrediction::predict (const Matrix& testdata, int startmonth) const {
00296     Ref<Matrix> result = new Matrix (testdata.rows-inputMonths(), testdata.cols);
00297     int startmonthi = startmonth%100;
00298     for (int r=0; r<result->rows; r++) {
00299         for (int c=0; c<testdata.cols; c++) {
00300             int month = (startmonthi+inputMonths()+r-1)%12;
00301             result->get(r,c) = testdata.get(r+inputMonths()-1,c) + mMonthAvg.get(month, c);
00302         }
00303     }
00304     return result;
00305 }
00306 
00307 
00308 
00310 //           -----                ___         |           ----              //
00311 //              /   ___           |  \   ___  |  |   ___  |   )             //
00312 //             /   /   ) |/\  __  |   | /   ) | -+-  ___| |---              //
00313 //            /    |---  |   /  \ |   | |---  |  |  (   | |                 //
00314 //           /____  \__  |   \__/ |__/   \__  |   \  \__| |     O           //
00316 
00317 ZeroDeltaPrediction::ZeroDeltaPrediction (const StringMap& params) : PredictionStrategy ("ZeroDelta") {
00318 }
00319 
00320 /*virtual*/ void ZeroDeltaPrediction::train (const Matrix& traindata, int startmonth) {
00321 }
00322 
00323 /*virtual*/ Ref<Matrix> ZeroDeltaPrediction::predict (const Matrix& testdata, int startmonth) const {
00324     Ref<Matrix> result = new Matrix (testdata.rows-1, testdata.cols);
00325     for (int r=0; r<result->rows; r++)
00326         for (int c=0; c<result->cols; c++)
00327             result->get(r,c) = testdata.get(r,c);
00328     return result;
00329 }
00330 
00331 
00332 
00334 //  ___                   o                 | ----                | o           o            //
00335 // /   \            |         _    ___      | |   )      ___      |    ___   |           _   //
00336 // |      __  |/|/| |---  | |/ \  /   )  ---| |---  |/\ /   )  ---| | |   \ -+- |  __  |/ \  //
00337 // |     /  \ | | | |   ) | |   | |---  (   | |     |   |---  (   | | |      |  | /  \ |   | //
00338 // \___/ \__/ | | | |__/  | |   |  \__   ---| |     |    \__   ---| |  \__/   \ | \__/ |   | //
00340 
00341 CombinedPrediction::CombinedPrediction (const StringMap& params) : PredictionStrategy ("CombinedPrediction")
00342 {
00343     make (params);
00344 }
00345 
00346 void CombinedPrediction::make (const StringMap& params)
00347 {
00348     PredictionStrategy::make (params);
00349     
00350     // Create and initialize predictors
00351     mPredictors.add (new ZeroDeltaPrediction (params));
00352     mPredictors.add (new PreviousYear (params));
00353     mPredictors.add (new PreviousYearsAvg (params));
00354     mPredictors.add (new AverageDeltaPrediction (params));
00355     
00356     // We use the biggest number of required input months
00357     mInputMonths = determineInputMonths ();
00358 }
00359 
00360 int CombinedPrediction::determineInputMonths () const
00361 {
00362     // Find the biggest number of required input months
00363     int inputMonths=0;
00364     for (int i=0; i<mPredictors.size(); i++)
00365         if (mPredictors[i].inputMonths() > inputMonths)
00366             inputMonths = mPredictors[i].inputMonths();
00367     return inputMonths;
00368 }
00369 
00370 /*virtual*/ void CombinedPrediction::train (const Matrix& traindata, int startmonth)
00371 {
00372     int firstMonth = (startmonth%100)-1; // Zero-based month number
00373 
00374     // Train the predictors
00375     for (int p=0; p<mPredictors.size(); p++)
00376         mPredictors[p].train (traindata, startmonth);
00377 
00379     // Evaluate the capability of predictors for each month/variable pair
00380     
00381     // Record the ID of the best predictor found so far
00382     mPredictorChoises.make (12, traindata.cols);
00383     for (int r=0; r<12; r++)
00384         for (int c=0; c<traindata.cols; c++)
00385             mPredictorChoises.get(r,c) = 0;
00386 
00387     // Record the smallest error found so far
00388     Matrix smallestError (12, traindata.cols);
00389     smallestError = 1e30;
00390 
00391     // Use training data as test data
00392     const Matrix& testdata = traindata;
00393     
00394     // Test each predictor
00395     for (int p=0; p<mPredictors.size(); p++) {
00396         //cout << "\nPredictor " << p << ":\n";
00397         int predictorInputMonths = mPredictors[p].inputMonths();
00398 
00399         // Test the training data with a predictor
00400         Ref<Matrix> predictionRef = mPredictors[p].predict (testdata, startmonth);
00401         Matrix& prediction = predictionRef.object();
00402 
00403         // WARNING: Unused
00404         // int firstResultMonth = (firstMonth+predictorInputMonths)%12;
00405         
00406         // See if it did better than other predictors for any value
00407         for (int m=0; m<12 || m<prediction.rows; m++) {
00408             for (int v=0; v<prediction.cols; v++) {
00409                 int testDataRow = m+predictorInputMonths;
00410 
00411                 // Average over all years
00412                 double error = 0.0;
00413                 int year=0;
00414                 for (; year*12+m<prediction.rows; year++)
00415                     error += fabs(prediction.get(year*12+m,v)-testdata.get(year*12+testDataRow,v));
00416 
00417                 // Calculate average error
00418                 error /= year;
00419 
00420                 // Ignore too small errors. They probably imply overfitting
00421                 if (error > 0.001) {
00422 
00423                     // Check if the result is better than with other methods
00424                     int month = (testDataRow+firstMonth)%12;
00425                     if (error < smallestError.get(month,v)) {
00426                         // It is. Use this method to predict this month/variable.
00427                         smallestError.get(month,v) = error;
00428                         mPredictorChoises.get(month,v) = p;
00429                     }
00430                 }
00431             }
00432         }
00433     }
00434 
00435     //for (int r=0; r<12; r++) {
00436     //  for (int c=0; c<traindata.cols; c++)
00437     //      cout << mPredictorChoises.get(r,c) << " ";
00438     //  cout << "\n";
00439     //}
00440 }
00441 
00442 /*virtual*/ Ref<Matrix> CombinedPrediction::predict (const Matrix& testdata, int startmonth) const {
00443     int firstMonth = (startmonth%100)-1; // Zero-based month
00444     Ref<Matrix> result = new Matrix (testdata.rows-inputMonths(), testdata.cols);
00445     
00446     // Test each predictor
00447     for (int p=0; p<mPredictors.size(); p++) {
00448         int predictorInputMonths = mPredictors[p].inputMonths();
00449 
00450         Matrix testdata2 = testdata.sub (inputMonths()-predictorInputMonths, Matrix::end, 0, Matrix::end);
00451         int firstTestMonth = (firstMonth+inputMonths()-predictorInputMonths)%12;
00452         
00453         // Test the training data with a predictor
00454         Ref<Matrix> predictionRef = mPredictors[p].predict (testdata2, firstTestMonth+1);
00455         Matrix& prediction = predictionRef.object();
00456 
00457         // Apply the predictor to those datapoints which it has been
00458         // found to predict well
00459         for (int r=0; r<result->rows; r++)
00460             for (int c=0; c<result->cols; c++)
00461                 if (mPredictorChoises.get((r+firstTestMonth+predictorInputMonths)%12, c) == p)
00462                     result->get(r,c) = prediction.get(r, c);
00463     }
00464 
00465     return result;
00466 }
00467 
00468 
00469 
00471 //                                                                          //
00472 //         ----                  o                                          //
00473 //         |   )      ___                      ____  ___   ___              //
00474 //         |---  |/\ /   ) |   | |  __  |   | (     /   )  ___| |/\         //
00475 //         |     |   |---   \ /  | /  \ |   |  \__  |---  (   | |           //
00476 //         |     |    \__    V   | \__/  \__! ____)  \__   \__| |           //
00477 //                                                                          //
00479 
00480 PreviousYear::PreviousYear (const StringMap& params) : PredictionStrategy ("PreviousYear") {
00481 }
00482 
00483 /*virtual*/ void PreviousYear::train (const Matrix& traindata, int startmonth) {
00484     ASSERT (traindata.rows >= 12);
00485     ASSERT ((startmonth%100) == 1);
00486     
00487     // One year
00488     mData.make (12, traindata.cols);
00489     for (int r=0; r<mData.rows; r++)
00490         for (int c=0; c<mData.cols; c++)
00491             mData.get(r,c) = traindata.get (traindata.rows-12+r,c);
00492 }
00493 
00494 /*virtual*/ Ref<Matrix> PreviousYear::predict (const Matrix& testdata, int startmonth) const {
00495     ASSERT (mData.rows>0);
00496     ASSERT ((startmonth%100) == 1);
00497 
00498     Ref<Matrix> result = new Matrix (testdata.rows, testdata.cols);
00499     int firstMonth = (startmonth%100)-1; // Zero-based month
00500     for (int r=0; r<result->rows; r++)
00501         for (int c=0; c<result->cols; c++)
00502             result->get (r,c) = mData.get ((r+firstMonth)%12,c);
00503 
00504     return result;
00505 }
00506 
00507 
00508 
00510 //                                                                                  //
00511 // ----                  o                                          _               //
00512 // |   )      ___                      ____  ___   ___       ____  / \              //
00513 // |---  |/\ /   ) |   | |  __  |   | (     /   )  ___| |/\ (     /   \ |   |  ___  //
00514 // |     |   |---   \ /  | /  \ |   |  \__  |---  (   | |    \__  |---|  \ /  (   \ //
00515 // |     |    \__    V   | \__/  \__! ____)  \__   \__| |   ____) |   |   V    ---/ //
00516 //                                                                             __/  //
00518 
00519 PreviousYearsAvg::PreviousYearsAvg (const StringMap& params) : PredictionStrategy ("PreviousYearsAvg") {
00520 }
00521 
00522 /*virtual*/ void PreviousYearsAvg::train (const Matrix& traindata, int startmonth) {
00523     ASSERT (traindata.rows >= 24);
00524     
00525     // One year
00526     mMonthlyAvg.make (12, traindata.cols);
00527     for (int r=0; r<mMonthlyAvg.rows; r++)
00528         for (int c=0; c<mMonthlyAvg.cols; c++) {
00529             // Calculate average of previous years
00530             float sum = 0.0;
00531             int year = 0;
00532             for (; traindata.rows-12+r-year*12 >= 0; year++)
00533                 sum += traindata.get (traindata.rows-12+r-year*12, c);
00534             mMonthlyAvg.get(r,c) = sum/float(year);
00535         }
00536 }
00537 
00538 /*virtual*/ Ref<Matrix> PreviousYearsAvg::predict (const Matrix& testdata, int startmonth) const {
00539     ASSERT (mMonthlyAvg.rows>0);
00540 
00541     int firstMonth = (startmonth%100)-1; // Zero-based month
00542     Ref<Matrix> result = new Matrix (testdata.rows, testdata.cols);
00543     for (int r=0; r<result->rows; r++)
00544         for (int c=0; c<result->cols; c++)
00545             result->get(r,c) = mMonthlyAvg.get((firstMonth+r)%12, c);
00546 
00547     return result;
00548 }
00549 
00550 
00551 
00553 //   _                    |                 |   |                       | ----    //
00554 //  / \  |      ____      |        |   ___  |\  |  ___             ___  | |   )   //
00555 // /   \ |---  (      __  | |   | -+- /   ) | \ | /   ) |   | |/\  ___| | |---    //
00556 // |---| |   )  \__  /  \ | |   |  |  |---  |  \| |---  |   | |   (   | | |       //
00557 // |   | |__/  ____) \__/ |  \__!   \  \__  |   |  \__   \__! |    \__| | |     O //
00559 
00560 AbsoluteNeuralPrediction::~AbsoluteNeuralPrediction () {
00561     delete mpNetwork;
00562 }
00563 
00564 void AbsoluteNeuralPrediction::make (const StringMap& params) {
00565     mUseAllOutputs      = params["AbsoluteNeuralPrediction.useAllOutputs"].toInt();
00566     mUseAllInputs       = params["AbsoluteNeuralPrediction.useAllInputs"].toInt();
00567     ASSERT (mUseAllInputs || (!mUseAllInputs && !mUseAllOutputs));
00568 
00569     mGlobalEqualization = params["AbsoluteNeuralPrediction.globalEqualization"].toInt();
00570     mHiddenTopology     = params["AbsoluteNeuralPrediction.hidden"];
00571     mpNetwork           = NULL;
00572 
00573     mParams = params;
00574 
00575     PredictionStrategy::make (params);
00576 }
00577 
00578 PatternSet* AbsoluteNeuralPrediction::makeSet (const Matrix& data, int startmonth) const {
00579     //TRACE2 ("Making pattern set from = %d rows, %d cols", data.rows, data.cols);
00580     
00581     int startmonthi = (startmonth % 100)-1;
00582     int inputs = data.cols;
00583     
00584     // Input patterns have inputs for each month (12) + inputmonths*attributes.
00585     PatternSet* result = new PatternSet (data.rows-inputMonths(),
00586                                          12+inputMonths()*(mUseAllInputs? inputs:1),
00587                                          mUseAllOutputs? inputs:1);
00588 
00589     // Copy the monthly attributes to the pattern set
00590     for (int p=0; p<result->patterns; p++) {
00591         // Zero the input month indicator flags
00592         for (int m=0; m<12; m++)
00593             result->set_input (p, m, 0);
00594 
00595         // Set input month indicators as 1
00596         for (int im=0; im<mInputMonths; im++)
00597             result->set_input (p, (startmonthi+p+im+12)%12, 1);
00598                 
00599         // Copy input month values to inputs
00600         if (mUseAllInputs)
00601             for (int j=0; j<inputs; j++)
00602                 for (int prm=0; prm<mInputMonths; prm++)
00603                     result->set_input (p, 12+inputs*prm+j, data.get(p+prm, j));
00604         else {
00605             // Only one input variable
00606             for (int prm=0; prm<mInputMonths; prm++)
00607                 result->set_input (p, 12+prm, data.get(p+prm, mVariable));
00608         }
00609         
00610         // Copy current month values to outputs
00611         if (mUseAllOutputs)
00612             for (int j=0; j<inputs; j++)
00613                 result->set_output (p, j, data.get(p+mInputMonths, j));
00614         else
00615             // Only one output variable
00616             result->set_output (p, 0, data.get(p+mInputMonths, mVariable));
00617     }
00618     return result;
00619 }
00620 
00621 /*virtual*/ void AbsoluteNeuralPrediction::train (const Matrix& traindata, int startmonth) {
00622     //TRACE2 ("Training data = %d rows, %d cols", traindata.rows, traindata.cols);
00623     
00625     // Create network
00626     
00627     if (!mpNetwork) {
00628         mpNetwork = new ANNetwork;
00629         mpNetwork->make (format("%d%s%d", inputVariables(traindata.cols),
00630                                 (CONSTR) mHiddenTopology,
00631                                 outputVariables(traindata.cols)));
00632         mpNetwork->connectFullFfw (false);
00633     }
00634 
00635     // Initialize the network
00636     mpNetwork->init (0.5);
00637 
00639     // Prepare data
00640 
00641     // Equalize data
00642     Matrix equalized = traindata;
00643     if (!mpNetwork->getEqualizer()) {
00644         MatrixEqualizer* mequalizer = new MatrixEqualizer (new MinmaxEq(0.0, 1.0)); // new HistogramEq (100000, 0.0, 1.0)
00645         mequalizer->analyze (traindata, mGlobalEqualization);
00646         mpNetwork->setEqualizer (mequalizer);
00647     }
00648     dynamic_cast<MatrixEqualizer*>(mpNetwork->getEqualizer())->equalize (equalized);
00649 
00650     // Create pattern set
00651     PatternSet* trainset = makeSet (equalized, startmonth);
00652     //trainset->print ();
00653     //fprintf (stderr, "Training data has %d patterns with %d inputs and %d outputs\n",
00654     //trainset->patterns, trainset->inputs, trainset->outputs);
00655 
00656     //PatternSet* trainset2 = makeSet (traindata, startmonth);
00657     //delete trainset2;
00658     
00660     // Train
00661 
00662     // Create trainer and set parameters
00663     RPropTrainer trainer;
00664     trainer.init (mParams);
00665     trainer.setTerminator (mParams["terminator"]);
00666 
00667     // Set observer to display current training cycle
00668     if (rpObserver)
00669         trainer.setObserver (rpObserver);
00670 
00671     // Train
00672     trainer.train (*mpNetwork, *trainset, mParams["maxCycles"].toInt(),
00673                    NULL, mParams["validationInterval"].toInt());
00674 
00675     //fprintf (stderr, "Trained for %d cycles, MSE=%f\n", trainer.totalCycles(), trainmse);
00676     delete trainset;
00677 }
00678 
00679 /*virtual*/ Ref<Matrix> AbsoluteNeuralPrediction::predict (const Matrix& testdata, int startmonth) const {
00680     //TRACE2 ("Test data = %d rows, %d cols", testdata.rows, testdata.cols);
00681     
00682     // Equalize
00683     Matrix equalized = testdata;
00684     dynamic_cast<MatrixEqualizer*>(mpNetwork->getEqualizer())->equalize (equalized);
00685     
00686     // Create pattern set and use it
00687     PatternSet* testset = makeSet (equalized, startmonth);
00688 
00690     // Test the network
00691 
00692     // Create a matrix where to place the results
00693     Ref<Matrix> result = new Matrix (testset->patterns, mUseAllOutputs? testset->outputs:1);
00694 
00695     // Test one month at a time
00696     for (int p=0; p<testset->patterns; p++) {
00697         Vector v = mpNetwork->testPattern (*testset, p);
00698         for (int i=0; i<v.size(); i++)
00699             result->get(p,i) = v[i];
00700     }
00701     delete testset;
00702 
00703     // Unequalize the results to get money values again
00704     dynamic_cast<MatrixEqualizer*>(mpNetwork->getEqualizer())->unequalize (result);
00705 
00706     return result;
00707 }
00708 
00709 void AbsoluteNeuralPrediction::load (TextIStream& in) {
00710     delete mpNetwork;
00711 
00712     mpNetwork = new ANNetwork();
00713     ANNFileFormatLib::load (in, *mpNetwork, "SNNS");
00714 }
00715 
00716 void AbsoluteNeuralPrediction::save (TextOStream& out) const {
00717     ANNFileFormatLib::save (out, *mpNetwork, "SNNS");
00718 }
00719 
00720 
00721 
00723 //      ---- o             |       |   |                       | ----        //
00724 //     (         _         |  ___  |\  |  ___             ___  | |   )       //
00725 //      ---  | |/ \   ___  | /   ) | \ | /   ) |   | |/\  ___| | |---        //
00726 //         ) | |   | (   \ | |---  |  \| |---  |   | |   (   | | |           //
00727 //     ___/  | |   |  ---/ |  \__  |   |  \__   \__! |    \__| | |     O     //
00728 //                    __/                                                    //
00730 
00731 void SingleNeuralPrediction::make (const StringMap& params) {
00732     AbsoluteNeuralPrediction::make (params);
00733 }
00734 
00735 /*virtual*/ void SingleNeuralPrediction::train (const Matrix& traindata, int startmonth) {
00736     for (int v=0; v<mNetworks.size(); v++)
00737         mNetworks.cut (v);
00738     mNetworks.empty ();
00739     mNetworks.make (traindata.cols);
00740 
00741     // Train each variable separately
00742     sout.autoFlush ();
00743     for (int v=0; v<traindata.cols; v++) {
00744         sout.printf ("Training variable %d...\n", v);
00745         mVariable = v;
00746         AbsoluteNeuralPrediction::train (traindata, startmonth);
00747         mNetworks.put (mpNetwork, v);
00748         mpNetwork=NULL;
00749     }
00750     sout.printf("\n");
00751 }
00752 
00753 /*virtual*/ Ref<Matrix> SingleNeuralPrediction::predict (const Matrix& testdata, int startmonth) const {
00754     SingleNeuralPrediction* ncthis = const_cast<SingleNeuralPrediction*>(this);
00755 
00756     Ref<Matrix> result = new Matrix ();
00757 
00758     // For each variable
00759     for (int v=0; v<testdata.cols; v++) {
00760         ncthis->mVariable = v;
00761 
00762         // Use a small kludge to set the current network
00763         ncthis->mpNetwork = const_cast<ANNetwork*>(&mNetworks[v]);
00764 
00765         // Let the baseclass do the prediction for one variable
00766         Ref<Matrix> oneVariable = AbsoluteNeuralPrediction::predict (testdata, startmonth);
00767 
00768         // Create the result matrix when we get the number of rows.
00769         if (result->rows==0)
00770             result->make (oneVariable->rows, testdata.cols);
00771         
00772         // Copy the one variable to the total result
00773         for (int r=0; r<result->rows; r++)
00774             result->get (r, v) = oneVariable->get (r, 0);
00775     }
00776     ncthis->mpNetwork = NULL;
00777 
00778     return result;
00779 }
00780 
00781 void SingleNeuralPrediction::load (TextIStream& in) {
00782     mNetworks.empty ();
00783 
00784     // Read the number of networks
00785     int nets;
00786     in >> nets;
00787     if (nets==0)
00788         throw invalid_format ("Invalid network file format (SingleNeuralPrediction)");
00789 
00790     mNetworks.make (nets);
00791     for (int i=0; i<nets; i++) {
00792         mNetworks.put (new ANNetwork(), i);
00793         ANNFileFormatLib::load (in, mNetworks[i], "SNNS");
00794     }
00795 }
00796 
00797 void SingleNeuralPrediction::save (TextOStream& out) const {
00798     out << mNetworks.size() << "\n";
00799     for (int i=0; i<mNetworks.size(); i++)
00800         ANNFileFormatLib::save (out, mNetworks[i], "SNNS");
00801 }
00802 
00803 
00804 
00806 //       ___         |           |   |                       | ----          //
00807 //       |  \   ___  |  |   ___  |\  |  ___             ___  | |   )         //
00808 //       |   | /   ) | -+-  ___| | \ | /   ) |   | |/\  ___| | |---          //
00809 //       |   | |---  |  |  (   | |  \| |---  |   | |   (   | | |             //
00810 //       |__/   \__  |   \  \__| |   |  \__   \__! |    \__| | |     O       //
00812 
00813 DeltaNeuralPrediction::DeltaNeuralPrediction (const StringMap& params) : PredictionStrategy ("DeltaNeural")
00814 {
00815 }
00816 
00817 /*virtual*/ void DeltaNeuralPrediction::train (const Matrix& traindata, int startmonth)
00818 {
00819 }
00820 
00821 /*virtual*/ Ref<Matrix> DeltaNeuralPrediction::predict (const Matrix& testdata, int startmonth) const
00822 {
00823     return Ref<Matrix> (NULL);
00824 }
00825 
00826 
00827 
00829 //   _             | o     o              ----                                     |     o       //
00830 //  / \            |    |      _         (      |       ___   |   ___              |       |     //
00831 // /   \ |   |  ---| | -+- | |/ \   ___   ---  -+- |/\  ___| -+- /   )  ___  \   | |     | |---  //
00832 // |---| |   | (   | |  |  | |   | (   \     )  |  |   (   |  |  |---  (   \  \  | |     | |   ) //
00833 // |   |  \__!  ---| |   \ | |   |  ---/ ___/    \ |    \__|   \  \__   ---/   \_/ |____ | |__/  //
00834 //                                  __/                                 __/   \_/                //
00836 
00837 PredictionStrategyLib PredictionStrategyLib::sInstance;
00838 
00839 PredictionStrategyLib::PredictionStrategyLib ()
00840 {
00841     registerCls ("AverageDeltaPrediction");
00842     registerCls ("ZeroDeltaPrediction");
00843     registerCls ("AbsoluteNeuralPrediction");
00844     registerCls ("SingleNeuralPrediction");
00845     registerCls ("PreviousYear");
00846     registerCls ("PreviousYearsAvg");
00847     registerCls ("CombinedPrediction");
00848     //registerCls ("DeltaNeuralPrediction");
00849 }
00850 
00851 PredictionStrategy* PredictionStrategyLib::create (int i) const
00852 {
00853     return dynamic_cast<PredictionStrategy*> (dyncreate (mClassNames[i]));
00854 }
00855 
00856 
00857 
00859 // -----           o       ----                                                  //
00860 //   |        ___      _   |   )  ___       ___         ___   |   ___       ____ //
00861 //   |   |/\  ___| | |/ \  |---   ___| |/\  ___| |/|/| /   ) -+- /   ) |/\ (     //
00862 //   |   |   (   | | |   | |     (   | |   (   | | | | |---   |  |---  |    \__  //
00863 //   |   |    \__| | |   | |      \__| |    \__| | | |  \__    \  \__  |   ____) //
00865 
00866 void TrainParameters::defaults ()
00867 {
00868     trainCycles    = 10000;
00869     delta0         = 0.1;
00870     deltaMax       = 50;
00871     weightDecay    = 0.99999;
00872     useWeightDecay = true;
00873     hidden1        = 10;
00874     hidden2        = 5;
00875     hidden3        = 0;
00876     runs           = 1;
00877     allInputs      = true;
00878     allOutputs     = true;
00879     monthInputs    = true;
00880     equalizeGlobal = true;
00881     inputMonths    = 1;
00882 }
00883 
00884 String TrainParameters::hiddenString () const
00885 {
00886     String result = "-";
00887     if (hidden1 > 0)
00888         result += String(hidden1) + "-";
00889     if (hidden2 > 0)
00890         result += String(hidden2) + "-";
00891     if (hidden3 > 0)
00892         result += String(hidden3) + "-";
00893     return result;
00894 }
00895 
00896 Ref<StringMap> TrainParameters::getParams () const
00897 {
00898     Ref<StringMap> resultRef = new StringMap ();
00899     StringMap& result = resultRef.object();
00900 
00901     result.set ("trainCycles", String(trainCycles));
00902     result.set ("delta0", String(delta0));
00903     result.set ("deltaMax", String(deltaMax));
00904     result.set ("weightDecay", String(weightDecay));
00905     result.set ("useWeightDecay", String(useWeightDecay));
00906     result.set ("hidden1", String(hidden1));
00907     result.set ("hidden2", String(hidden2));
00908     result.set ("hidden3", String(hidden3));
00909     result.set ("runs", String(runs));
00910     result.set ("allInputs", String(allInputs));
00911     result.set ("allOutputs", String(allOutputs));
00912     result.set ("monthInputs", String(monthInputs));
00913     result.set ("equalizeGlobal", String(equalizeGlobal));
00914     result.set ("inputMonths", String(inputMonths));
00915 
00916     return resultRef;
00917 }
00918 
00919 void TrainParameters::setParams (const StringMap& map)
00920 {
00921     trainCycles    = map["trainCycles"].toInt();
00922     delta0         = map["delta0"].toFloat();
00923     deltaMax       = map["deltaMax"].toFloat();
00924     weightDecay    = map["weightDecay"].toFloat();
00925     useWeightDecay = map["useWeightDecay"].toInt();
00926     hidden1        = map["hidden1"].toInt();
00927     hidden2        = map["hidden2"].toInt();
00928     hidden3        = map["hidden3"].toInt();
00929     runs           = map["runs"].toInt();
00930     allInputs      = map["allInputs"].toInt();
00931     allOutputs     = map["allOutputs"].toInt();
00932     monthInputs    = map["monthInputs"].toInt();
00933     equalizeGlobal = map["equalizeGlobal"].toInt();
00934     inputMonths    = map["inputMonths"].toInt();
00935 }
00936 
00937 void TrainParameters::write (TextOStream& out) const
00938 {
00939     writeStringMap (getParams(), out);
00940     out << "# end-of-map\n";
00941 }
00942 
00943 void TrainParameters::read (TextIStream& in)
00944 {
00945     setParams (readStringMap (in));
00946 }
00947 
00948 

Generated on Thu Feb 10 20:06:45 2005 for Inanna by doxygen1.2.18