BlendStopping Class Reference

#include <BlendStopping.h>

Inheritance diagram for BlendStopping:

Framework AutomaticParameterTuner AUC Framework Framework

List of all members.

Public Member Functions

 BlendStopping ()
 BlendStopping (Algorithm *data)
 BlendStopping (Algorithm *data, string algorithmFullPrediction)
 ~BlendStopping ()
double calcRMSEonProbe ()
double calcRMSEonBlend ()
void saveBestPrediction ()
double calcBlending (char *fname=0)
double getClassificationError ()
void setRegularization (REAL reg)
void clear ()
void saveTmpBestWeights ()
void saveBlendingWeights (string path, bool saveBest=false)
void loadBlendingWeights (string path, int nPredictors)
void predictEnsembleOutput (REAL **predictions, REAL *output)
void printWeights (bool printBest=false)

Public Attributes

REAL ** m_newPrediction

Protected Attributes

int m_nPredictors
int m_nClass
int m_nDomain
int m_nTrain
double m_blendingRegularization
REAL m_classificationError
REAL * m_singlePrediction
REAL * m_prediction
REAL ** m_A
REAL ** m_b
REAL ** m_x
REAL ** m_xBest
vector< string > m_usedFiles
Algorithmm_data
NumericalTools m_numTools
string m_algorithmFullPrediction
bool m_globalWeights
double * m_paramsAUC
bool m_optimizeRMSE


Detailed Description

BlendStopping

This class calculates the ensemble error (in the easiest case a linear combination) Is used for determine the error from a set of Algorithms The Algorithms are trained sequentially The class can read a directory of full-predictions of the trainingset, typically predicted with k-fold cross-validation (can also be predictions from out-of-bag estimates)

The class solves a linear equation system in a least-squares sense with simple pseudoinverse to get the linear combination of predictions

Extention: k-fold cross validation of the blending In order to determine the optimal ridge-regression regularizer lambda

Extentions: nonNeg solver, parameter-search based combiner (nelder-mead for AUC optimization)

Definition at line 41 of file BlendStopping.h.


Constructor & Destructor Documentation

BlendStopping::BlendStopping (  ) 

Constructor

Definition at line 8 of file BlendStopping.cpp.

00009 {
00010     cout<<"Constructor BlendStopping"<<endl;
00011 
00012     // init member vars
00013     m_newPrediction = 0;
00014     m_nPredictors = 0;
00015     m_nClass = 0;
00016     m_nDomain = 0;
00017     m_nTrain = 0;
00018     m_blendingRegularization = 0;
00019     m_classificationError = 0;
00020     m_singlePrediction = 0;
00021     m_prediction = 0;
00022     m_A = 0;
00023     m_b = 0;
00024     m_x = 0;
00025     m_xBest = 0;
00026     m_data = 0;
00027     m_paramsAUC = 0;
00028     m_optimizeRMSE = 0;
00029     m_globalWeights = 0;
00030 }

BlendStopping::BlendStopping ( Algorithm data  ) 

Constructor

Parameters:
data The data object with the trainingset

Definition at line 37 of file BlendStopping.cpp.

00038 {
00039     cout<<"Constructor BlendStopping"<<endl;
00040     // init member vars
00041     m_newPrediction = 0;
00042     m_nPredictors = 0;
00043     m_nClass = 0;
00044     m_nDomain = 0;
00045     m_nTrain = 0;
00046     m_blendingRegularization = 0;
00047     m_classificationError = 0;
00048     m_singlePrediction = 0;
00049     m_prediction = 0;
00050     m_A = 0;
00051     m_b = 0;
00052     m_x = 0;
00053     m_xBest = 0;
00054     m_data = 0;
00055     m_paramsAUC = 0;
00056     m_optimizeRMSE = 0;
00057 
00058     m_data = data;
00059     m_nClass = m_data->m_nClass;
00060     m_nDomain = m_data->m_nDomain;
00061     m_nTrain = m_data->m_nTrain;
00062     m_globalWeights = m_data->m_enableGlobalBlendingWeights;
00063 }

BlendStopping::BlendStopping ( Algorithm data,
string  algorithmFullPrediction 
)

Constructor

Parameters:
data The data object with the trainingset
algorithmFullPrediction The filename of the actual full-prediction of the current Algorithm

Definition at line 71 of file BlendStopping.cpp.

