source: trunk/test/regression_test.cc @ 740

Last change on this file since 740 was 740, checked in by Peter, 16 years ago

added more test in MultiDimWeighted? and moved some stuff to be implemented in MultiDimWeighted? rather than in PolynomialWeighted?.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 13.7 KB
Line 
1// $Id: regression_test.cc 740 2007-01-12 15:17:22Z peter $
2
3/*
4  Copyright (C) The authors contributing to this file.
5
6  This file is part of the yat library, http://lev.thep.lu.se/trac/yat
7
8  The yat library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2 of the
11  License, or (at your option) any later version.
12
13  The yat library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21  02111-1307, USA.
22*/
23
24#include "yat/regression/KernelBox.h"
25#include "yat/regression/Linear.h"
26#include "yat/regression/LinearWeighted.h"
27#include "yat/regression/Local.h"
28#include "yat/regression/Naive.h"
29#include "yat/regression/NaiveWeighted.h"
30#include "yat/regression/Polynomial.h"
31#include "yat/regression/PolynomialWeighted.h"
32#include "yat/utility/matrix.h"
33#include "yat/utility/vector.h"
34
35#include <cmath>
36
37#include <fstream>
38#include <iostream>
39
40
41using namespace theplu::yat;
42
43bool equal(regression::OneDimensional&, regression::OneDimensionalWeighted&, 
44           std::ostream*); 
45
46bool multidim(std::ostream* error);
47
48bool unity_weights(regression::OneDimensional&, 
49                   regression::OneDimensionalWeighted&, 
50                   const utility::vector&, const utility::vector&,
51                   std::ostream*); 
52
53bool rescale_weights(regression::OneDimensionalWeighted&, 
54                     const utility::vector&, const utility::vector&,
55                     std::ostream*); 
56
57bool zero_weights(regression::OneDimensionalWeighted&, 
58                  const utility::vector&, const utility::vector&,
59                  std::ostream*); 
60
61
62bool Local_test(regression::OneDimensionalWeighted&, 
63                regression::Kernel&);
64
65int main(const int argc,const char* argv[])
66{
67  std::ostream* error;
68  if (argc>1 && argv[1]==std::string("-v"))
69    error = &std::cerr;
70  else {
71    error = new std::ofstream("/dev/null");
72    if (argc>1)
73      std::cout << "regression_test -v : for printing extra information\n";
74  }
75  *error << "  testing regression" << std::endl;
76  bool ok = true;
77
78  // test data for Linear and Naive (Weighted and non-weighted)
79  utility::vector x(4); x(0)=1970; x(1)=1980; x(2)=1990; x(3)=2000;
80  utility::vector y(4); y(0)=12;   y(1)=11;   y(2)=14;   y(3)=13;
81  utility::vector w(4); w(0)=0.1;  w(1)=0.2;  w(2)=0.3;  w(3)=0.4;
82
83  // Comparing linear and polynomial(1)
84  regression::Linear linear;
85  linear.fit(x,y);
86  regression::Polynomial polynomial(1);
87  polynomial.fit(x,y);
88  if ( fabs(linear.beta()-polynomial.fit_parameters()(1))>0.0001 ){
89    *error << "error: beta and fit_parameters(1) not equal" << std::endl;
90    *error << "       beta = " << linear.beta() << std::endl;
91    *error << "       fit_parameters(1) = " 
92           << polynomial.fit_parameters()(1) << std::endl;
93    ok = false;
94  }
95  if ( fabs(polynomial.fit_parameters()(0)-linear.alpha()+
96            linear.beta()*1985)>0.0001){
97    *error << "error: fit_parameters(0) = " 
98           << polynomial.fit_parameters()(0)<< std::endl;
99    *error << "error: alpha-beta*m_x = " 
100           << linear.alpha()-linear.beta()*1985 << std::endl;
101    ok = false;
102  }
103  if ( fabs(polynomial.chisq()-linear.chisq())>0.0001){
104    *error << "error: chisq not same in linear and polynomial(1)" 
105           << std::endl;
106    ok = false;
107  }
108  if ( fabs(polynomial.predict(1.0)-linear.predict(1.0))>0.0001){
109    *error << "error: predict not same in linear and polynomial(1)" 
110           << std::endl;
111    ok = false;
112  }
113  if ( fabs(polynomial.standard_error2(1985)-linear.standard_error2(1985))
114       >0.0001){
115    *error << "error: standard_error not same in linear and polynomial(1)" 
116           << "\n  polynomial: " << polynomial.standard_error2(1985)
117           << "\n  linear: " << linear.standard_error2(1985)
118           << std::endl;
119    ok = false;
120  }
121
122  *error << "  testing regression::LinearWeighted" << std::endl;
123  regression::LinearWeighted linear_w;
124  ok = equal(linear, linear_w, error) && ok;
125  linear_w.fit(x,y,w);
126  double y_predicted = linear_w.predict(1990);
127  double y_predicted_err = linear_w.prediction_error2(1990);
128  if (fabs(y_predicted-12.8)>0.001){
129    *error << "error: cannot reproduce fit." << std::endl;
130    *error << "predicted value: " << y_predicted << " expected 12.8" 
131           << std::endl;
132    ok=false;
133  }
134
135  // testing regression::NaiveWeighted
136  *error << "  testing regression::NaiveWeighted" << std::endl;
137  regression::NaiveWeighted naive_w;
138  regression::Naive naive;
139  ok = equal(naive, naive_w, error) && ok;
140  naive_w.fit(x,y,w);
141
142  y_predicted=naive_w.predict(0.0);
143  y_predicted_err=naive_w.prediction_error2(0.0);
144  if (y_predicted!=(0.1*12+0.2*11+0.3*14+0.4*13)) {
145    *error << "regression_NaiveWeighted: cannot reproduce fit." << std::endl;
146    *error << "returned value: " << y_predicted << std::endl;
147    *error << "expected: " << 0.1*12+0.2*11+0.3*14+0.4*13 << std::endl;
148    ok=false;
149  }
150
151  // testing regression::Local
152  *error << "  testing regression::Local" << std::endl;
153  regression::KernelBox kb;
154  regression::LinearWeighted rl;
155  if (!Local_test(rl,kb)) {
156    *error << "regression_Local: Linear cannot reproduce fit." << std::endl;
157    ok=false;
158  }
159  regression::NaiveWeighted rn;
160  if (!Local_test(rn,kb)) {
161    *error << "regression_Local: Naive cannot reproduce fit." << std::endl;
162    ok=false;
163  }
164
165  // testing regression::Polynomial
166  *error << "  testing regression::Polynomial" << std::endl;
167  {
168    std::ifstream s("data/regression_gauss.data");
169    utility::matrix data(s);
170    utility::vector x(data.rows());
171    utility::vector ln_y(data.rows());
172    for (size_t i=0; i<data.rows(); ++i) {
173      x(i)=data(i,0);
174      ln_y(i)=log(data(i,1));
175    }
176
177    regression::Polynomial polynomialfit(2);
178    polynomialfit.fit(x,ln_y);
179    utility::vector fit=polynomialfit.fit_parameters();
180    if (fabs(fit[0]-1.012229646706 + fit[1]-0.012561322528 +
181             fit[2]+1.159674470130)>1e-11) {  // Jari, fix number!
182      *error << "regression_Polynomial: cannot reproduce fit." << std::endl;
183      ok=false;
184    }
185  }
186
187  *error << "  testing regression::PolynomialWeighted" << std::endl;
188  regression::PolynomialWeighted pol_weighted(2);
189  regression::Polynomial polynomial2(2);
190  // ok = equal(polynomial2, pol_weighted, error) && ok;
191
192  ok = multidim(error) && ok;
193
194  if (!ok)
195    *error << "Test failed\n" << std::endl;
196
197  if (error!=&std::cerr)
198    delete error;
199
200  return (ok ? 0 : -1);
201}
202
203
204bool equal(regression::OneDimensional& r, 
205           regression::OneDimensionalWeighted& wr, 
206           std::ostream* error)
207{
208  bool ok=true;
209  utility::vector x(5); x(0)=1970; x(1)=1980; x(2)=1990; x(3)=2000; x(4)=2010;
210  utility::vector y(5); y(0)=12;   y(1)=11;   y(2)=14;   y(3)=13;   y(4)=15;
211
212  ok = unity_weights(r, wr, x, y, error) && ok;
213  ok = rescale_weights(wr, x, y, error) && ok;
214  ok = zero_weights(wr, x, y, error) && ok;
215  return ok;
216}
217
218
219bool unity_weights(regression::OneDimensional& r, 
220                   regression::OneDimensionalWeighted& rw, 
221                   const utility::vector& x, const utility::vector& y,
222                   std::ostream* error)
223{
224  *error << "    testing unity weights equal to non-weighted version.\n"; 
225  bool ok=true;
226  utility::vector w(x.size(), 1.0);
227  r.fit(x,y);
228  rw.fit(x,y,w);
229  if (r.predict(2000) != rw.predict(2000)){
230    ok = false;
231    *error << "Error: predict not equal\n" 
232           << "   weighted: " << rw.predict(2000) << "\n"
233           << "   non-weighted: " << r.predict(2000)
234           << std::endl;
235  }
236  if (fabs(r.prediction_error2(2000)-rw.prediction_error2(2000))>10e-7){
237    ok = false;
238    *error << "Error: prediction_error2 not equal non-weighted version.\n" 
239           << "       weighted: " << rw.prediction_error2(2000) << "\n"
240           << "   non-weighted: " << r.prediction_error2(2000)
241           << std::endl;
242  }
243  if (fabs(r.s2()-rw.s2())>10E-7){
244    ok = false;
245    *error << "Error: r2 not equal non-weighted version." << std::endl;
246    *error << "weighted r2 = " << rw.r2() << std::endl;
247    *error << "non-weighted r2 = " << r.r2() << std::endl;
248  }
249  if (fabs(r.s2()-rw.s2())>10E-7){
250    ok = false;
251    *error << "Error: s2 not equal non-weighted version." << std::endl;
252    *error << "weighted s2 = " << rw.s2() << std::endl;
253    *error << "non-weighted s2 = " << r.s2() << std::endl;
254  }
255  if (fabs(r.standard_error2(2000)-rw.standard_error2(2000))>10e-7){
256    ok = false;
257    *error << "Error: standard_error not equal non-weighted version." 
258           << std::endl;
259  }
260  return ok;
261} 
262
263
264bool rescale_weights(regression::OneDimensionalWeighted& wr, 
265                     const utility::vector& x, const utility::vector& y,
266                     std::ostream* error)
267{
268  *error << "    testing rescaling weights.\n"; 
269  bool ok = true;
270  utility::vector w(5);  w(0)=1.0;  w(1)=1.0;  w(2)=0.5;  w(3)=0.2;  w(4)=0.2;
271  wr.fit(x,y,w);
272  double predict = wr.predict(2000);
273  double prediction_error2 = wr.prediction_error2(2000);
274  double r2 = wr.r2();
275  double s2 = wr.s2();
276  double standard_error2 = wr.standard_error2(2000);
277
278  w.scale(2);
279  wr.fit(x,y,w);
280  if (wr.predict(2000) != predict){
281    ok = false;
282    *error << "Error: predict not equal after rescaling.\n";
283  }
284  if (wr.prediction_error2(2000,2) != prediction_error2){
285    ok = false;
286    *error << "Error: prediction_error2 not equal after rescaling.\n";
287  }
288  if (wr.r2() != r2){
289    ok = false;
290    *error << "Error: r2 not equal after rescaling.\n";
291  }
292  if (wr.s2(2) != s2){
293    ok = false;
294    *error << "Error: s2 not equal after rescaling.\n";
295    *error << "       s2 = " << s2 << " and after doubling weights.\n";
296    *error << "       s2 = " << wr.s2(2) << "\n";
297  }
298  if (wr.standard_error2(2000) != standard_error2){
299    ok = false;
300    *error << "Error: standard_error2 not equal after rescaling.\n";
301  }
302  return ok; 
303}
304
305
306bool zero_weights(regression::OneDimensionalWeighted& wr, 
307                  const utility::vector& x, const utility::vector& y,
308                  std::ostream* error)
309{
310  *error << "    testing zero weights equal to missing value.\n"; 
311  bool ok = true;
312  utility::vector w(5);  w(0)=1.0;  w(1)=1.0;  w(2)=0.5;  w(3)=0.2;  w(4)=0;
313  wr.fit(x,y,w);
314  double predict = wr.predict(2000);
315  double prediction_error2 = wr.prediction_error2(2000);
316  double r2 = wr.r2();
317  double s2 = wr.s2();
318  double standard_error2 = wr.standard_error2(2000);
319
320  utility::vector x2(4);
321  utility::vector y2(4);
322  utility::vector w2(4);
323  for (size_t i=0; i<4; ++i){
324    x2(i) = x(i);
325    y2(i) = y(i);
326    w2(i) = w(i);
327  }
328
329  wr.fit(x2,y2,w2);
330  if (wr.predict(2000) != predict){
331    ok = false;
332    *error << "Error: predict not equal.\n";
333  }
334  if (wr.prediction_error2(2000) != prediction_error2){
335    ok = false;
336    *error << "Error: prediction_error2 not equal.\n";
337  }
338  if (wr.r2() != r2){
339    ok = false;
340    *error << "Error: r2 not equal.\n";
341  }
342  if (wr.s2() != s2){
343    ok = false;
344    *error << "Error: s2 not equal.\n";
345  }
346  if (wr.standard_error2(2000) != standard_error2){
347    ok = false;
348    *error << "Error: standard_error2 not equal.\n";
349  }
350  return ok; 
351}
352
353
354bool multidim(std::ostream* error)
355{
356  bool ok = true;
357  *error << "  testing regression::MultiDimensionalWeighted" << std::endl;
358  utility::vector x(5); x(0)=1970; x(1)=1980; x(2)=1990; x(3)=2000; x(4)=2010;
359  utility::vector y(5); y(0)=12;   y(1)=11;   y(2)=14;   y(3)=13;   y(4)=15;
360  utility::vector w(5,1.0);
361 
362  utility::matrix data(5,3);
363  for (size_t i=0; i<data.rows(); ++i){
364    data(i,0)=1;
365    data(i,1)=x(i);
366    data(i,2)=x(i)*x(i);
367  }
368  regression::MultiDimensional md;
369  md.fit(data,y);
370  regression::MultiDimensionalWeighted mdw;
371  mdw.fit(data,y,w);
372  utility::vector z(3,1);
373  z(1)=2000;
374  z(2)=2000*2000;
375  if (md.predict(z) != mdw.predict(z)){
376    ok = false;
377    *error << "Error: predict not equal\n" 
378           << "   weighted: " << mdw.predict(z) << "\n"
379           << "   non-weighted: " << md.predict(z)
380           << std::endl;
381  }
382
383  if (md.standard_error2(z) != mdw.standard_error2(z)){
384    ok = false;
385    *error << "Error: standard_error2 not equal\n" 
386           << "   weighted: " << mdw.standard_error2(z) << "\n"
387           << "   non-weighted: " << md.standard_error2(z)
388           << std::endl;
389  }
390  if (fabs(md.prediction_error2(z)-mdw.prediction_error2(z,1.0))>10e-7){
391    ok = false;
392    *error << "Error: prediction_error2 not equal\n" 
393           << "   weighted: " << mdw.prediction_error2(z,1.0) << "\n"
394           << "   non-weighted: " << md.prediction_error2(z)
395           << std::endl;
396  }
397
398  w(0)=1.0;  w(1)=1.0;  w(2)=0.5;  w(3)=0.2;  w(4)=0.2;
399  mdw.fit(data,y,w);
400  double predict = mdw.predict(z);
401  double prediction_error2 = mdw.prediction_error2(z, 1.0);
402  double s2 = mdw.s2(1.0);
403  double standard_error2 = mdw.standard_error2(z);
404
405  w.scale(2);
406  mdw.fit(data,y,w);
407  if (fabs(mdw.predict(z)-predict)>10e-10){
408    ok = false;
409    *error << "Error: predict not equal after rescaling.\n";
410    *error << "   predict = " << predict << " and after doubling weights.\n";
411    *error << "   predict = " << mdw.predict(z) << "\n";
412  }
413  if (fabs(mdw.prediction_error2(z,2)-prediction_error2)>10e-7){
414    ok = false;
415    *error << "Error: prediction_error2 not equal after rescaling.\n";
416    *error << "       predict_error2 = " << prediction_error2
417           << " and after doubling weights.\n";
418    *error << "       predict_error2 = " << mdw.prediction_error2(z,2) << "\n";
419  }
420  if (fabs(mdw.s2(2)-s2)>10e-10){
421    ok = false;
422    *error << "Error: s2 not equal after rescaling.\n";
423    *error << "       s2 = " << s2 << " and after doubling weights.\n";
424    *error << "       s2 = " << mdw.s2(2) << "\n";
425  }
426  if (fabs(mdw.standard_error2(z)-standard_error2)>10e-7){
427    ok = false;
428    *error << "Error: standard_error2 not equal after rescaling.\n";
429    *error << " standard_error2 = " << standard_error2
430           << " and after doubling weights.\n";
431    *error << " standard_error2 = " << mdw.standard_error2(z) << "\n";
432  }
433
434  return ok;
435}
436
437
438bool Local_test(regression::OneDimensionalWeighted& r, 
439                regression::Kernel& k)
440{
441  regression::Local rl(r,k);
442  for (size_t i=0; i<1000; i++){
443    rl.add(i, 10);
444  }
445
446  rl.fit(10, 100);
447
448  utility::vector y = rl.y_predicted();
449  for (size_t i=0; i<y.size(); i++) 
450    if (y(i)!=10.0){
451      return false;
452    }
453  return true;
454}
Note: See TracBrowser for help on using the repository browser.