source: trunk/c++_tools/classifier/SubsetGenerator.cc @ 621

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

fixes #108 SubsetGenerator? with featureselection is now supported for MatrixLookup? MatrixLookupWeighted?, and KernelLookup? built on a MatrixLookup? (not KernelLookup? built on two MatrixLookups? see #122)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date ID
File size: 9.5 KB
Line 
1// $Id$
2
3
4#include <c++_tools/classifier/SubsetGenerator.h>
5#include <c++_tools/classifier/DataLookup2D.h>
6#include <c++_tools/classifier/FeatureSelector.h>
7#include <c++_tools/classifier/KernelLookup.h>
8#include <c++_tools/classifier/MatrixLookup.h>
9#include <c++_tools/classifier/MatrixLookupWeighted.h>
10#include <c++_tools/classifier/Target.h>
11
12#include <algorithm>
13#include <cassert>
14#include <utility>
15#include <typeinfo>
16#include <vector>
17
18namespace theplu {
19namespace classifier { 
20
21  SubsetGenerator::SubsetGenerator(const Sampler& sampler, 
22                                   const DataLookup2D& data)
23    : f_selector_(NULL), sampler_(sampler), state_(0), weighted_(false)
24  { 
25    assert(target().size()==data.columns());
26
27    training_data_.reserve(sampler_.size());
28    training_weight_.reserve(sampler_.size());
29    validation_data_.reserve(sampler_.size());
30    validation_weight_.reserve(sampler_.size());
31    for (size_t i=0; i<sampler_.size(); ++i){
32      // Dynamically allocated. Must be deleted in destructor.
33      training_data_.push_back(data.training_data(sampler.training_index(i)));
34      training_weight_.push_back
35        (new MatrixLookup(training_data_.back()->rows(),
36                          training_data_.back()->columns(),1));
37      validation_data_.push_back(data.validation_data(sampler.training_index(i),
38                                                      sampler.validation_index(i)));
39      validation_weight_.push_back
40        (new MatrixLookup(validation_data_.back()->rows(),
41                          validation_data_.back()->columns(),1));
42
43
44      training_target_.push_back(Target(target(),sampler.training_index(i)));
45      validation_target_.push_back(Target(target(),
46                                          sampler.validation_index(i)));
47      assert(training_data_.size()==i+1);
48      assert(training_weight_.size()==i+1);
49      assert(training_target_.size()==i+1);
50      assert(validation_data_.size()==i+1);
51      assert(validation_weight_.size()==i+1);
52      assert(validation_target_.size()==i+1);
53    }
54
55    // No feature selection, hence features same for all partitions
56    // and can be stored in features_[0]
57    features_.resize(1);
58    features_[0].reserve(data.rows());
59    for (size_t i=0; i<data.rows(); ++i)
60      features_[0].push_back(i);
61
62    assert(training_data_.size()==size());
63    assert(training_weight_.size()==size());
64    assert(training_target_.size()==size());
65    assert(validation_data_.size()==size());
66    assert(validation_weight_.size()==size());
67    assert(validation_target_.size()==size());
68  }
69
70  SubsetGenerator::SubsetGenerator(const Sampler& sampler, 
71                                   const DataLookup2D& data,
72                                   const MatrixLookup& weight)
73    : sampler_(sampler), state_(0), weighted_(true)
74  { 
75    assert(target().size()==data.columns());
76    training_data_.reserve(size());
77    training_weight_.reserve(size());
78    validation_data_.reserve(size());
79    validation_weight_.reserve(size());
80    for (reset(); more(); next()){
81     
82      // Dynamically allocated. Must be deleted in destructor.
83      training_data_.push_back(data.training_data(training_index()));
84      validation_data_.push_back(data.validation_data(training_index(), 
85                                                    validation_index()));
86      training_weight_.push_back(weight.training_data(training_index()));
87      validation_weight_.push_back(weight.validation_data(training_index(), 
88                                                          validation_index()));
89
90
91      training_target_.push_back(Target(target(),training_index()));
92      validation_target_.push_back(Target(target(),validation_index()));
93    }
94    // No feature selection, hence features same for all partitions
95    // and can be stored in features_[0]
96    features_.resize(1);
97    features_[0].reserve(data.rows());
98    for (size_t i=0; i<data.rows(); ++i)
99      features_[0].push_back(i);
100
101    assert(training_data_.size()==size());
102    assert(training_weight_.size()==size());
103    assert(training_target_.size()==size());
104    assert(validation_data_.size()==size());
105    assert(validation_weight_.size()==size());
106    assert(validation_target_.size()==size());
107    reset();
108  }
109
110
111  SubsetGenerator::SubsetGenerator(const Sampler& sampler, 
112                                   const DataLookup2D& data, 
113                                   FeatureSelector& fs)
114    : f_selector_(&fs), sampler_(sampler), state_(0), weighted_(false)
115  { 
116    assert(target().size()==data.columns());
117
118    features_.reserve(size());
119    training_data_.reserve(size());
120    training_weight_.reserve(size());
121    validation_data_.reserve(size());
122    validation_weight_.reserve(size());
123
124
125    // Taking care of three different case.
126    // We start with the case of MatrixLookup
127    const MatrixLookup* ml = dynamic_cast<const MatrixLookup*>(&data);
128    if (ml){
129      for (reset(); more(); next()){
130     
131        // training data with no feature selection
132        const MatrixLookup* train_data_all_feat = 
133          ml->training_data(training_index());
134        // use these data to create feature selection
135        f_selector_->update(*train_data_all_feat, training_target());
136        // get features
137        features_.push_back(f_selector_->features());
138        delete train_data_all_feat;
139       
140        // Dynamically allocated. Must be deleted in destructor.
141        training_data_.push_back(ml->training_data(features_.back(), 
142                                                    training_index()));
143        training_weight_.push_back
144          (new MatrixLookup(training_data_.back()->rows(),
145                            training_data_.back()->columns(),1));
146        validation_data_.push_back(ml->validation_data(features_.back(),
147                                                        training_index(), 
148                                                        validation_index()));
149        validation_weight_.push_back
150          (new MatrixLookup(validation_data_.back()->rows(),
151                            validation_data_.back()->columns(),1));
152       
153
154        training_target_.push_back(Target(target(),training_index()));
155        validation_target_.push_back(Target(target(),validation_index()));
156      }
157    }
158    else {
159      // Second the case of MatrixLookupWeighted
160      const MatrixLookupWeighted* ml = 
161        dynamic_cast<const MatrixLookupWeighted*>(&data);
162      if (ml){
163        for (reset(); more(); next()){
164     
165          // training data with no feature selection
166          const MatrixLookupWeighted* train_data_all_feat = 
167            ml->training_data(training_index());
168          // use these data to create feature selection
169          f_selector_->update(*train_data_all_feat, training_target());
170          // get features
171          features_.push_back(f_selector_->features());
172          delete train_data_all_feat;
173         
174          // Dynamically allocated. Must be deleted in destructor.
175          training_data_.push_back(ml->training_data(features_.back(), 
176                                                     training_index()));
177          training_weight_.push_back
178            (new MatrixLookup(training_data_.back()->rows(),
179                              training_data_.back()->columns(),1));
180          validation_data_.push_back(ml->validation_data(features_.back(),
181                                                         training_index(), 
182                                                         validation_index()));
183          validation_weight_.push_back
184            (new MatrixLookup(validation_data_.back()->rows(),
185                              validation_data_.back()->columns(),1));
186         
187         
188          training_target_.push_back(Target(target(),training_index()));
189          validation_target_.push_back(Target(target(),validation_index()));
190        }
191      }
192      else {
193        // Third the case of MatrixLookupWeighted
194        const KernelLookup* kernel =  dynamic_cast<const KernelLookup*>(&data);
195        if (kernel){
196          for (reset(); more(); next()){
197            const KernelLookup* kl=NULL;
198            if (kernel->weighted()){
199              std::cerr << "Feature selection with weighted Kernel not " 
200                        << "implemented.\nPlease see http://lev.thep.lu."
201                        << "se/trac/c++_tools/ticket/116\n";
202              exit(-1);
203            }
204            else {
205              const MatrixLookup* matrix = kernel->data();
206              const MatrixLookup* training_matrix = 
207                matrix->training_data(training_index());
208              f_selector_->update(*training_matrix, training_target());
209              features_.push_back(f_selector_->features());
210              kl = kernel->selected(features_.back());
211              delete matrix;
212              delete training_matrix;
213            }
214           
215            // Dynamically allocated. Must be deleted in destructor.
216            training_data_.push_back(kl->training_data(features_.back(), 
217                                                       training_index()));
218            training_weight_.push_back
219              (new MatrixLookup(training_data_.back()->rows(),
220                                training_data_.back()->columns(),1));
221            validation_data_.push_back(kl->validation_data(features_.back(),
222                                                           training_index(), 
223                                                           validation_index()));
224            validation_weight_.push_back
225              (new MatrixLookup(validation_data_.back()->rows(),
226                                validation_data_.back()->columns(),1));
227           
228           
229            training_target_.push_back(Target(target(),training_index()));
230            validation_target_.push_back(Target(target(),validation_index()));
231            if (kl)
232              delete kl;
233          }
234        }
235        else {
236        std::cerr << "Sorry, your type of DataLookup2D " << typeid(data).name() 
237                  << "is not supported in FeatureSelection\n";
238        exit(-1);
239        }
240      }
241    }
242    assert(training_data_.size()==size());
243    assert(training_weight_.size()==size());
244    assert(training_target_.size()==size());
245    assert(validation_data_.size()==size());
246    assert(validation_weight_.size()==size());
247    assert(validation_target_.size()==size());
248    reset();
249  }
250
251
252  SubsetGenerator::~SubsetGenerator()
253  {
254    assert(training_data_.size()==validation_data_.size());
255    for (size_t i=0; i<training_data_.size(); i++) 
256      delete training_data_[i];
257    for (size_t i=0; i<validation_data_.size(); i++) 
258      delete validation_data_[i];
259    for (size_t i=0; i<training_weight_.size(); i++) 
260      delete training_weight_[i];
261    for (size_t i=0; i<validation_weight_.size(); i++) 
262      delete validation_weight_[i];
263  }
264
265}} // of namespace classifier and namespace theplu
Note: See TracBrowser for help on using the repository browser.