00072 {
00073     cout<<"Constructor BlendStopping"<<endl;
00074     // init member vars
00075     m_newPrediction = 0;
00076     m_nPredictors = 0;
00077     m_nClass = 0;
00078     m_nDomain = 0;
00079     m_nTrain = 0;
00080     m_blendingRegularization = 0;
00081     m_classificationError = 0;
00082     m_singlePrediction = 0;
00083     m_prediction = 0;
00084     m_A = 0;
00085     m_b = 0;
00086     m_x = 0;
00087     m_xBest = 0;
00088     m_data = 0;
00089     m_paramsAUC = 0;
00090     m_optimizeRMSE = 0;
00091 
00092     m_data = data;
00093     m_nClass = m_data->m_nClass;
00094     m_nDomain = m_data->m_nDomain;
00095     m_nTrain = m_data->m_validationType=="ValidationSet"? m_data->m_validSize : m_data->m_nTrain;
00096     m_globalWeights = m_data->m_enableGlobalBlendingWeights;
00097 
00098     m_algorithmFullPrediction = algorithmFullPrediction;
00099     string directory = m_data->m_datasetPath + "/" + m_data->m_fullPredPath + "/";
00100 
00101     vector<string> files = m_data->m_algorithmNameList;//Data::getDirectoryFileList(directory);
00102 
00103     // add a prediction to blend, if the file exists
00104     string additionalFullPrediction = m_data->m_datasetPath + "/" + m_data->m_fullPredPath + "/" + m_algorithmFullPrediction;
00105     fstream f ( additionalFullPrediction.c_str(), ios::in );
00106     if ( f.is_open() )
00107     {
00108         cout<<"ADD:"<<additionalFullPrediction<<" ";
00109         files.push_back ( additionalFullPrediction );
00110         m_algorithmFullPrediction = "";
00111     }
00112     f.close();
00113 
00114     m_nPredictors = 0;
00115     for ( int i=0;i<files.size();i++ )
00116     {
00117         if ( files[i].at ( files[i].size()-1 ) != '.' && files[i].find ( ".dat" ) == files[i].length()-4 )
00118         {
00119             //cout<<endl<<"File: "<<files[i]<<endl<<endl;
00120             m_usedFiles.push_back ( files[i] );
00121             m_nPredictors++;
00122         }
00123     }
00124 
00125     // add the constant predictor
00126     m_nPredictors++;
00127 
00128     // add the new prediction
00129     if ( m_algorithmFullPrediction=="tune" )
00130     {
00131         m_nPredictors++;
00132         cout<<"Number of predictors for blendStopping: "<<m_nPredictors<<" (+1 const, +1 new)"<<endl;
00133     }
00134     else
00135         cout<<"Number of predictors for blendStopping: "<<m_nPredictors<<" (+1 const)"<<endl;
00136 
00137     // allocate per class a linear equation system
00138     // find for every target class the best linear combination
00139     m_singlePrediction = new REAL[m_nTrain];
00140     m_prediction = new REAL[m_nTrain*m_nClass*m_nDomain];
00141     m_A = new REAL*[m_nClass*m_nDomain];
00142     m_b = new REAL*[m_nClass*m_nDomain];
00143     m_x = new REAL*[m_nClass*m_nDomain];
00144     m_xBest = new REAL*[m_nClass*m_nDomain];
00145     for ( int i=0;i<m_nClass*m_nDomain;i++ )
00146     {
00147         m_A[i] = new REAL[m_nPredictors * m_nTrain];
00148         m_b[i] = new REAL[m_nTrain];
00149         m_x[i] = new REAL[m_nPredictors];
00150         m_xBest[i] = new REAL[m_nPredictors];
00151         for ( int j=0;j<m_nPredictors;j++ )
00152         {
00153             m_x[i][j] = 0.0;
00154             m_xBest[i][j] = 0.0;
00155         }
00156     }
00157 
00158     // set target values
00159     for ( int i=0;i<m_nTrain;i++ )
00160         for ( int j=0;j<m_nClass*m_nDomain;j++ )
00161         {
00162             REAL t = m_data->m_trainTargetOrig[i*m_nClass*m_nDomain + j];
00163             if(m_data->m_validationType == "ValidationSet")
00164                 t = m_data->m_validTarget[i*m_nClass*m_nDomain + j];
00165             
00166             m_b[j][i] = t;
00167         }
00168 
00169     // set constant predictor as first predictor
00170     for ( int i=0;i<m_nClass*m_nDomain;i++ )
00171         for ( int j=0;j<m_nTrain;j++ )
00172             m_A[i][j] = 1.0;
00173 
00174     // load the fullPredictors
00175     cout<<endl;
00176     for ( int i=0;i<m_usedFiles.size();i++ )
00177     {
00178         fstream f ( m_usedFiles[i].c_str(), ios::in );
00179         if ( f.is_open() == false )
00180         {
00181             cout<<"Cannot open:"<<m_usedFiles[i]<<endl;
00182             assert ( false );
00183         }
00184         REAL* cache0 = new REAL[m_nTrain*m_nClass*m_nDomain];
00185         f.read ( ( char* ) cache0, sizeof ( REAL ) *m_nTrain*m_nClass*m_nDomain );
00186         f.close();
00187         double rmse0 = 0.0, err;
00188         for ( int j=0;j<m_nClass*m_nDomain;j++ )
00189         {
00190             for ( int k=0;k<m_nTrain;k++ )
00191             {
00192                 m_A[j][k + ( i+1 ) *m_nTrain] = cache0[j + k*m_nClass*m_nDomain];
00193                 err = m_A[j][k + ( i+1 ) *m_nTrain] - m_b[j][k];
00194                 rmse0 += err * err;
00195             }
00196         }
00197         cout<<"File:"<<m_usedFiles[i]<<"  RMSE:"<<sqrt ( rmse0/ ( double ) ( m_nClass*m_nTrain*m_nDomain ) ) <<endl;
00198         if ( cache0 )
00199             delete[] cache0;
00200         cache0 = 0;
00201     }
00202     cout<<endl;
00203 
00204     // init random prediction
00205     if ( m_algorithmFullPrediction=="tune" ) // HACK
00206     {
00207         for ( int i=0;i<m_nClass*m_nDomain;i++ )
00208             for ( int j=0;j<m_nTrain;j++ )
00209                 m_A[i][ ( m_nPredictors - 1 ) *m_nTrain + j] = 0.0;//NumericalTools::getNormRandomNumber(0.0,0.01);
00210 
00211         // the pointers to the prediction for outside use
00212         m_newPrediction = new REAL*[m_nClass*m_nDomain];
00213         for ( int i=0;i<m_nClass*m_nDomain;i++ )
00214             m_newPrediction[i] = m_A[i] + ( m_nPredictors - 1 ) *m_nTrain;
00215     }
00216 
00217     if ( m_data->m_errorFunction=="AUC" )
00218         m_paramsAUC = new double[m_nClass*m_nPredictors*m_nDomain];
00219 }

