00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <boost/numeric/ublas/matrix_proxy.hpp>
00020 #include <boost/numeric/ublas/vector_proxy.hpp>
00021 #include <boost/numeric/ublas/vector_expression.hpp>
00022 #include <boost/numeric/ublas/io.hpp>
00023
00024 #include <iostream>
00025 #include <iomanip>
00026
00027
00028
00029
00030 #include "model.hpp"
00031
00032 Model::Model() {
00033
00034 };
00035
00036 Model::Model(int input_dim) : N(input_dim),R(2),
00037 beta_0(0),
00038 x_0(N),
00039 MSE(R),
00040 data_count(R), derivatives_ok(R),
00041 a_zz(R),a_zres(R),a_xz(N,R),
00042 y_target(R),e_cv(R),
00043 u(N,R),p(N,R),
00044 x_res(N,R+1),beta(R),z(R),
00045 x_temp(N), u_temp(N,R)
00046 {
00047
00048 u.clear();
00049 p.clear();
00050
00051 u_temp.clear();
00052
00053
00054 u(0,0) = 1;
00055 p(0,0) = 1;
00056
00057 if(N>1){
00058 u(1,1) = 1;
00059 p(1,1) = 1;
00060 }
00061
00062 lambda = .999;
00063 phi = 0.5;
00064
00065 x_0.clear();
00066 beta.clear();
00067 MSE.clear();
00068
00069
00070 data_count = ublas::scalar_vector<Types::RValue>(R,1e-10);
00071 derivatives_ok = ublas::zero_vector<Types::RValue>(R);
00072 a_zz = ublas::scalar_vector<Types::RValue>(R,1e-10);
00073
00074 a_zres.clear();
00075 a_xz.clear();
00076 }
00077
00078 Model::Model(int input_dim, const boost::program_options::variables_map& vm) : N(input_dim),R(2),
00079 beta_0(0),
00080 x_0(N),
00081 MSE(R),
00082 data_count(R), derivatives_ok(R),
00083 a_zz(R),a_zres(R),a_xz(N,R),
00084 y_target(R),e_cv(R),
00085 u(N,R),p(N,R),
00086 x_res(N,R+1),beta(R),z(R),
00087 x_temp(N), u_temp(N,R)
00088 {
00089
00090 u.clear();
00091 p.clear();
00092
00093 u_temp.clear();
00094
00095
00096 u(0,0) = 1;
00097 p(0,0) = 1;
00098
00099 if(N>1){
00100 u(1,1) = 1;
00101 p(1,1) = 1;
00102 }
00103
00104 lambda = vm["lambda"].as<Types::RParam>();
00105 phi = vm["phi"].as<Types::RParam>();
00106
00107 x_0.clear();
00108 beta.clear();
00109
00110 MSE.clear();
00111
00112
00113 data_count = ublas::scalar_vector<Types::RValue>(R,1e-10);
00114 derivatives_ok = ublas::zero_vector<Types::RValue>(R);
00115 a_zz = ublas::scalar_vector<Types::RValue>(R,1e-10);
00116
00117 a_zres.clear();
00118 a_xz.clear();
00119 }
00120
00121
00122 void Model::learn(Types::Input x, Types::Output y, Types::RValue w, Types::RValue W, Types::RValue W_old){
00123 x_0 = (lambda * W_old * x_0 + w * x)/W;
00124 beta_0 = (lambda * W_old * beta_0 + w * y)/W;
00125
00126
00127 column(x_res,0) = x - x_0;
00128 y_hat = beta_0;
00129
00130 for(int r=0; r<R; ++r){
00131 z(r) = prec_inner_prod(column(x_res,r),column(u,r));
00132
00133
00134 y_hat += beta(r) * z(r);
00135 e_cv(r) = y-y_hat;
00136
00137 column(x_res,r+1) = column(x_res,r) - z(r) * column(p,r);
00138 MSE(r) = lambda * MSE(r) + w * (y-y_hat) * (y-y_hat);
00139 }
00140
00141 y_target(0) = y-beta_0;
00142 ublas::project(y_target, ublas::range(1,R)).assign(ublas::project(e_cv,ublas::range(0,R-1)));
00143
00144
00145
00146 res = y - beta_0;
00147 for(int r=0; r<R; ++r){
00148 a_zz(r) = lambda * a_zz(r) + w * z(r) * z(r);
00149
00150
00151 a_zres(r) = lambda * a_zres(r) + w * z(r) * y_target(r);
00152
00153 beta(r) = a_zres(r) / a_zz(r);
00154
00155 column(a_xz,r) = lambda * column(a_xz,r) + w * column(x_res,r) * z(r);
00156
00157
00158 Types::RParam lambda_slow = 1 - (1-lambda)/10;
00159
00160
00161 column(u_temp,r) = lambda_slow * column(u_temp,r) + w * y_target(r)*column(x_res,r);
00162
00163 Types::RValue norm_coeff = ublas::norm_2(column(u_temp,r));
00164 if(norm_coeff > 0)
00165 column(u,r) = column(u_temp,r)/norm_coeff;
00166
00167 column(p,r) = column(a_xz,r) / a_zz(r);
00168
00169 res -= z(r) * beta(r);
00170 }
00171
00172 e = res;
00173
00174
00175 data_count = lambda * data_count + ublas::scalar_vector<Types::RValue>(R,1.0);
00176
00177 }
00178
00179 bool Model::trustworthy() const
00180 {
00181 bool trust = true;
00182
00183 for(int r=0; r<R; ++r)
00184 trust = trust && (data_count(r) > 2*N);
00185
00186 return trust;
00187 }
00188
00189 Types::Input Model::check_derivatives() const
00190 {
00191 for(int r=0; r<R; ++r)
00192 derivatives_ok(r) = (data_count(r) > 0.1/(1-lambda));
00193
00194 return derivatives_ok;
00195 }
00196
00197 bool Model::updateNumProjections()
00198 {
00199 if( (R < N) &&
00200 (MSE(R-1)/MSE(R-2) <= phi) &&
00201 data_count(R-1)/data_count(0) > .9 &&
00202 data_count(R-1)*(1-lambda) > 0.5
00203 ){
00204
00205 std::cerr << "****************** Adding Projection: " << x_0 << " ******************" << std::endl;
00206
00207
00208 R += 1;
00209
00210
00211 u.resize(N,R);
00212 p.resize(N,R);
00213 a_xz.resize(N,R);
00214
00215 for(int i=0; i<N; ++i){
00216 u(i,R-1) = (i == R-1);
00217 p(i,R-1) = (i == R-1);
00218 a_xz(i,R-1) = 0;
00219 }
00220
00221 a_zz.resize(R);
00222 a_zz(R-1) = 1e-10;
00223
00224 a_zres.resize(R);
00225
00226 MSE.resize(R);
00227 MSE(R-1) = 0;
00228
00229 e_cv.resize(R);
00230 y_target.resize(R);
00231
00232 u_temp.resize(N,R);
00233 for (int i=0;i<N;++i)
00234 u_temp(i,R-1) = 0;
00235
00236 data_count.resize(R);
00237 data_count(R-1) = 1e-10;
00238 derivatives_ok.resize(R);
00239 derivatives_ok(R-1) = 0;
00240
00241 x_res.resize(N,R+1);
00242 beta.resize(R);
00243 z.resize(R);
00244
00245 return true;
00246 }
00247 else
00248 return false;
00249 }
00250
00251 Types::OutputT Model::predict(Types::Input x) const {
00252 Types::OutputT y = beta_0;
00253
00254 Types::vector &x_local = const_cast<Types::vector&>(x_temp);
00255
00256 x_local = x - x_0;
00257
00258 for(int r=0; r<R; ++r){
00259 Types::RValue s = prec_inner_prod(column(u,r),x_local);
00260
00261 y += beta(r) * s;
00262 x_local -= s * column(p,r);
00263 }
00264
00265 return y;
00266
00267 }
00268
00269 void Model::project(Types::Input x, Types::vector& z) const {
00270 z.resize(x.size());
00271 z = x - x_0;
00272
00273 for(int r=0; r<R; ++r){
00274 Types::RValue s = prec_inner_prod(column(u,r),z);
00275
00276 z -= s * column(p,r);
00277 }
00278 }
00279
00280 std::ostream& operator<<(std::ostream& out, const Model& m)
00281 {
00282 out << m.u << std::endl;
00283 }
00284