00001 #include "PolynomialRegression.h"
00002
00003 extern StreamOutput cout;
00004
00008 PolynomialRegression::PolynomialRegression()
00009 {
00010 cout<<"PolynomialRegression"<<endl;
00011
00012 m_x = 0;
00013 m_reg = 0;
00014 m_polyMean = 0;
00015 m_polyStd = 0;
00016 m_polyOrder = 0;
00017 m_enableCrossInteractions = 0;
00018 m_inputDim = 0;
00019 }
00020
00024 PolynomialRegression::~PolynomialRegression()
00025 {
00026 cout<<"descructor PolynomialRegression"<<endl;
00027 for ( int i=0;i<m_nCross+1;i++ )
00028 {
00029 if ( m_x )
00030 {
00031 if ( m_x[i] )
00032 delete[] m_x[i];
00033 m_x[i] = 0;
00034 }
00035 }
00036 if ( m_x )
00037 delete[] m_x;
00038 m_x = 0;
00039 if ( m_polyMean )
00040 delete[] m_polyMean;
00041 m_polyMean = 0;
00042 if ( m_polyStd )
00043 delete[] m_polyStd;
00044 m_polyStd = 0;
00045 }
00046
00051 void PolynomialRegression::readSpecificMaps()
00052 {
00053 m_polyOrder = m_intMap["polyOrder"];
00054 m_reg = m_doubleMap["initReg"];
00055 m_enableCrossInteractions = m_boolMap["enableCrossInteractions"];
00056 }
00057
00062 void PolynomialRegression::modelInit()
00063 {
00064
00065 paramDoubleValues.push_back ( &m_reg );
00066 paramDoubleNames.push_back ( "reg" );
00067
00068 m_inputDim = m_polyOrder * m_nFeatures;
00069
00070 if ( m_enableCrossInteractions )
00071 {
00072 m_inputDim = 0;
00073
00074
00075 for ( int i=0;i<m_polyOrder*m_nFeatures;i++ )
00076 for ( int j=0;j<m_polyOrder*m_nFeatures+1;j++ )
00077 if ( j >= i )
00078 m_inputDim++;
00079 }
00080
00081 cout<<"Input dimension:"<<m_inputDim<<endl;
00082
00083
00084 if ( m_x == 0 )
00085 {
00086 m_x = new REAL*[m_nCross+1];
00087 for ( int i=0;i<m_nCross+1;i++ )
00088 m_x[i] = new REAL[ ( m_inputDim + 1 ) * m_nClass * m_nDomain];
00089
00090
00091 m_polyMean = new REAL[m_inputDim];
00092 m_polyStd = new REAL[m_inputDim];
00093 }
00094 }
00095
00104 void PolynomialRegression::predictAllOutputs ( REAL* rawInputs, REAL* outputs, uint nSamples, uint crossRun )
00105 {
00106 REAL x,y;
00107
00108 for ( int i=0;i<nSamples;i++ )
00109 {
00110 for ( int j=0;j<m_nClass*m_nDomain;j++ )
00111 {
00112 if ( m_enableCrossInteractions )
00113 {
00114 REAL sum = 0.0;
00115 REAL* inputPtr = rawInputs + i*m_nFeatures;
00116 REAL* xPtr = m_x[crossRun] + j;
00117
00118
00119 int pos = 0;
00120 for ( int ii=0;ii<m_polyOrder*m_nFeatures;ii++ )
00121 for ( int jj=0;jj<m_polyOrder*m_nFeatures+1;jj++ )
00122 if ( jj >= ii )
00123 {
00124 int index0 = ii%m_nFeatures;
00125 int index1 = jj%m_nFeatures;
00126
00127 int order0 = ( ii%m_polyOrder ) + 1;
00128 int order1 = ( jj%m_polyOrder ) + 1;
00129
00130 x = inputPtr[index0];
00131 y = inputPtr[index1];
00132
00133 x = power ( x,order0 );
00134 y = power ( y,order1 );
00135
00136 if ( jj < m_polyOrder*m_nFeatures )
00137 x = x * y;
00138
00139 x = ( x - m_polyMean[pos] ) / m_polyStd[pos];
00140 sum += x * xPtr[pos*m_nClass*m_nDomain];
00141 pos++;
00142 }
00143
00144 sum += xPtr[pos];
00145 if ( pos != m_inputDim )
00146 assert ( false );
00147
00148 outputs[i*m_nClass*m_nDomain + j] = sum;
00149 }
00150 else
00151 {
00152 REAL sum = 1.0 * m_x[crossRun][m_polyOrder*m_nFeatures*m_nClass*m_nDomain + j];
00153 for ( int order=0;order<m_polyOrder;order++ )
00154 {
00155 REAL* inputPtr = rawInputs + i*m_nFeatures;
00156 REAL* meanPtr = m_polyMean + order*m_nFeatures;
00157 REAL* stdPtr = m_polyStd + order*m_nFeatures;
00158 REAL* xPtr = m_x[crossRun] + order*m_nClass*m_nDomain*m_nFeatures + j;
00159 for ( int k=0;k<m_nFeatures;k++ )
00160 {
00161 x = power ( inputPtr[k], order+1 );
00162 x = ( x - meanPtr[k] ) / stdPtr[k];
00163 sum += x * xPtr[k*m_nClass*m_nDomain];
00164 }
00165 }
00166 outputs[i*m_nClass*m_nDomain + j] = sum;
00167 }
00168 }
00169 }
00170 }
00171
00181 void PolynomialRegression::modelUpdate ( REAL* input, REAL* target, uint nSamples, uint crossRun )
00182 {
00183 REAL x,y;
00184 REAL* crossTrain = 0;
00185
00186 if ( m_enableCrossInteractions )
00187 {
00188 double minStd = 1e10, maxStd = -1e10, minMean = 1e10, maxMean = -1e10;
00189
00190
00191 int pos = 0;
00192 for ( int ii=0;ii<m_polyOrder*m_nFeatures;ii++ )
00193 for ( int jj=0;jj<m_polyOrder*m_nFeatures+1;jj++ )
00194 if ( jj >= ii )
00195 {
00196 int index0 = ii%m_nFeatures;
00197 int index1 = jj%m_nFeatures;
00198
00199 int order0 = ( ii%m_polyOrder ) + 1;
00200 int order1 = ( jj%m_polyOrder ) + 1;
00201
00202
00203 double mean = 0.0, val;
00204 for ( int j=0;j<nSamples;j++ )
00205 {
00206 x = input[j*m_nFeatures + index0];
00207 y = input[j*m_nFeatures + index1];
00208
00209 x = power ( x,order0 );
00210 y = power ( y,order1 );
00211
00212 if ( jj < m_polyOrder*m_nFeatures )
00213 x = x * y;
00214
00215 mean += x;
00216 }
00217 mean /= ( double ) nSamples;
00218
00219
00220 double std = 0.0;
00221 for ( int j=0;j<nSamples;j++ )
00222 {
00223 x = input[j*m_nFeatures + index0];
00224 y = input[j*m_nFeatures + index1];
00225
00226 x = power ( x,order0 );
00227 y = power ( y,order1 );
00228
00229 if ( jj < m_polyOrder*m_nFeatures )
00230 x = x * y;
00231
00232 std += ( mean - x ) * ( mean - x );
00233 }
00234 std = sqrt ( std/ ( double ) ( nSamples-1 ) );
00235 if ( std < m_standardDeviationMin )
00236 std = m_standardDeviationMin;
00237
00238 minStd = minStd > std? std : minStd;
00239 maxStd = maxStd < std? std : maxStd;
00240 minMean = minMean > mean? mean : minMean;
00241 maxMean = maxMean < mean? mean : maxMean;
00242
00243
00244 m_polyMean[pos] = mean;
00245 m_polyStd[pos] = std;
00246 pos++;
00247 }
00248
00249
00250
00251
00252 if ( pos != m_inputDim )
00253 assert ( false );
00254
00255
00256 crossTrain = new REAL[nSamples* ( m_inputDim+1 ) ];
00257 for ( int i=0;i<nSamples;i++ )
00258 {
00259 REAL* inputPtr = input + i*m_nFeatures;
00260 REAL* trainPtr = crossTrain + i* ( m_inputDim + 1 );
00261
00262
00263 pos = 0;
00264 for ( int ii=0;ii<m_polyOrder*m_nFeatures;ii++ )
00265 for ( int jj=0;jj<m_polyOrder*m_nFeatures+1;jj++ )
00266 if ( jj >= ii )
00267 {
00268 int index0 = ii%m_nFeatures;
00269 int index1 = jj%m_nFeatures;
00270
00271 int order0 = ( ii%m_polyOrder ) + 1;
00272 int order1 = ( jj%m_polyOrder ) + 1;
00273
00274 x = inputPtr[index0];
00275 y = inputPtr[index1];
00276
00277 x = power ( x,order0 );
00278 y = power ( y,order1 );
00279
00280 if ( jj < m_polyOrder*m_nFeatures )
00281 x = x * y;
00282
00283 trainPtr[pos] = ( x - m_polyMean[pos] ) / m_polyStd[pos];
00284 pos++;
00285 }
00286 trainPtr[pos] = 1.0;
00287
00288 if ( pos != m_inputDim )
00289 assert ( false );
00290 }
00291
00292
00293 solver.RidgeRegressionMultisolutionSinglecall ( crossTrain, target, m_x[crossRun], nSamples, m_inputDim + 1, m_nClass*m_nDomain, m_reg, true );
00294 }
00295 else
00296 {
00297 crossTrain = new REAL[nSamples* ( m_polyOrder*m_nFeatures+1 ) ];
00298
00299
00300 double minStd = 1e10, maxStd = -1e10, minMean = 1e10, maxMean = -1e10;
00301 for ( int order=0;order<m_polyOrder;order++ )
00302 {
00303 for ( int i=0;i<m_nFeatures;i++ )
00304 {
00305
00306 double mean = 0.0, val;
00307 for ( int j=0;j<nSamples;j++ )
00308 {
00309 val = input[j*m_nFeatures + i];
00310 mean += power ( val, order+1 );
00311 }
00312 mean /= ( double ) nSamples;
00313
00314
00315 double std = 0.0;
00316 for ( int j=0;j<nSamples;j++ )
00317 {
00318 val = input[j*m_nFeatures + i];
00319 val = power ( val, order+1 );
00320 std += ( mean - val ) * ( mean - val );
00321 }
00322 std = sqrt ( std/ ( double ) ( nSamples-1 ) );
00323 if ( std < m_standardDeviationMin )
00324 std = m_standardDeviationMin;
00325
00326 minStd = minStd > std? std : minStd;
00327 maxStd = maxStd < std? std : maxStd;
00328 minMean = minMean > mean? mean : minMean;
00329 maxMean = maxMean < mean? mean : maxMean;
00330
00331
00332 m_polyMean[order*m_nFeatures + i] = mean;
00333 m_polyStd[order*m_nFeatures + i] = std;
00334 }
00335 }
00336
00337
00338
00339 for ( int i=0;i<nSamples;i++ )
00340 {
00341 for ( int order=0;order<m_polyOrder;order++ )
00342 {
00343 int index = i* ( m_polyOrder*m_nFeatures + 1 ) + order * m_nFeatures;
00344 REAL* inputPtr = input + i*m_nFeatures;
00345 REAL* meanPtr = m_polyMean + order*m_nFeatures;
00346 REAL* stdPtr = m_polyStd + order*m_nFeatures;
00347 REAL* featurePtr = crossTrain + index;
00348 for ( int k=0;k<m_nFeatures;k++ )
00349 {
00350 x = power ( inputPtr[k], order+1 );
00351 x = ( x - meanPtr[k] ) / stdPtr[k];
00352 featurePtr[k] = x;
00353 }
00354 }
00355 crossTrain[i* ( m_polyOrder*m_nFeatures + 1 ) + m_polyOrder*m_nFeatures] = 1.0;
00356 }
00357
00358
00359 solver.RidgeRegressionMultisolutionSinglecall ( crossTrain, target, m_x[crossRun], nSamples, m_polyOrder * m_nFeatures + 1, m_nClass*m_nDomain, m_reg, true );
00360 }
00361 if ( crossTrain )
00362 delete[] crossTrain;
00363 crossTrain = 0;
00364 }
00365
00373 REAL PolynomialRegression::power ( REAL x, int e )
00374 {
00375 REAL tmp = x;
00376 for ( int i=1;i<e;i++ )
00377 tmp *= x;
00378 return tmp;
00379 }
00380
00385 void PolynomialRegression::saveWeights ( int cross )
00386 {
00387 char buf[1024];
00388 sprintf ( buf,"%02d",cross );
00389 string name = m_datasetPath + "/" + m_tempPath + "/" + m_weightFile + "." + buf;
00390 if ( m_inRetraining )
00391 cout<<"Save:"<<name<<endl;
00392 fstream f ( name.c_str(), ios::out );
00393 f.write ( ( char* ) &m_nTrain, sizeof ( int ) );
00394 f.write ( ( char* ) &m_nFeatures, sizeof ( int ) );
00395 f.write ( ( char* ) &m_nClass, sizeof ( int ) );
00396 f.write ( ( char* ) &m_nDomain, sizeof ( int ) );
00397 f.write ( ( char* ) &m_inputDim, sizeof ( int ) );
00398 f.write ( ( char* ) m_x[cross], sizeof ( REAL ) * ( m_inputDim+1 ) *m_nClass*m_nDomain );
00399 f.write ( ( char* ) m_polyMean, sizeof ( REAL ) *m_inputDim );
00400 f.write ( ( char* ) m_polyStd, sizeof ( REAL ) *m_inputDim );
00401 f.write ( ( char* ) &m_maxSwing, sizeof ( double ) );
00402 f.write ( ( char* ) &m_reg, sizeof ( double ) );
00403 f.close();
00404 }
00405
00410 void PolynomialRegression::loadWeights ( int cross )
00411 {
00412 char buf[1024];
00413 sprintf ( buf,"%02d",cross );
00414 string name = m_datasetPath + "/" + m_tempPath + "/" + m_weightFile + "." + buf;
00415 cout<<"Load:"<<name<<endl;
00416 fstream f ( name.c_str(), ios::in );
00417 if ( f.is_open() == false )
00418 assert ( false );
00419 f.read ( ( char* ) &m_nTrain, sizeof ( int ) );
00420 f.read ( ( char* ) &m_nFeatures, sizeof ( int ) );
00421 f.read ( ( char* ) &m_nClass, sizeof ( int ) );
00422 f.read ( ( char* ) &m_nDomain, sizeof ( int ) );
00423 f.read ( ( char* ) &m_inputDim, sizeof ( int ) );
00424
00425 m_x = new REAL*[m_nCross+1];
00426 for ( int i=0;i<m_nCross+1;i++ )
00427 m_x[i] = 0;
00428 m_x[cross] = new REAL[ ( m_inputDim + 1 ) * m_nClass * m_nDomain];
00429 m_polyMean = new REAL[m_inputDim];
00430 m_polyStd = new REAL[m_inputDim];
00431
00432 f.read ( ( char* ) m_x[cross], sizeof ( REAL ) * ( m_inputDim+1 ) *m_nClass*m_nDomain );
00433 f.read ( ( char* ) m_polyMean, sizeof ( REAL ) *m_inputDim );
00434 f.read ( ( char* ) m_polyStd, sizeof ( REAL ) *m_inputDim );
00435 f.read ( ( char* ) &m_maxSwing, sizeof ( double ) );
00436 f.read ( ( char* ) &m_reg, sizeof ( double ) );
00437 f.close();
00438 }
00439
00443 void PolynomialRegression::loadMetaWeights ( int cross )
00444 {
00445 char buf[1024];
00446 sprintf ( buf,"%02d",cross );
00447 string name = m_datasetPath + "/" + m_tempPath + "/" + m_weightFile + "." + buf;
00448 cout<<"LoadMeta:"<<name<<endl;
00449 fstream f ( name.c_str(), ios::in );
00450 if ( f.is_open() == false )
00451 assert ( false );
00452 f.read ( ( char* ) &m_nTrain, sizeof ( int ) );
00453 f.read ( ( char* ) &m_nFeatures, sizeof ( int ) );
00454 f.read ( ( char* ) &m_nClass, sizeof ( int ) );
00455 f.read ( ( char* ) &m_nDomain, sizeof ( int ) );
00456 f.read ( ( char* ) &m_inputDim, sizeof ( int ) );
00457
00458 REAL* tmp = new REAL[ ( m_inputDim+1 ) *m_nClass*m_nDomain];
00459 f.read ( ( char* ) tmp, sizeof ( REAL ) * ( m_inputDim+1 ) *m_nClass*m_nDomain );
00460 delete[] tmp;
00461 tmp = new REAL[m_inputDim];
00462 f.read ( ( char* ) tmp, sizeof ( REAL ) *m_inputDim );
00463 f.read ( ( char* ) tmp, sizeof ( REAL ) *m_inputDim );
00464 delete[] tmp;
00465 f.read ( ( char* ) &m_maxSwing, sizeof ( double ) );
00466 f.read ( ( char* ) &m_reg, sizeof ( double ) );
00467 f.close();
00468 }
00469
00475 string PolynomialRegression::templateGenerator ( int id, string preEffect, int nameID, bool blendStop )
00476 {
00477 stringstream s;
00478 s<<"ALGORITHM=PolynomialRegression"<<endl;
00479 s<<"ID="<<id<<endl;
00480 s<<"TRAIN_ON_FULLPREDICTOR="<<preEffect<<endl;
00481 s<<"DISABLE=0"<<endl;
00482 s<<endl;
00483 s<<"[int]"<<endl;
00484 s<<"polyOrder=2"<<endl;
00485 s<<"maxTuninigEpochs=20"<<endl;
00486 s<<endl;
00487 s<<"[double]"<<endl;
00488 s<<"initMaxSwing=1.0"<<endl;
00489 s<<"initReg=1e-3"<<endl;
00490 s<<endl;
00491 s<<"[bool]"<<endl;
00492 s<<"enableCrossInteractions=0"<<endl;
00493 s<<"enableClipping=1"<<endl;
00494 s<<"enableTuneSwing=0"<<endl;
00495 s<<endl;
00496 s<<"minimzeProbe="<< ( !blendStop ) <<endl;
00497 s<<"minimzeProbeClassificationError=0"<<endl;
00498 s<<"minimzeBlend="<<blendStop<<endl;
00499 s<<"minimzeBlendClassificationError=0"<<endl;
00500 s<<endl;
00501 s<<"[string]"<<endl;
00502 s<<"weightFile=PolynomialRegression_"<<nameID<<"_weights.dat"<<endl;
00503 s<<"fullPrediction=PolynomialRegression_"<<nameID<<".dat"<<endl;
00504
00505 return s.str();
00506 }