BlendStopping::~BlendStopping (  ) 

Destructor

Definition at line 224 of file BlendStopping.cpp.

00225 {
00226     cout<<"destructor BlendStopping"<<endl;
00227     if ( m_singlePrediction )
00228         delete[] m_singlePrediction;
00229     m_singlePrediction = 0;
00230     if ( m_prediction )
00231         delete[] m_prediction;
00232     m_prediction = 0;
00233     for ( int i=0;i<m_nClass*m_nDomain;i++ )
00234     {
00235         if ( m_A )
00236         {
00237             if ( m_A[i] )
00238                 delete[] m_A[i];
00239             m_A[i] = 0;
00240         }
00241         if ( m_b )
00242         {
00243             if ( m_b[i] )
00244                 delete[] m_b[i];
00245             m_b[i] = 0;
00246         }
00247         if ( m_x )
00248         {
00249             if ( m_x[i] )
00250                 delete[] m_x[i];
00251             m_x[i] = 0;
00252         }
00253         if ( m_xBest )
00254         {
00255             if ( m_xBest[i] )
00256                 delete[] m_xBest[i];
00257             m_xBest[i] = 0;
00258         }
00259     }
00260     if ( m_A )
00261         delete[] m_A;
00262     m_A = 0;
00263     if ( m_b )
00264         delete[] m_b;
00265     m_b = 0;
00266     if ( m_x )
00267         delete[] m_x;
00268     m_x = 0;
00269     if ( m_xBest )
00270         delete[] m_xBest;
00271     m_xBest = 0;
00272     if ( m_newPrediction )
00273         delete[] m_newPrediction;
00274     m_newPrediction = 0;
00275     if ( m_paramsAUC )
00276         delete[] m_paramsAUC;
00277     m_paramsAUC = 0;
00278 }


Member Function Documentation

double BlendStopping::calcBlending ( char *  fname = 0  ) 

Calculate the ensemble error by a linear combination of algorithms

Parameters:
fname The name of the binary outputfile (default param =0)
Returns:
The blend rmse

Definition at line 298 of file BlendStopping.cpp.

