~ubuntu-branches/ubuntu/wily/openms/wily

« back to all changes in this revision

Viewing changes to include/OpenMS/ANALYSIS/SVM/SVMWrapper.h

  • Committer: Package Import Robot
  • Author(s): Filippo Rusconi
  • Date: 2013-12-20 11:30:16 UTC
  • mfrom: (5.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20131220113016-wre5g9bteeheq6he
Tags: 1.11.1-3
* remove version number from libbost development package names;
* ensure that AUTHORS is correctly shipped in all packages.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// -*- mode: C++; tab-width: 2; -*-
2
 
// vi: set ts=2:
3
 
//
4
 
// --------------------------------------------------------------------------
5
 
//                   OpenMS Mass Spectrometry Framework
6
 
// --------------------------------------------------------------------------
7
 
//  Copyright (C) 2003-2011 -- Oliver Kohlbacher, Knut Reinert
8
 
//
9
 
//  This library is free software; you can redistribute it and/or
10
 
//  modify it under the terms of the GNU Lesser General Public
11
 
//  License as published by the Free Software Foundation; either
12
 
//  version 2.1 of the License, or (at your option) any later version.
13
 
// 
14
 
//  This library is distributed in the hope that it will be useful,
15
 
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 
//  Lesser General Public License for more details.
18
 
//
19
 
//  You should have received a copy of the GNU Lesser General Public
20
 
//  License along with this library; if not, write to the Free Software
21
 
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
1
// --------------------------------------------------------------------------
 
2
//                   OpenMS -- Open-Source Mass Spectrometry
 
3
// --------------------------------------------------------------------------
 
4
// Copyright The OpenMS Team -- Eberhard Karls University Tuebingen,
 
5
// ETH Zurich, and Freie Universitaet Berlin 2002-2013.
 
6
//
 
7
// This software is released under a three-clause BSD license:
 
8
//  * Redistributions of source code must retain the above copyright
 
9
//    notice, this list of conditions and the following disclaimer.
 
10
//  * Redistributions in binary form must reproduce the above copyright
 
11
//    notice, this list of conditions and the following disclaimer in the
 
12
//    documentation and/or other materials provided with the distribution.
 
13
//  * Neither the name of any author or any participating institution
 
14
//    may be used to endorse or promote products derived from this software
 
15
//    without specific prior written permission.
 
16
// For a full list of authors, refer to the file AUTHORS.
 
17
// --------------------------------------------------------------------------
 
18
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
19
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
20
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
21
// ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING
 
22
// INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
23
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
24
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 
25
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 
26
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 
27
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 
28
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22
29
//
23
30
// --------------------------------------------------------------------------
24
31
// $Maintainer: Sandro Andreotti $
43
50
#include <iostream>
44
51
#include <fstream>
45
52
 
46
 
namespace OpenMS 
 
53
namespace OpenMS
47
54
{
48
 
        
49
 
        /// Data structure used in SVMWrapper
50
 
        struct SVMData
51
 
        {
52
 
                std::vector< std::vector< std::pair<Int, DoubleReal> > > sequences;
53
 
                std::vector< DoubleReal > labels;
54
 
                
55
 
                SVMData()
56
 
                        : sequences(std::vector< std::vector< std::pair<Int, DoubleReal> > >()),
57
 
                                labels(std::vector< DoubleReal >())
58
 
                {
59
 
                };
60
 
                
61
 
                SVMData(std::vector< std::vector< std::pair<Int, DoubleReal> > >& seqs, std::vector< DoubleReal >& lbls)
62
 
                        : sequences(seqs),
63
 
                                labels(lbls)
64
 
                {
65
 
                };
66
 
                
67
 
                bool operator == (const SVMData& rhs) const
68
 
                {
69
 
                        return sequences == rhs.sequences
70
 
                                && labels == rhs.labels;
71
 
                }
72
 
                
73
 
                bool store(const String& filename) const
74
 
                {
75
 
                        std::ofstream output_file(filename.c_str());
76
 
 
77
 
                        // checking if file is writable
78
 
                        if (!File::writable(filename) || sequences.size() != labels.size())
79
 
                        {
80
 
                                return false;
81
 
                        }
82
 
                                
83
 
                        // writing feature vectors              
84
 
                        for (Size i = 0; i < sequences.size(); i++)
85
 
                        {
86
 
                                output_file << labels[i] << " ";
87
 
                                for (Size j = 0; j < sequences[i].size(); ++j)
88
 
                                {
89
 
                                        output_file << sequences[i][j].second << ":" << sequences[i][j].first << " " ;                                  
90
 
                                }
91
 
                                output_file << std::endl;
92
 
                        }
93
 
                        output_file.flush();
94
 
                        output_file.close();
95
 
                        std::cout.flush();
96
 
                        return true;
97
 
                }
98
 
                
99
 
                bool load(const String& filename)
100
 
                {
101
 
                        Size counter = 0;
102
 
                        std::vector<String> parts;
103
 
                        std::vector<String> temp_parts;
104
 
                        
105
 
                        if (!File::exists(filename))
106
 
                        {
107
 
                                return false;
108
 
                        }
109
 
                        if (!File::readable(filename))
110
 
                        {
111
 
                                return false;
112
 
                        }
113
 
            if (File::empty(filename))
114
 
            {
115
 
                                return false;
116
 
            }           
117
 
        
118
 
                        TextFile text_file(filename.c_str(), true);
119
 
            TextFile::iterator it;
120
 
        
121
 
                        it = text_file.begin();
122
 
                        
123
 
                        sequences.resize(text_file.size(), std::vector< std::pair<Int, DoubleReal> >());
124
 
                        labels.resize(text_file.size(), 0.);
125
 
                        while(counter < text_file.size()&& it != text_file.end())
126
 
                        {
127
 
                                it->split(' ', parts);
128
 
                                labels[counter] = parts[0].trim().toFloat();            
129
 
                                sequences[counter].resize(parts.size(), std::pair<Int, DoubleReal>());                  
130
 
                                for (Size j = 1; j < parts.size(); ++j)
131
 
                                {
132
 
                                        parts[j].split(':', temp_parts);
133
 
                                        if (temp_parts.size() < 2)
134
 
                                        {
135
 
                                                return false;
136
 
                                        }
137
 
                                        sequences[counter][j - 1].second = temp_parts[0].trim().toFloat();
138
 
                                        sequences[counter][j - 1].first = temp_parts[1].trim().toInt();
139
 
                                }
140
 
                                ++counter;
141
 
                                ++it;
142
 
                        }
143
 
                        return true;                    
144
 
                }
145
 
                                                        
146
 
        };
 
55
 
 
56
  /// Data structure used in SVMWrapper
 
57
  struct SVMData
 
58
  {
 
59
    std::vector<std::vector<std::pair<Int, DoubleReal> > > sequences;
 
60
    std::vector<DoubleReal> labels;
 
61
 
 
62
    SVMData() :
 
63
      sequences(std::vector<std::vector<std::pair<Int, DoubleReal> > >()),
 
64
      labels(std::vector<DoubleReal>())
 
65
    {
 
66
    }
 
67
 
 
68
    SVMData(std::vector<std::vector<std::pair<Int, DoubleReal> > > & seqs, std::vector<DoubleReal> & lbls) :
 
69
      sequences(seqs),
 
70
      labels(lbls)
 
71
    {
 
72
    }
 
73
 
 
74
    bool operator==(const SVMData & rhs) const
 
75
    {
 
76
      return sequences == rhs.sequences
 
77
             && labels == rhs.labels;
 
78
    }
 
79
 
 
80
    bool store(const String & filename) const
 
81
    {
 
82
      std::ofstream output_file(filename.c_str());
 
83
 
 
84
      // checking if file is writable
 
85
      if (!File::writable(filename) || sequences.size() != labels.size())
 
86
      {
 
87
        return false;
 
88
      }
 
89
 
 
90
      // writing feature vectors
 
91
      for (Size i = 0; i < sequences.size(); i++)
 
92
      {
 
93
        output_file << labels[i] << " ";
 
94
        for (Size j = 0; j < sequences[i].size(); ++j)
 
95
        {
 
96
          output_file << sequences[i][j].second << ":" << sequences[i][j].first << " ";
 
97
        }
 
98
        output_file << std::endl;
 
99
      }
 
100
      output_file.flush();
 
101
      output_file.close();
 
102
      std::cout.flush();
 
103
      return true;
 
104
    }
 
105
 
 
106
    bool load(const String & filename)
 
107
    {
 
108
      Size counter = 0;
 
109
      std::vector<String> parts;
 
110
      std::vector<String> temp_parts;
 
111
 
 
112
      if (!File::exists(filename))
 
113
      {
 
114
        return false;
 
115
      }
 
116
      if (!File::readable(filename))
 
117
      {
 
118
        return false;
 
119
      }
 
120
      if (File::empty(filename))
 
121
      {
 
122
        return false;
 
123
      }
 
124
 
 
125
      TextFile text_file(filename.c_str(), true);
 
126
      TextFile::iterator it;
 
127
 
 
128
      it = text_file.begin();
 
129
 
 
130
      sequences.resize(text_file.size(), std::vector<std::pair<Int, DoubleReal> >());
 
131
      labels.resize(text_file.size(), 0.);
 
132
      while (counter < text_file.size() && it != text_file.end())
 
133
      {
 
134
        it->split(' ', parts);
 
135
        labels[counter] = parts[0].trim().toFloat();
 
136
        sequences[counter].resize(parts.size(), std::pair<Int, DoubleReal>());
 
137
        for (Size j = 1; j < parts.size(); ++j)
 
138
        {
 
139
          parts[j].split(':', temp_parts);
 
140
          if (temp_parts.size() < 2)
 
141
          {
 
142
            return false;
 
143
          }
 
144
          sequences[counter][j - 1].second = temp_parts[0].trim().toFloat();
 
145
          sequences[counter][j - 1].first = temp_parts[1].trim().toInt();
 
146
        }
 
147
        ++counter;
 
148
        ++it;
 
149
      }
 
150
      return true;
 
151
    }
 
152
 
 
153
  };
147
154
 
148
155
  /**
149
156
    @brief Serves as a wrapper for the libsvm
150
 
    
 
157
 
151
158
    This class can be used for svm predictions. You can either perform classification or regression and
152
 
                choose certain kernel fuctions and additional parameters. Furthermore the models can be saved and 
153
 
                loaded and we support also a new kernel function that was specially designed for learning with
154
 
                small sequences of different lengths.
 
159
        choose certain kernel fuctions and additional parameters. Furthermore the models can be saved and
 
160
        loaded and we support also a new kernel function that was specially designed for learning with
 
161
        small sequences of different lengths.
155
162
  */
156
 
  class OPENMS_DLLAPI SVMWrapper
157
 
    : public ProgressLogger
158
 
        {
159
 
         public:
160
 
        
161
 
                  /**
162
 
                    @brief      Parameters for the svm to be set from outside
163
 
                
164
 
                                This type is used to specify the kind of parameter that
165
 
                                is to be set or retrieved by the set/getParameter methods.
166
 
                        */
167
 
                        enum SVM_parameter_type
168
 
                        {
169
 
                                SVM_TYPE,                               ///< the svm type cab be NU_SVR or EPSILON_SVR
170
 
                                KERNEL_TYPE,            ///< the kernel type
171
 
                                DEGREE,                                 ///< the degree for the polynomial- kernel
172
 
                                C,                                                      ///< the C parameter of the svm
173
 
                                NU,                                                     ///< the nu parameter for nu-SVR
174
 
                                P,                                                      ///< the epsilon parameter for epsilon-SVR
175
 
                                GAMMA,                                  ///< the gamma parameter of the POLY, RBF and SIGMOID kernel
176
 
                                PROBABILITY,            ///<
177
 
                                SIGMA,                                  ///<
178
 
                                BORDER_LENGTH           ///<
179
 
                        };
180
 
                        
181
 
                        /// Kernel type
182
 
                        enum SVM_kernel_type
183
 
                        {
184
 
                                OLIGO = 19,
185
 
                                OLIGO_COMBINED
186
 
                        };
187
 
        
188
 
                        /// standard constructor
189
 
            SVMWrapper();
190
 
 
191
 
                        /// destructor  
192
 
            virtual ~SVMWrapper();
193
 
        
194
 
                  /**
195
 
                    @brief You can set the parameters of the svm: 
196
 
             
197
 
                 KERNEL_TYPE: can be LINEAR                              for the linear kernel
198
 
                                     RBF                                 for the rbf kernel
199
 
                                     POLY                    for the polynomial kernel
200
 
                                     SIGMOID                             for the sigmoid kernel 
201
 
                 DEGREE:      the degree for the polynomial- kernel and the
202
 
                              locality- improved kernel
203
 
             
204
 
                 C:            the C parameter of the svm            
205
 
                        */           
206
 
            void setParameter(SVM_parameter_type type, Int value);
207
 
        
208
 
                  /**
209
 
                    @brief sets the double parameters of the svm
210
 
                    
211
 
                        */
212
 
            void setParameter(SVM_parameter_type type, DoubleReal value);
213
 
                
214
 
                  /**
215
 
                    @brief      trains the svm 
216
 
 
217
 
              The svm is trained with the data stored in the 'svm_problem' structure.
218
 
                        */
219
 
            Int train(struct svm_problem* problem);
220
 
        
221
 
                  /**
222
 
                    @brief      trains the svm 
223
 
 
224
 
              The svm is trained with the data stored in the 'SVMData' structure.
225
 
                        */
226
 
                        Int train(SVMData& problem);
227
 
 
228
 
                  /**
229
 
                    @brief      saves the svm model 
230
 
 
231
 
              The model of the trained svm is saved into 'modelFilename'. Throws an exception if 
232
 
              the model cannot be saved.
233
 
 
234
 
                                @exception Exception::UnableToCreateFile
235
 
                        */
236
 
            void saveModel(std::string modelFilename) const;
237
 
        
238
 
                  /**
239
 
                    @brief loads the model
240
 
 
241
 
              The svm- model is loaded. After this, the svm is ready for 
242
 
              prediction.
243
 
                  */
244
 
            void loadModel(std::string modelFilename);
245
 
        
246
 
                  /**
247
 
                    @brief predicts the labels using the trained model
248
 
                    
249
 
                 The prediction process is started and the results are stored in 'predicted_labels'.
250
 
 
251
 
                  */
252
 
            void predict(struct svm_problem* problem, std::vector<DoubleReal>& predicted_labels);
253
 
 
254
 
                  /**
255
 
                    @brief predicts the labels using the trained model
256
 
                    
257
 
                 The prediction process is started and the results are stored in 'predicted_labels'.
258
 
 
259
 
                  */
260
 
                        void predict(const SVMData& problem, std::vector<DoubleReal>& results);
261
 
 
262
 
                  /**
263
 
                    @brief You can get the actual int- parameters of the svm
264
 
 
265
 
                 KERNEL_TYPE: can be LINEAR                              for the linear kernel
266
 
                                     RBF                                 for the rbf kernel
267
 
                                     POLY                     for the polynomial kernel
268
 
                                     SIGMOID                             for the sigmoid kernel 
269
 
             
270
 
                 DEGREE:       the degree for the polynomial- kernel and the
271
 
                               locality- improved kernel
272
 
             
273
 
                 SVM_TYPE:     the SVm type of the svm: can be NU_SVR or EPSILON_SVR
274
 
                  */         
275
 
            Int getIntParameter(SVM_parameter_type type);
276
 
        
277
 
                  /**
278
 
                    @brief You can get the actual double- parameters of the svm
279
 
                    
280
 
                    C:            the C parameter of the svm
281
 
                    P:                        the P parameter of the svm (sets the epsilon in
282
 
                                                                                                  epsilon-svr)
283
 
                        NU:           the nu parameter in nu-SVR
284
 
                        GAMMA:                          for POLY, RBF and SIGMOID                   
285
 
                  */
286
 
            DoubleReal getDoubleParameter(SVM_parameter_type type); 
287
 
 
288
 
                  /**
289
 
                    @brief You can create 'number' equally sized random partitions
290
 
                    
291
 
                    This function creates 'number' equally sized random partitions and stores them in 'partitions'. 
292
 
                    
293
 
                  */
294
 
                        static void createRandomPartitions(svm_problem* problem, Size number, std::vector<svm_problem*>& partitions);
295
 
        
296
 
                  /**
297
 
                    @brief You can create 'number' equally sized random partitions
298
 
                    
299
 
                    This function creates 'number' equally sized random partitions and stores them in 'partitions'. 
300
 
                    
301
 
                  */
302
 
                        static void createRandomPartitions(const SVMData&                                 problem,
303
 
                                                                                                                                                                Size                                                              number,
304
 
                                                                                                                                                                std::vector<SVMData>&           problems);
305
 
                  /**
306
 
                    @brief You can merge partitions excuding the partition with index 'except' 
307
 
                    
308
 
                  */
309
 
            static svm_problem* mergePartitions(const std::vector<svm_problem*>& problems, Size except);
310
 
                                                                                                                                                                        
311
 
                  /**
312
 
                    @brief You can merge partitions excuding the partition with index 'except' 
313
 
                    
314
 
                  */
315
 
                        static void mergePartitions(const std::vector<SVMData>& problems,
316
 
                                                                                                                                  Size                                                                                    except,
317
 
                                                                                                                                        SVMData&                                                                                merged_problem);
318
 
 
319
 
                  /**
320
 
                    @brief predicts the labels using the trained model
321
 
                    
322
 
                 The prediction process is started and the results are stored in 'predicted_rts'.
323
 
 
324
 
                  */
325
 
            void predict(const std::vector<svm_node*>& vectors, std::vector<DoubleReal>& predicted_rts);
326
 
        
327
 
                  /**
328
 
                    @brief Stores the stored labels of the encoded SVM data at 'labels' 
329
 
                    
330
 
                  */
331
 
                        static void getLabels(svm_problem* problem, std::vector<DoubleReal>& labels);
332
 
                                                                                                                                                                        
333
 
                  /**
334
 
                    @brief Performs a CV for the data given by 'problem'
335
 
                    
336
 
                  */
337
 
      DoubleReal performCrossValidation(svm_problem*                                                                                                                          problem_ul,
338
 
                                                                                                            const SVMData&                                              problem_l,
339
 
                                                                                                const bool                                        is_labeled,
340
 
                                                                                                                                                                const   std::map<SVM_parameter_type, DoubleReal>&   start_values_map,
341
 
                                                                                                                                                                const   std::map<SVM_parameter_type, DoubleReal>&   step_sizes_map,
342
 
                                                                                                                                                                const   std::map<SVM_parameter_type, DoubleReal>&   end_values_map,
343
 
                                                                                                                                                                Size                                                                                                                                                        number_of_partitions,
344
 
                                                                                                                                                                Size                                                                                                                                                          number_of_runs,
345
 
                                                                                                                                                                std::map<SVM_parameter_type, DoubleReal>&             best_parameters,
346
 
                                                                                                                                                                bool                                                                                                                                                                                    additive_step_sizes = true,
347
 
                                                                                                                                                                bool                                                                                                                                                                            output = false,
348
 
                                                                                                                                                                String                                                                                                                                                                          performances_file_name = "performances.txt",
349
 
                                                                                                                                                                bool                                                                                                                                                                                    mcc_as_performance_measure = false);
350
 
 
351
 
      
352
 
      /**
353
 
                    @brief Returns the probability parameter sigma of the fitted laplace model.               
354
 
                    
355
 
                    The libsvm is used to fit a laplace model to the prediction values by performing
356
 
                    an internal cv using the training set if setParameter(PROBABILITY, 1) was invoked
357
 
                    before using train. Look for your libsvm documentation for more details.
358
 
                    The model parameter sigma is returned by this method.       If no model was fitted during 
359
 
                    training zero is returned. 
360
 
                  */
361
 
                        DoubleReal getSVRProbability();                                                                                                                                                                                         
362
 
 
363
 
      /**
364
 
                                @brief returns the value of the oligo kernel for sequences 'x' and 'y'
365
 
 
366
 
                This function computes the kernel value of the oligo kernel,
367
 
                                        which was introduced by Meinicke et al. in 2004. 'x' and
368
 
                                        'y' are encoded by encodeOligo and 'gauss_table' has to be 
369
 
                                        constructed by calculateGaussTable. 
370
 
                                        
371
 
                                        'max_distance' can be used to speed up the computation 
372
 
                                        even further by restricting the maximum distance between a k_mer at
373
 
                                        position i in sequence 'x' and a k_mer at position j 
374
 
                                        in sequence 'y'. If i - j > 'max_distance' the value is not
375
 
                                        added to the kernel value. This approximation is switched
376
 
                                        off by default (max_distance < 0).
377
 
      */
378
 
      static DoubleReal kernelOligo(const std::vector< std::pair<int, double> >&    x, 
379
 
                                                                                                                                                const std::vector< std::pair<int, double> >&    y,
380
 
                                                                                                                                                const std::vector<double>&                          gauss_table,
381
 
                                                                                                                                                int                                                                                                             max_distance = -1);
382
 
                                                                                                                                
383
 
                  /**
384
 
                    @brief calculates the oligo kernel value for the encoded sequences 'x' and 'y'
385
 
                    
386
 
                    This kernel function calculates the oligo kernel value [Meinicke 04] for
387
 
                    the sequences 'x' and 'y' that had been encoded by the encodeOligoBorder... function
388
 
                    of the LibSVMEncoder class.                             
389
 
                  */
390
 
                        static DoubleReal kernelOligo(const svm_node*   x, const svm_node* y, const std::vector<DoubleReal>&    gauss_table, DoubleReal sigma_square = 0,       Size    max_distance = 50);
391
 
 
392
 
                  /**
393
 
                    @brief calculates the significance borders of the error model and stores them in 'sigmas'         
394
 
                    
395
 
                  */
396
 
                        void getSignificanceBorders(svm_problem* data, std::pair<DoubleReal, DoubleReal>& borders, DoubleReal confidence = 0.95, Size number_of_runs = 5, Size number_of_partitions = 5, DoubleReal step_size = 0.01, Size max_iterations = 1000000);
397
 
 
398
 
                  /**
399
 
                    @brief calculates the significance borders of the error model and stores them in 'sigmas'         
400
 
                    
401
 
                  */
402
 
                        void getSignificanceBorders(const SVMData& data, 
403
 
                                                                                                                                        std::pair<DoubleReal, DoubleReal>& sigmas,
404
 
                                                                                                                                        DoubleReal confidence = 0.95,
405
 
                                                                                                                                        Size number_of_runs = 5,
406
 
                                                                                                                                        Size number_of_partitions = 5,
407
 
                                                                                                                                        DoubleReal step_size = 0.01,
408
 
                                                                                                                                        Size max_iterations = 1000000);
409
 
 
410
 
                  /**
411
 
                    @brief calculates a p-value for a given data point using the model parameters
412
 
                    
413
 
                    Uses the model parameters to calculate the p-value for 'point' which has the data
414
 
                    entries: measured, predicted retention time.              
415
 
                    
416
 
                  */
417
 
                        DoubleReal getPValue(DoubleReal sigma1, DoubleReal sigma2, std::pair<DoubleReal, DoubleReal> point);
418
 
 
419
 
                  /**
420
 
                    @brief stores the prediction values for the encoded data in 'decision_values'
421
 
                    
422
 
                    This function can be used to get the prediction values of the data if a model 
423
 
                    is already trained by the train() method. For regression the result is the same
424
 
                    as for the method predict. For classification this function returns the distance from
425
 
                    the separating hyperplane. For multiclass classification the decision_values vector
426
 
                    will be empty. 
427
 
                    
428
 
                  */
429
 
                        void getDecisionValues(svm_problem* data, std::vector<DoubleReal>& decision_values);
430
 
 
431
 
                  /**
432
 
                    @brief Scales the data such that every coloumn is scaled to [-1, 1].
433
 
                    
434
 
                    Scales the x[][].value values of the svm_problem* structure. If the second 
435
 
                    parameter is omitted, the data is scaled to [-1, 1]. Otherwise the data is scaled to [0, max_scale_value]
436
 
                  */
437
 
                        void scaleData(svm_problem* data, Int max_scale_value = -1);
438
 
 
439
 
                        static void calculateGaussTable(Size border_length, DoubleReal sigma, std::vector<DoubleReal>&  gauss_table);
440
 
 
441
 
                  /**
442
 
                    @brief computes the kernel matrix using the actual svm parameters   and the given data
443
 
                    
444
 
                    This function can be used to compute a kernel matrix. 'problem1' and 'problem2'
445
 
                    are used together wit the oligo kernel function (could be extended if you 
446
 
                    want to use your own kernel functions).      
447
 
                    
448
 
                  */
449
 
                        svm_problem* computeKernelMatrix(svm_problem* problem1, svm_problem* problem2);
450
 
 
451
 
                  /**
452
 
                    @brief computes the kernel matrix using the actual svm parameters   and the given data
453
 
                    
454
 
                    This function can be used to compute a kernel matrix. 'problem1' and 'problem2'
455
 
                    are used together wit the oligo kernel function (could be extended if you 
456
 
                    want to use your own kernel functions).      
457
 
                    
458
 
                  */
459
 
                        svm_problem* computeKernelMatrix(const SVMData& problem1, const SVMData& problem2);
460
 
 
461
 
                  /**
462
 
                    @brief This is used for being able to perform predictions with non libsvm standard kernels                          
463
 
                    
464
 
                  */
465
 
                void setTrainingSample(svm_problem* training_sample);
466
 
                
467
 
                  /**
468
 
                    @brief This is used for being able to perform predictions with non libsvm standard kernels                          
469
 
                    
470
 
                  */
471
 
                        void setTrainingSample(SVMData& training_sample);
472
 
                                
473
 
                  /**
474
 
                    @brief This function fills probabilities with the probability estimates for the first class.
475
 
                                                        
476
 
                    The libSVM function svm_predict_probability is called to get probability estimates
477
 
                    for the positive class. Since this is only used for binary classification it is sufficient
478
 
                    for every test example to report the probability of the test example belonging to the positive
479
 
                    class. Probability estimates have to be turned on during training (svm.setParameter(PROBABILITY, 1)),
480
 
                    otherwise this method will fill the 'probabilities' vector with -1s.
481
 
                  */
482
 
                        void getSVCProbabilities(struct svm_problem* problem, std::vector<DoubleReal>& probabilities, std::vector<DoubleReal>& prediction_labels);
483
 
 
484
 
                  /**
485
 
                    @brief Sets weights for the classes in C_SVC (see libsvm documentation for further details)                         
486
 
                    
487
 
                  */
488
 
                        void setWeights(const std::vector<Int>& weight_labels, const std::vector<DoubleReal>& weights);
489
 
 
490
 
         private:
491
 
     /**
492
 
        @brief find next grid search parameter combination
493
 
 
494
 
        The current grid cell is given in @p actual_values.
495
 
        The result is returned in @p actual_values.
496
 
 
497
 
     */
498
 
      bool nextGrid_(const std::vector<DoubleReal>& start_values, 
499
 
                     const std::vector<DoubleReal>& step_sizes,
500
 
                     const std::vector<DoubleReal>& end_values,
501
 
                     const bool additive_step_sizes,
502
 
                     std::vector<DoubleReal>& actual_values);
503
 
 
504
 
                        Size getNumberOfEnclosedPoints_(DoubleReal m1, DoubleReal m2, const std::vector<std::pair<DoubleReal, DoubleReal> >&    points);
505
 
        
506
 
                  /**
507
 
                    @brief Initializes the svm with standard parameters
508
 
                    
509
 
                  */
510
 
            void initParameters_();
511
 
 
512
 
      /**
513
 
        @brief This function is passed to lib svm for output control
514
 
 
515
 
        The intention is to discard the output, as we don't need it.
516
 
 
517
 
      */
518
 
      static void printToVoid_(const char * /*s*/);
519
 
 
520
 
            svm_parameter*                                                                                              param_;                     // the parameters for the svm
521
 
            svm_model*                                                                                                  model_;                               // the learnt svm discriminant
522
 
            DoubleReal                                                                                                          sigma_;                                                         // for the oligo kernel (amount of positional smearing) 
523
 
                        std::vector<DoubleReal>                                                         sigmas_;                                                        // for the combined oligo kernel (amount of positional smearing) 
524
 
                        std::vector<DoubleReal>                                                         gauss_table_;                                   // lookup table for fast computation of the oligo kernel
525
 
                        std::vector<std::vector<DoubleReal>     > gauss_tables_;                                // lookup table for fast computation of the combined oligo kernel
526
 
                        Size                                                                                                                                    kernel_type_;                                   // the actual kernel type       
527
 
                        Size                                                                                                                                    border_length_;                         // the actual kernel type                               
528
 
                        svm_problem*                                                                                                    training_set_;                          // the training set
529
 
                        svm_problem*                                                                                                    training_problem_;              // the training set
530
 
                        SVMData                                                                                                                         training_data_;                         // the training set (different encoding)
531
 
 
532
 
        };
533
 
 
 
163
  class OPENMS_DLLAPI SVMWrapper :
 
164
    public ProgressLogger
 
165
  {
 
166
public:
 
167
 
 
168
    /**
 
169
      @brief    Parameters for the svm to be set from outside
 
170
 
 
171
          This type is used to specify the kind of parameter that
 
172
          is to be set or retrieved by the set/getParameter methods.
 
173
      */
 
174
    enum SVM_parameter_type
 
175
    {
 
176
      SVM_TYPE,                         ///< the svm type cab be NU_SVR or EPSILON_SVR
 
177
      KERNEL_TYPE,                  ///< the kernel type
 
178
      DEGREE,                           ///< the degree for the polynomial- kernel
 
179
      C,                                    ///< the C parameter of the svm
 
180
      NU,                                   ///< the nu parameter for nu-SVR
 
181
      P,                                    ///< the epsilon parameter for epsilon-SVR
 
182
      GAMMA,                            ///< the gamma parameter of the POLY, RBF and SIGMOID kernel
 
183
      PROBABILITY,                  ///<
 
184
      SIGMA,                            ///<
 
185
      BORDER_LENGTH                 ///<
 
186
    };
 
187
 
 
188
    /// Kernel type
 
189
    enum SVM_kernel_type
 
190
    {
 
191
      OLIGO = 19,
 
192
      OLIGO_COMBINED
 
193
    };
 
194
 
 
195
    /// standard constructor
 
196
    SVMWrapper();
 
197
 
 
198
    /// destructor
 
199
    virtual ~SVMWrapper();
 
200
 
 
201
    /**
 
202
      @brief You can set the parameters of the svm:
 
203
 
 
204
       KERNEL_TYPE: can be LINEAR                    for the linear kernel
 
205
                           RBF                       for the rbf kernel
 
206
                           POLY                    for the polynomial kernel
 
207
                           SIGMOID                       for the sigmoid kernel
 
208
       DEGREE:      the degree for the polynomial- kernel and the
 
209
                    locality- improved kernel
 
210
 
 
211
       C:            the C parameter of the svm
 
212
      */
 
213
    void setParameter(SVM_parameter_type type, Int value);
 
214
 
 
215
    /**
 
216
      @brief sets the double parameters of the svm
 
217
 
 
218
      */
 
219
    void setParameter(SVM_parameter_type type, DoubleReal value);
 
220
 
 
221
    /**
 
222
      @brief    trains the svm
 
223
 
 
224
    The svm is trained with the data stored in the 'svm_problem' structure.
 
225
      */
 
226
    Int train(struct svm_problem * problem);
 
227
 
 
228
    /**
 
229
      @brief    trains the svm
 
230
 
 
231
    The svm is trained with the data stored in the 'SVMData' structure.
 
232
      */
 
233
    Int train(SVMData & problem);
 
234
 
 
235
    /**
 
236
      @brief    saves the svm model
 
237
 
 
238
    The model of the trained svm is saved into 'modelFilename'. Throws an exception if
 
239
    the model cannot be saved.
 
240
 
 
241
          @exception Exception::UnableToCreateFile
 
242
      */
 
243
    void saveModel(std::string modelFilename) const;
 
244
 
 
245
    /**
 
246
      @brief loads the model
 
247
 
 
248
    The svm- model is loaded. After this, the svm is ready for
 
249
    prediction.
 
250
    */
 
251
    void loadModel(std::string modelFilename);
 
252
 
 
253
    /**
 
254
      @brief predicts the labels using the trained model
 
255
 
 
256
       The prediction process is started and the results are stored in 'predicted_labels'.
 
257
 
 
258
    */
 
259
    void predict(struct svm_problem * problem, std::vector<DoubleReal> & predicted_labels);
 
260
 
 
261
    /**
 
262
      @brief predicts the labels using the trained model
 
263
 
 
264
       The prediction process is started and the results are stored in 'predicted_labels'.
 
265
 
 
266
    */
 
267
    void predict(const SVMData & problem, std::vector<DoubleReal> & results);
 
268
 
 
269
    /**
 
270
      @brief You can get the actual int- parameters of the svm
 
271
 
 
272
       KERNEL_TYPE: can be LINEAR                    for the linear kernel
 
273
                           RBF                       for the rbf kernel
 
274
                           POLY                     for the polynomial kernel
 
275
                           SIGMOID                       for the sigmoid kernel
 
276
 
 
277
       DEGREE:       the degree for the polynomial- kernel and the
 
278
                     locality- improved kernel
 
279
 
 
280
       SVM_TYPE:     the SVm type of the svm: can be NU_SVR or EPSILON_SVR
 
281
    */
 
282
    Int getIntParameter(SVM_parameter_type type);
 
283
 
 
284
    /**
 
285
      @brief You can get the actual double- parameters of the svm
 
286
 
 
287
      C:            the C parameter of the svm
 
288
      P:                              the P parameter of the svm (sets the epsilon in
 
289
                                                epsilon-svr)
 
290
      NU:           the nu parameter in nu-SVR
 
291
      GAMMA:                            for POLY, RBF and SIGMOID
 
292
    */
 
293
    DoubleReal getDoubleParameter(SVM_parameter_type type);
 
294
 
 
295
    /**
 
296
      @brief You can create 'number' equally sized random partitions
 
297
 
 
298
      This function creates 'number' equally sized random partitions and stores them in 'partitions'.
 
299
 
 
300
    */
 
301
    static void createRandomPartitions(svm_problem * problem, Size number, std::vector<svm_problem *> & partitions);
 
302
 
 
303
    /**
 
304
      @brief You can create 'number' equally sized random partitions
 
305
 
 
306
      This function creates 'number' equally sized random partitions and stores them in 'partitions'.
 
307
 
 
308
    */
 
309
    static void createRandomPartitions(const SVMData & problem,
 
310
                                       Size                                  number,
 
311
                                       std::vector<SVMData> & problems);
 
312
    /**
 
313
      @brief You can merge partitions excuding the partition with index 'except'
 
314
 
 
315
    */
 
316
    static svm_problem * mergePartitions(const std::vector<svm_problem *> & problems, Size except);
 
317
 
 
318
    /**
 
319
      @brief You can merge partitions excuding the partition with index 'except'
 
320
 
 
321
    */
 
322
    static void mergePartitions(const std::vector<SVMData> & problems,
 
323
                                Size                                            except,
 
324
                                SVMData & merged_problem);
 
325
 
 
326
    /**
 
327
      @brief predicts the labels using the trained model
 
328
 
 
329
       The prediction process is started and the results are stored in 'predicted_rts'.
 
330
 
 
331
    */
 
332
    void predict(const std::vector<svm_node *> & vectors, std::vector<DoubleReal> & predicted_rts);
 
333
 
 
334
    /**
 
335
      @brief Stores the stored labels of the encoded SVM data at 'labels'
 
336
 
 
337
    */
 
338
    static void getLabels(svm_problem * problem, std::vector<DoubleReal> & labels);
 
339
 
 
340
    /**
 
341
      @brief Performs a CV for the data given by 'problem'
 
342
 
 
343
    */
 
344
    DoubleReal performCrossValidation(svm_problem * problem_ul,
 
345
                                      const SVMData & problem_l,
 
346
                                      const bool                                        is_labeled,
 
347
                                      const   std::map<SVM_parameter_type, DoubleReal> & start_values_map,
 
348
                                      const   std::map<SVM_parameter_type, DoubleReal> & step_sizes_map,
 
349
                                      const   std::map<SVM_parameter_type, DoubleReal> & end_values_map,
 
350
                                      Size                                                                                number_of_partitions,
 
351
                                      Size                                                                                  number_of_runs,
 
352
                                      std::map<SVM_parameter_type, DoubleReal> & best_parameters,
 
353
                                      bool                                                                                            additive_step_sizes = true,
 
354
                                      bool                                                                                        output = false,
 
355
                                      String                                                                                      performances_file_name = "performances.txt",
 
356
                                      bool                                                                                            mcc_as_performance_measure = false);
 
357
 
 
358
 
 
359
    /**
 
360
          @brief Returns the probability parameter sigma of the fitted laplace model.
 
361
 
 
362
          The libsvm is used to fit a laplace model to the prediction values by performing
 
363
          an internal cv using the training set if setParameter(PROBABILITY, 1) was invoked
 
364
          before using train. Look for your libsvm documentation for more details.
 
365
          The model parameter sigma is returned by this method. If no model was fitted during
 
366
          training zero is returned.
 
367
        */
 
368
    DoubleReal getSVRProbability();
 
369
 
 
370
    /**
 
371
              @brief returns the value of the oligo kernel for sequences 'x' and 'y'
 
372
 
 
373
          This function computes the kernel value of the oligo kernel,
 
374
                  which was introduced by Meinicke et al. in 2004. 'x' and
 
375
                  'y' are encoded by encodeOligo and 'gauss_table' has to be
 
376
                  constructed by calculateGaussTable.
 
377
 
 
378
                  'max_distance' can be used to speed up the computation
 
379
                  even further by restricting the maximum distance between a k_mer at
 
380
                  position i in sequence 'x' and a k_mer at position j
 
381
                  in sequence 'y'. If i - j > 'max_distance' the value is not
 
382
                  added to the kernel value. This approximation is switched
 
383
                  off by default (max_distance < 0).
 
384
    */
 
385
    static DoubleReal kernelOligo(const std::vector<std::pair<int, double> > & x,
 
386
                                  const std::vector<std::pair<int, double> > & y,
 
387
                                  const std::vector<double> & gauss_table,
 
388
                                  int                                                                     max_distance = -1);
 
389
 
 
390
    /**
 
391
      @brief calculates the oligo kernel value for the encoded sequences 'x' and 'y'
 
392
 
 
393
      This kernel function calculates the oligo kernel value [Meinicke 04] for
 
394
      the sequences 'x' and 'y' that had been encoded by the encodeOligoBorder... function
 
395
      of the LibSVMEncoder class.
 
396
    */
 
397
    static DoubleReal kernelOligo(const svm_node * x, const svm_node * y, const std::vector<DoubleReal> & gauss_table, DoubleReal sigma_square = 0, Size    max_distance = 50);
 
398
 
 
399
    /**
 
400
      @brief calculates the significance borders of the error model and stores them in 'sigmas'
 
401
 
 
402
    */
 
403
    void getSignificanceBorders(svm_problem * data, std::pair<DoubleReal, DoubleReal> & borders, DoubleReal confidence = 0.95, Size number_of_runs = 5, Size number_of_partitions = 5, DoubleReal step_size = 0.01, Size max_iterations = 1000000);
 
404
 
 
405
    /**
 
406
      @brief calculates the significance borders of the error model and stores them in 'sigmas'
 
407
 
 
408
    */
 
409
    void getSignificanceBorders(const SVMData & data,
 
410
                                std::pair<DoubleReal, DoubleReal> & sigmas,
 
411
                                DoubleReal confidence = 0.95,
 
412
                                Size number_of_runs = 5,
 
413
                                Size number_of_partitions = 5,
 
414
                                DoubleReal step_size = 0.01,
 
415
                                Size max_iterations = 1000000);
 
416
 
 
417
    /**
 
418
      @brief calculates a p-value for a given data point using the model parameters
 
419
 
 
420
      Uses the model parameters to calculate the p-value for 'point' which has the data
 
421
      entries: measured, predicted retention time.
 
422
 
 
423
    */
 
424
    DoubleReal getPValue(DoubleReal sigma1, DoubleReal sigma2, std::pair<DoubleReal, DoubleReal> point);
 
425
 
 
426
    /**
 
427
      @brief stores the prediction values for the encoded data in 'decision_values'
 
428
 
 
429
      This function can be used to get the prediction values of the data if a model
 
430
      is already trained by the train() method. For regression the result is the same
 
431
      as for the method predict. For classification this function returns the distance from
 
432
      the separating hyperplane. For multiclass classification the decision_values vector
 
433
      will be empty.
 
434
 
 
435
    */
 
436
    void getDecisionValues(svm_problem * data, std::vector<DoubleReal> & decision_values);
 
437
 
 
438
    /**
 
439
      @brief Scales the data such that every coloumn is scaled to [-1, 1].
 
440
 
 
441
      Scales the x[][].value values of the svm_problem* structure. If the second
 
442
      parameter is omitted, the data is scaled to [-1, 1]. Otherwise the data is scaled to [0, max_scale_value]
 
443
    */
 
444
    void scaleData(svm_problem * data, Int max_scale_value = -1);
 
445
 
 
446
    static void calculateGaussTable(Size border_length, DoubleReal sigma, std::vector<DoubleReal> & gauss_table);
 
447
 
 
448
    /**
 
449
      @brief computes the kernel matrix using the actual svm parameters and the given data
 
450
 
 
451
      This function can be used to compute a kernel matrix. 'problem1' and 'problem2'
 
452
      are used together wit the oligo kernel function (could be extended if you
 
453
      want to use your own kernel functions).
 
454
 
 
455
    */
 
456
    svm_problem * computeKernelMatrix(svm_problem * problem1, svm_problem * problem2);
 
457
 
 
458
    /**
 
459
      @brief computes the kernel matrix using the actual svm parameters and the given data
 
460
 
 
461
      This function can be used to compute a kernel matrix. 'problem1' and 'problem2'
 
462
      are used together wit the oligo kernel function (could be extended if you
 
463
      want to use your own kernel functions).
 
464
 
 
465
    */
 
466
    svm_problem * computeKernelMatrix(const SVMData & problem1, const SVMData & problem2);
 
467
 
 
468
    /**
 
469
      @brief This is used for being able to perform predictions with non libsvm standard kernels
 
470
 
 
471
    */
 
472
    void setTrainingSample(svm_problem * training_sample);
 
473
 
 
474
    /**
 
475
      @brief This is used for being able to perform predictions with non libsvm standard kernels
 
476
 
 
477
    */
 
478
    void setTrainingSample(SVMData & training_sample);
 
479
 
 
480
    /**
 
481
      @brief This function fills probabilities with the probability estimates for the first class.
 
482
 
 
483
      The libSVM function svm_predict_probability is called to get probability estimates
 
484
      for the positive class. Since this is only used for binary classification it is sufficient
 
485
      for every test example to report the probability of the test example belonging to the positive
 
486
      class. Probability estimates have to be turned on during training (svm.setParameter(PROBABILITY, 1)),
 
487
      otherwise this method will fill the 'probabilities' vector with -1s.
 
488
    */
 
489
    void getSVCProbabilities(struct svm_problem * problem, std::vector<DoubleReal> & probabilities, std::vector<DoubleReal> & prediction_labels);
 
490
 
 
491
    /**
 
492
      @brief Sets weights for the classes in C_SVC (see libsvm documentation for further details)
 
493
 
 
494
    */
 
495
    void setWeights(const std::vector<Int> & weight_labels, const std::vector<DoubleReal> & weights);
 
496
 
 
497
private:
 
498
    /**
 
499
       @brief find next grid search parameter combination
 
500
 
 
501
       The current grid cell is given in @p actual_values.
 
502
       The result is returned in @p actual_values.
 
503
 
 
504
    */
 
505
    bool nextGrid_(const std::vector<DoubleReal> & start_values,
 
506
                   const std::vector<DoubleReal> & step_sizes,
 
507
                   const std::vector<DoubleReal> & end_values,
 
508
                   const bool additive_step_sizes,
 
509
                   std::vector<DoubleReal> & actual_values);
 
510
 
 
511
    Size getNumberOfEnclosedPoints_(DoubleReal m1, DoubleReal m2, const std::vector<std::pair<DoubleReal, DoubleReal> > & points);
 
512
 
 
513
    /**
 
514
      @brief Initializes the svm with standard parameters
 
515
 
 
516
    */
 
517
    void initParameters_();
 
518
 
 
519
    /**
 
520
      @brief This function is passed to lib svm for output control
 
521
 
 
522
      The intention is to discard the output, as we don't need it.
 
523
 
 
524
    */
 
525
    static void printToVoid_(const char * /*s*/);
 
526
 
 
527
    svm_parameter * param_;                                                                 // the parameters for the svm
 
528
    svm_model * model_;                                                                       // the learnt svm discriminant
 
529
    DoubleReal                                                      sigma_;                                 // for the oligo kernel (amount of positional smearing)
 
530
    std::vector<DoubleReal>                             sigmas_;                                    // for the combined oligo kernel (amount of positional smearing)
 
531
    std::vector<DoubleReal>                             gauss_table_;                           // lookup table for fast computation of the oligo kernel
 
532
    std::vector<std::vector<DoubleReal> > gauss_tables_;                        // lookup table for fast computation of the combined oligo kernel
 
533
    Size                                                                    kernel_type_;                           // the actual kernel type
 
534
    Size                                                                    border_length_;                     // the actual kernel type
 
535
    svm_problem * training_set_;                                                                        // the training set
 
536
    svm_problem * training_problem_;                                                                // the training set
 
537
    SVMData                                                             training_data_;                     // the training set (different encoding)
 
538
 
 
539
  };
 
540
 
534
541
} // namespace OpenMS
535
542
 
536
543
#endif // OPENMS_ANALYSIS_SVM_SVMWRAPPER_H