00299 {
00300     cout<<" [CalcBlend] ";
00301     double rmse = 0.0, mae = 0.0, err;
00302     double* rmseClass = new double[m_nClass*m_nDomain];
00303 
00304     // search for optimal lambda in ridge regression
00305     if ( m_data->m_blendingEnableCrossValidation == true && m_data->m_blendingAlgorithm != "Average" && m_data->m_blendingAlgorithm != "TakeLast" )
00306     {
00307         if ( m_data->m_errorFunction=="AUC" && Framework::getDatasetType() && m_data->m_blendingAlgorithm=="NelderMead" )
00308         {
00309             // init weights with constants
00310             for ( int i=0;i<m_nClass*m_nDomain;i++ )
00311                 for ( int j=0;j<m_nPredictors;j++ )
00312                     m_x[i][j] = m_xBest[i][j] = ( j+1==m_nPredictors ) ? 0.1 : 1.0;
00313 
00314             for ( int i=0;i<m_nClass*m_nDomain;i++ )
00315             {
00316                 for ( int j=0;j<m_nPredictors;j++ )
00317                 {
00318                     char buf[1024];
00319                     sprintf ( buf,"w-t%d-p%d",i,j );
00320                     m_paramsAUC[i*m_nPredictors+j] = m_x[i][j];
00321                     addDoubleParameter ( & ( m_paramsAUC[i*m_nPredictors+j] ), buf, -100.0, 100.0 );
00322                 }
00323             }
00324 
00325             // start the nelder-mead searcher
00326             setDebug ( 0 );
00327             //if(fname)
00328             //    setDebug(1);
00329             NelderMeadSearch ( 500 );
00330             //expSearcher(0,100,3,2,0.99,true,false);
00331 
00332             int cnt = 0;
00333             for ( int i=0;i<m_nClass*m_nDomain;i++ )
00334             {
00335                 for ( int j=0;j<m_nPredictors;j++ )
00336                 {
00337                     char buf[1024];
00338                     sprintf ( buf,"w-t%d-p%d",i,j );
00339 
00340                     m_x[i][j] = m_paramsAUC[i*m_nPredictors+j];
00341                     m_xBest[i][j] = m_paramsAUC[i*m_nPredictors+j];
00342                     removeDoubleParameter ( buf );
00343                 }
00344             }
00345         }
00346         else
00347         {
00348             setDebug ( 0 );
00349             addDoubleParameter ( &m_blendingRegularization, "lambda", 1e-10, 1e3 );
00350 
00351             // start the structured searcher
00352             int minTuninigEpochs = 0, maxTuninigEpochs = 30;
00353             m_optimizeRMSE = 1;
00354             expSearcher ( minTuninigEpochs, maxTuninigEpochs, 3, 1, 0.8, true, false );
00355             m_optimizeRMSE = 0;
00356 
00357             removeDoubleParameter ( "lambda" );
00358 
00359             for ( int i=0;i<m_nClass*m_nDomain;i++ )
00360                 for ( int j=0;j<m_nPredictors;j++ )
00361                     m_xBest[i][j] = m_x[i][j];
00362 
00363             if ( fname == 0 )
00364             {
00365                 //cout<<"lambda:"<<m_blendingRegularization<<" ";
00366                 //return m_expSearchErrorBest;
00367             }
00368             else
00369                 cout<<endl<<"Blending-CV-error:"<<m_expSearchErrorBest<<endl;
00370         }
00371     }
00372 
00373     cout<<"lambda:"<<m_blendingRegularization<<" ";
00374 
00375     for ( int i=0;i<m_nClass*m_nDomain;i++ )
00376     {
00377         rmseClass[i] = 0.0;
00378 
00379         if ( m_data->m_blendingAlgorithm=="Average" )
00380         {
00381             // weight all algorithms equal (constant-prediction: weight=0)
00382             m_x[i][0] = 0.0;
00383             REAL normalizer = 1.0 / ( double ) ( m_nPredictors-1 );
00384             for ( int j=1;j<m_nPredictors;j++ )
00385                 m_x[i][j] = normalizer;
00386         }
00387         else if ( m_data->m_blendingAlgorithm=="TakeLast" )
00388         {
00389             // take only the last algorithm in the ensemble
00390             for ( int j=0;j<m_nPredictors;j++ )
00391                 m_x[i][j] = 0.0;
00392             m_x[i][m_nPredictors-1] = 1.0;
00393         }
00394         else if ( m_data->m_blendingAlgorithm=="LinearRegression" )
00395         {
00396             if ( m_globalWeights ) // equal weights for all classes and domains
00397             {
00398                 REAL* A = new REAL[m_nTrain*m_nPredictors*m_nClass*m_nDomain], *b = new REAL[m_nTrain*m_nClass*m_nDomain];
00399                 for ( int j=0;j<m_nPredictors;j++ )
00400                     for ( int k=0;k<m_nClass*m_nDomain;k++ )
00401                         for ( int l=0;l<m_nTrain;l++ )
00402                             A[l + k*m_nTrain + j*m_nTrain*m_nClass*m_nDomain] = m_A[k][l+j*m_nTrain];
00403                 for ( int k=0;k<m_nClass*m_nDomain;k++ )
00404                     for ( int l=0;l<m_nTrain;l++ )
00405                         b[l + k*m_nTrain] = m_b[k][l];
00406                 m_numTools.RidgeRegressionMultisolutionSinglecallGELSS ( A, b, m_x[i], m_nTrain*m_nClass*m_nDomain, m_nPredictors, 1, m_blendingRegularization, false );
00407                 delete[] A;
00408                 delete[] b;
00409             }
00410             else
00411                 m_numTools.RidgeRegressionMultisolutionSinglecallGELSS ( m_A[i], m_b[i], m_x[i], m_nTrain, m_nPredictors, 1, m_blendingRegularization, false );
00412         }
00413         else if ( m_data->m_blendingAlgorithm=="LinearRegressionNonNeg" )
00414         {
00415             if ( m_globalWeights ) // equal weights for all classes and domains
00416             {
00417                 REAL* A = new REAL[m_nTrain*m_nPredictors*m_nClass*m_nDomain], *b = new REAL[m_nTrain*m_nClass*m_nDomain];
00418                 for ( int j=0;j<m_nPredictors;j++ )
00419                     for ( int k=0;k<m_nClass*m_nDomain;k++ )
00420                         for ( int l=0;l<m_nTrain;l++ )
00421                             A[l + k*m_nTrain + j*m_nTrain*m_nClass*m_nDomain] = m_A[k][l+j*m_nTrain];
00422                 for ( int k=0;k<m_nClass*m_nDomain;k++ )
00423                     for ( int l=0;l<m_nTrain;l++ )
00424                         b[l + k*m_nTrain] = m_b[k][l];
00425                 m_numTools.RidgeRegressionNonNegSinglecall ( A, b, m_x[i], m_nTrain, m_nPredictors, m_blendingRegularization, 1e-10, 1000, false );
00426                 delete[] A;
00427                 delete[] b;
00428             }
00429             else
00430                 m_numTools.RidgeRegressionNonNegSinglecall ( m_A[i], m_b[i], m_x[i], m_nTrain, m_nPredictors, m_blendingRegularization, 1e-10, 1000, false );
00431 
00432             // in case of zero weights
00433             REAL sumX = 0.0;
00434             for ( int j=1;j<m_nPredictors;j++ )
00435                 sumX += m_x[i][j];
00436             if ( sumX == 0.0 )
00437             {
00438                 if ( i > 0 )
00439                     for ( int j=0;j<m_nPredictors;j++ )
00440                         m_x[i][j] = m_x[i-1][j];
00441                 else
00442                 {
00443                     for ( int j=0;j<m_nPredictors;j++ )
00444                         m_x[i][j] = 0.0;
00445                     m_x[i][m_nPredictors-1] = 1.0;
00446                 }
00447             }
00448         }
00449         else if ( m_data->m_blendingAlgorithm=="NelderMead" )
00450         {
00451             //for(int j=0;j<m_nPredictors;j++)
00452             //    m_x[i][j] = m_xBest[i][j];
00453             //m_x[i][m_nPredictors-1] = 1.0;
00454         }
00455 
00456         // calc RMSE with BLAS
00457         CBLAS_GEMM ( CblasColMajor, CblasNoTrans, CblasNoTrans, m_nTrain, 1, m_nPredictors , 1.0, m_A[i], m_nTrain, m_x[i], m_nPredictors, 0.0, m_singlePrediction, m_nTrain );  // Ab = A'b
00458 
00459         if ( m_data->m_enablePostBlendClipping )
00460         {
00461             IPPS_THRESHOLD ( m_singlePrediction, m_singlePrediction, m_nTrain, m_data->m_negativeTarget, ippCmpLess );  // clip negative
00462             IPPS_THRESHOLD ( m_singlePrediction, m_singlePrediction, m_nTrain, m_data->m_positiveTarget, ippCmpGreater );  // clip positive
00463         }
00464 
00465         memcpy ( ( char* ) ( m_prediction+m_nTrain*i ), m_singlePrediction, sizeof ( REAL ) *m_nTrain );
00466         for ( int j=0;j<m_nTrain;j++ )
00467         {
00468             rmse += ( m_singlePrediction[j] - m_b[i][j] ) * ( m_singlePrediction[j] - m_b[i][j] );
00469             mae += fabs ( m_singlePrediction[j] - m_b[i][j] );
00470             rmseClass[i] += ( m_singlePrediction[j] - m_b[i][j] ) * ( m_singlePrediction[j] - m_b[i][j] );
00471         }
00472     }
00473 
00474     //for ( int i=0;i<m_nClass*m_nDomain;i++ )
00475     //    for ( int j=0;j<m_nPredictors;j++ )
00476     //        m_xBest[i][j] = m_x[i][j];
00477 
00478     if ( fname )
00479         printWeights ( false );
00480 
00481     if ( fname )
00482     {
00483         cout<<"[Write train prediction:"<<fname<<"]"<<" nSamples:"<<m_nTrain<<endl;
00484         fstream f ( fname, ios::out );
00485         if ( f.is_open() == false )
00486             assert ( false );
00487         REAL* tmpOut = new REAL[m_nTrain*m_nClass*m_nDomain];
00488         for ( int i=0;i<m_nTrain;i++ )
00489         {
00490             int realIndex = m_data->m_mixDatasetIndices[i];
00491             if(m_data->m_validationType=="ValidationSet")
00492                 realIndex = i;
00493             for ( int j=0;j<m_nClass*m_nDomain;j++ )
00494                 tmpOut[j*m_nTrain + realIndex] = m_prediction[j*m_nTrain + i];
00495         }
00496         for ( int i=0;i<m_nTrain;i++ )
00497             for ( int j=0;j<m_nClass*m_nDomain;j++ )
00498             {
00499                 float predictionSP = tmpOut[j*m_nTrain + i];
00500                 f.write ( ( char* ) &predictionSP,sizeof ( float ) );
00501             }
00502         f.close();
00503         if ( tmpOut )
00504             delete[] tmpOut;
00505         tmpOut = 0;
00506     }
00507 
00508     // only if the dataset is for classification
00509     if ( Framework::getDatasetType() )
00510     {
00511         int* wrongLabelCnt = new int[m_nDomain];
00512         for ( int d=0;d<m_nDomain;d++ )
00513             wrongLabelCnt[d] = 0;
00514 
00515         // in all domains
00516         for ( int d=0;d<m_nDomain;d++ )
00517         {
00518             // classification error
00519             for ( int i=0;i<m_nTrain;i++ )
00520             {
00521                 REAL max = -1e10;
00522                 int indBest = -1;
00523                 for ( int j=0;j<m_nClass;j++ )
00524                 {
00525                     if ( max < m_prediction[d*m_nClass*m_nTrain + j*m_nTrain + i] )
00526                     {
00527                         max = m_prediction[d*m_nClass*m_nTrain + j*m_nTrain + i];
00528                         indBest = j;
00529                     }
00530                 }
00531                 if (m_data->m_validationType == "ValidationSet")
00532                 {
00533                     if ( indBest != m_data->m_validLabel[d + i*m_nDomain] )
00534                         wrongLabelCnt[d]++;
00535                 }
00536                 else
00537                 {
00538                     if ( indBest != m_data->m_trainLabelOrig[d + i*m_nDomain] )
00539                         wrongLabelCnt[d]++;
00540                 }
00541             }
00542         }
00543 
00544         int nWrong = 0;
00545         for ( int d=0;d<m_nDomain;d++ )
00546         {
00547             nWrong += wrongLabelCnt[d];
00548             //if(m_nDomain > 1)
00549             //    cout<<"["<<(double)wrongLabelCnt[d]/(double)m_nTrain<<"] ";
00550         }
00551         m_classificationError = ( double ) nWrong/ ( ( double ) m_nTrain*m_nDomain );
00552         cout<<" [classErr:"<<100.0*m_classificationError<<"%] ";
00553 
00554         delete[] wrongLabelCnt;
00555     }
00556 
00557     if ( rmseClass )
00558         delete[] rmseClass;
00559     rmseClass = 0;
00560 
00561     rmse = sqrt ( rmse/ ( ( double ) m_nTrain * ( double ) m_nClass * ( double ) m_nDomain ) );
00562     mae = mae/ ( ( double ) m_nTrain * ( double ) m_nClass * ( double ) m_nDomain );
00563 
00564     if ( m_data->m_errorFunction=="AUC" && Framework::getDatasetType() )
00565     {
00566         cout<<"[rmse:"<<rmse<<"] ";
00567 
00568         // calc area under curve
00569         REAL auc = getAUC ( m_prediction, m_data->m_trainLabelOrig, m_data->m_nClass, m_data->m_nDomain, m_data->m_nTrain );
00570         return auc;
00571     }
00572     else if ( m_data->m_errorFunction=="MAE" )
00573         return mae;
00574 
00575     return rmse;
00576 }

double BlendStopping::calcRMSEonBlend (  )  [virtual]

tmp (needed virtual overrider in AutomaticParameterTuner)

Implements AutomaticParameterTuner.

Definition at line 864 of file BlendStopping.cpp.

00865 {
00866     assert ( false );
00867     return 0.0;
00868 }

double BlendStopping::calcRMSEonProbe (  )  [virtual]

Used for determine optimal lambda Here, n-fold cross validation is calculated

Returns:
The n-fold cross validation blend error

Implements AutomaticParameterTuner.

Definition at line 712 of file BlendStopping.cpp.

00713 {
00714     if ( m_optimizeRMSE )
00715     {
00716         int *randomIndex = new int[m_nTrain];
00717         REAL* tmpA = new REAL[m_nTrain * m_nPredictors];
00718         REAL* tmpB = new REAL[m_nTrain];
00719 
00720         // fill random 0..NCross-1  numbers in array
00721         for ( int i=0;i<m_nTrain;i++ )
00722         {
00723             if(m_data->m_validationType=="Bagging")
00724                 randomIndex[i] = rand() % m_data->m_nCross;  // this is random
00725             else
00726                 randomIndex[i] = m_data->m_crossIndex[i];  // this is taken from the predefined CV-split
00727         }
00728         
00729         double rmse = 0.0;
00730         int cnt = 0;
00731 
00732         for ( int cross=0;cross<m_data->m_nCross;cross++ )
00733         {
00734             for ( int i=0;i<m_nClass*m_nDomain;i++ )
00735             {
00736                 // clear and save the values of A and b
00737                 for ( int j=0;j<m_nTrain;j++ )
00738                 {
00739                     if ( randomIndex[j] == cross )
00740                     {
00741                         for ( int k=0;k<m_nPredictors;k++ )
00742                         {
00743                             tmpA[j + k*m_nTrain] = m_A[i][j + k*m_nTrain];
00744                             m_A[i][j + k*m_nTrain] = 0.0;
00745                         }
00746                         tmpB[j] = m_b[i][j];
00747                         m_b[i][j] = 0.0;
00748                     }
00749                 }
00750 
00751                 // solve linear equation system
00752                 if ( m_data->m_blendingAlgorithm=="LinearRegression" || m_data->m_blendingAlgorithm=="NelderMead" )
00753                 {
00754                     if ( m_globalWeights ) // equal weights for all classes and domains
00755                     {
00756                         REAL* A = new REAL[m_nTrain*m_nPredictors*m_nClass*m_nDomain], *b = new REAL[m_nTrain*m_nClass*m_nDomain];
00757                         for ( int j=0;j<m_nPredictors;j++ )
00758                             for ( int k=0;k<m_nClass*m_nDomain;k++ )
00759                                 for ( int l=0;l<m_nTrain;l++ )
00760                                     A[l + k*m_nTrain + j*m_nTrain*m_nClass*m_nDomain] = m_A[k][l+j*m_nTrain];
00761                         for ( int k=0;k<m_nClass*m_nDomain;k++ )
00762                             for ( int l=0;l<m_nTrain;l++ )
00763                                 b[l + k*m_nTrain] = m_b[k][l];
00764                         m_numTools.RidgeRegressionMultisolutionSinglecallGELSS ( A, b, m_x[i], m_nTrain*m_nClass*m_nDomain, m_nPredictors, 1, m_blendingRegularization, false );
00765                         delete[] A;
00766                         delete[] b;
00767                     }
00768                     else
00769                         m_numTools.RidgeRegressionMultisolutionSinglecallGELSS ( m_A[i], m_b[i], m_x[i], m_nTrain, m_nPredictors, 1, m_blendingRegularization, false );
00770                 }
00771                 else if ( m_data->m_blendingAlgorithm=="LinearRegressionNonNeg" )
00772                 {
00773                     if ( m_globalWeights ) // equal weights for all classes and domains
00774                     {
00775                         REAL* A = new REAL[m_nTrain*m_nPredictors*m_nClass*m_nDomain], *b = new REAL[m_nTrain*m_nClass*m_nDomain];
00776                         for ( int j=0;j<m_nPredictors;j++ )
00777                             for ( int k=0;k<m_nClass*m_nDomain;k++ )
00778                                 for ( int l=0;l<m_nTrain;l++ )
00779                                     A[l + k*m_nTrain + j*m_nTrain*m_nClass*m_nDomain] = m_A[k][l+j*m_nTrain];
00780                         for ( int k=0;k<m_nClass*m_nDomain;k++ )
00781                             for ( int l=0;l<m_nTrain;l++ )
00782                                 b[l + k*m_nTrain] = m_b[k][l];
00783                         m_numTools.RidgeRegressionNonNegSinglecall ( A, b, m_x[i], m_nTrain, m_nPredictors, m_blendingRegularization, 1e-10, 1000, false );
00784                         delete[] A;
00785                         delete[] b;
00786                     }
00787                     else
00788                         m_numTools.RidgeRegressionNonNegSinglecall ( m_A[i], m_b[i], m_x[i], m_nTrain, m_nPredictors, m_blendingRegularization, 1e-10, 1000, false );
00789                 }
00790 
00791                 // restore the values of A and b
00792                 for ( int j=0;j<m_nTrain;j++ )
00793                 {
00794                     if ( randomIndex[j] == cross )
00795                     {
00796                         for ( int k=0;k<m_nPredictors;k++ )
00797                             m_A[i][j + k*m_nTrain] = tmpA[j + k*m_nTrain];
00798                         m_b[i][j] = tmpB[j];
00799                     }
00800                 }
00801 
00802                 // calc RMSE with BLAS
00803                 CBLAS_GEMM ( CblasColMajor, CblasNoTrans, CblasNoTrans, m_nTrain, 1, m_nPredictors , 1.0, m_A[i], m_nTrain, m_x[i], m_nPredictors, 0.0, m_singlePrediction, m_nTrain );  // Ab = A'b
00804                 for ( int j=0;j<m_nTrain;j++ )
00805                 {
00806                     if ( randomIndex[j] == cross ) // predict only ratings in this fold
00807                     {
00808                         if ( m_data->m_enablePostBlendClipping )
00809                         {
00810                             if ( m_singlePrediction[j] < m_data->m_negativeTarget )
00811                                 m_singlePrediction[j] = m_data->m_negativeTarget;
00812                             if ( m_singlePrediction[j] > m_data->m_positiveTarget )
00813                                 m_singlePrediction[j] = m_data->m_positiveTarget;
00814                         }
00815                         m_prediction[j + m_nTrain*i] = m_singlePrediction[j];
00816                         rmse += ( m_singlePrediction[j] - m_b[i][j] ) * ( m_singlePrediction[j] - m_b[i][j] );
00817                         cnt++;
00818                     }
00819                 }
00820 
00821             }
00822         }
00823         if ( randomIndex )
00824             delete[] randomIndex;
00825         randomIndex = 0;
00826         if ( tmpA )
00827             delete[] tmpA;
00828         tmpA = 0;
00829         if ( tmpB )
00830             delete[] tmpB;
00831         tmpB = 0;
00832         rmse = sqrt ( rmse/ ( double ) cnt );
00833         return rmse;
00834     }
00835     if ( m_optimizeRMSE == 0 ) // optimize AUC
00836     {
00837         // init blending weights with params
00838         for ( int i=0;i<m_nClass*m_nDomain;i++ )
00839             for ( int j=0;j<m_nPredictors;j++ )
00840                 m_x[i][j] = m_paramsAUC[j + i*m_nPredictors];
00841 
00842         // calc predictions
00843         for ( int i=0;i<m_nClass*m_nDomain;i++ )
00844             for ( int j=0;j<m_nTrain;j++ )
00845             {
00846                 REAL out = 0.0;
00847                 for ( int k=0;k<m_nPredictors;k++ )
00848                     out += m_A[i][j+k*m_nTrain] * m_x[i][k];
00849                 m_prediction[j+i*m_nTrain] = out;
00850             }
00851 
00852         // calc area under curve
00853         REAL auc = getAUC ( m_prediction, m_data->m_trainLabelOrig, m_data->m_nClass, m_data->m_nDomain, m_data->m_nTrain );
00854         return auc;
00855     }
00856 
00857     assert ( false );
00858     return 0;
00859 }

double BlendStopping::getClassificationError (  ) 

Returns the classification error

Returns:
The classification error rate

Definition at line 583 of file BlendStopping.cpp.

00584 {
00585     return m_classificationError;
00586 }

void BlendStopping::loadBlendingWeights ( string  path,
int  nPredictors 
)

Load the blending weights

Parameters:
path The path where the file is located
nPredictors The number of prediction of this blend

Definition at line 620 of file BlendStopping.cpp.

00621 {
00622     char buf[1024];
00623     sprintf ( buf, "blendingWeights_%02d.dat", nPredictors );
00624     string name = path + "/" + string ( buf );
00625 
00626     cout<<"Load blending weights: "<<name<<endl;
00627     fstream f ( name.c_str(), ios::in );
00628     if ( f.is_open() == false )
00629         assert ( false );
00630     f.read ( ( char* ) &m_nClass, sizeof ( int ) );
00631     f.read ( ( char* ) &m_nDomain, sizeof ( int ) );
00632     f.read ( ( char* ) &m_nPredictors, sizeof ( int ) );
00633 
00634     // alloc mem
00635     if ( m_x == 0 )
00636     {
00637         m_x = new REAL*[m_nClass*m_nDomain];
00638         for ( int i=0;i<m_nClass*m_nDomain;i++ )
00639             m_x[i] = new REAL[m_nPredictors];
00640     }
00641 
00642     // read the solution weights
00643     for ( int i=0;i<m_nClass*m_nDomain;i++ )
00644         f.read ( ( char* ) m_x[i], sizeof ( REAL ) *m_nPredictors );
00645 
00646     printWeights ( false );
00647 
00648     f.close();
00649 }

void BlendStopping::predictEnsembleOutput ( REAL **  predictions,
REAL *  output 
)

Make a prediction for more input examples Make predictions with a given set of predictions per algorithm Here, a simple linear combination is calculated

Parameters:
predictions double** pointer to the predictions [nrPrediction][class] per class
output Pointer to output

Definition at line 659 of file BlendStopping.cpp.

00660 {
00661     for ( int i=0;i<m_nClass*m_nDomain;i++ )
00662         output[i] = 0.0;
00663     for ( int i=0;i<m_nClass*m_nDomain;i++ )
00664     {
00665         for ( int j=0;j<m_nPredictors;j++ )
00666             output[i] += m_x[i][j] * predictions[j][i];
00667 
00668         // no clipping, because of ambiguty of max. values (to determine classID)
00669         if ( m_data->m_enablePostBlendClipping )
00670             output[i] = NumericalTools::clipValue ( output[i], m_data->m_negativeTarget, m_data->m_positiveTarget );
00671     }
00672 }

void BlendStopping::printWeights ( bool  printBest = false  ) 

Print out blending weights (table)

Definition at line 678 of file BlendStopping.cpp.

00679 {
00680     cout<<"Blending weights (row: classes, col: predictors[1.col=const predictor])"<<endl;
00681     REAL** xPtr = printBest==true?m_xBest : m_x;
00682     for ( int i=0;i<m_nClass*m_nDomain;i++ )
00683     {
00684         if ( cout.m_enableOutput )
00685         {
00686             for ( int j=0;j<m_nPredictors;j++ )
00687                 printf ( "%1.3f\t",xPtr[i][j] );
00688             printf ( "\n" );
00689         }
00690     }
00691 }

void BlendStopping::saveBestPrediction (  )  [virtual]

tmp (needed virtual overrider in AutomaticParameterTuner)

Implements AutomaticParameterTuner.

Definition at line 873 of file BlendStopping.cpp.

00874 {
00875 
00876 }

void BlendStopping::saveBlendingWeights ( string  path,
bool  saveBest = false 
)

Saves the blending weights for later use

Parameters:
path The path for saving

Definition at line 593 of file BlendStopping.cpp.

00594 {
00595     printWeights ( saveBest );
00596 
00597     char buf[1024];
00598     sprintf ( buf, "blendingWeights_%02d.dat", m_nPredictors );
00599     string name = path + "/" + string ( buf );
00600     cout<<"Save blending weights: "<<name<<endl;
00601     fstream f ( name.c_str(), ios::out );
00602     f.write ( ( char* ) &m_nClass, sizeof ( int ) );
00603     f.write ( ( char* ) &m_nDomain, sizeof ( int ) );
00604     f.write ( ( char* ) &m_nPredictors, sizeof ( int ) );
00605 
00606     // write the solution weights
00607     REAL** xPtr = (saveBest==true?m_xBest:m_x);
00608     for ( int i=0;i<m_nClass*m_nDomain;i++ )
00609         f.write ( ( char* ) xPtr[i], sizeof ( REAL ) *m_nPredictors );
00610 
00611     f.close();
00612 }

void BlendStopping::saveTmpBestWeights (  ) 

Saves current blending weights

Definition at line 284 of file BlendStopping.cpp.

00285 {
00286     cout<<"[SB]";
00287     for ( int i=0;i<m_nClass*m_nDomain;i++ )
00288         for ( int j=0;j<m_nPredictors;j++ )
00289             m_xBest[i][j] = m_x[i][j];
00290 }

void BlendStopping::setRegularization ( REAL  reg  ) 

Set the regularization for the linear regression problem Ax=b In: x = inv(A'A + reg*I)A'b

Parameters:
reg The ridge-regression parameter

Definition at line 699 of file BlendStopping.cpp.

00700 {
00701     cout<<"Blending regularization: "<<reg<<endl;
00702     m_blendingRegularization = reg;
00703 }


The documentation for this class was generated from the following files:

Generated on Tue Jan 26 09:21:04 2010 for ELF by  doxygen 1.5.8