const-fixing functions
[mldemos:baraks-mldemos.git] / _AlgorithmsPlugins / Projections / classifierKPCA.cpp
1 /*********************************************************************\r
2 MLDemos: A User-Friendly visualization toolkit for machine learning\r
3 Copyright (C) 2010  Basilio Noris\r
4 Contact: mldemos@b4silio.com\r
5 \r
6 This library is free software; you can redistribute it and/or\r
7 modify it under the terms of the GNU Lesser General Public\r
8 License as published by the Free Software Foundation; either\r
9 version 2.1 of the License, or (at your option) any later version.\r
10 \r
11 This library is distributed in the hope that it will be useful,\r
12 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
14 Library General Public License for more details.\r
15 \r
16 You should have received a copy of the GNU Lesser General Public\r
17 License along with this library; if not, write to the Free\r
18 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
19 *********************************************************************/\r
20 #include <public.h>\r
21 #include "classifierKPCA.h"\r
22 #include <QDebug>\r
23 \r
24 using namespace std;\r
25 \r
26 ClassifierKPCA::ClassifierKPCA()\r
27         : pca(0)\r
28 {\r
29     bUsesDrawTimer = true;\r
30 }\r
31 \r
32 \r
33 std::vector<fvec> ClassifierKPCA::Project(std::vector<fvec> samples)\r
34 {\r
35         if(!samples.size() || !pca) return samples;\r
36         vector<fvec> projected;\r
37         int dim = samples[0].size();\r
38 \r
39         FOR(i, samples.size()) samples[i] -= mean;\r
40 \r
41         // we dump the data in a matrix\r
42         MatrixXd data(samples[0].size(), samples.size());\r
43         FOR(i, samples.size())\r
44         {\r
45                 FOR(d, dim) data(d,i) = samples[i][d];\r
46         }\r
47 \r
48         MatrixXd projections = pca->project(data, dim);\r
49         projected.clear();\r
50         projected.resize(projections.rows());\r
51         fvec sample;\r
52         sample.resize(projections.cols());\r
53         FOR(i, projections.rows())\r
54         {\r
55                 FOR(d, projections.cols())\r
56                 {\r
57                         sample[d] = projections(i,d); // we recenter the data\r
58                 }\r
59                 projected[i] = sample;\r
60         }\r
61         fvec diffValues = maxValues - minValues;\r
62         // we renormalize the results in a 0-1 space\r
63         FOR(i, projected.size())\r
64         {\r
65                 FOR(d, projected[0].size())\r
66                 {\r
67                         projected[i][d] = ((projected[i][d]-minValues[d])/diffValues[d])*0.9f + 0.05f;\r
68                 }\r
69         }\r
70 \r
71         return projected;\r
72 }\r
73 \r
74 void ClassifierKPCA::Train(std::vector< fvec > samples, ivec labels)\r
75 {\r
76         if(!samples.size()) return;\r
77         this->labels = labels;\r
78         this->samples = samples;\r
79         int count = samples.size();\r
80         int dim = samples[0].size();\r
81         int dimSpace = dim;\r
82 \r
83         // we center the data\r
84         mean = samples[0];\r
85         FOR(i, count-1) mean += samples[i+1];\r
86         mean /= count;\r
87         FOR(i, count) samples[i] -= mean;\r
88 \r
89         // we dump the data in a matrix\r
90         MatrixXd data(samples[0].size(), samples.size());\r
91         FOR(i, count)\r
92         {\r
93                 FOR(d, dim) data(d,i) = samples[i][d];\r
94         }\r
95 \r
96         // and we run the algorithm\r
97         DEL(pca);\r
98         pca = new PCA();\r
99         pca->kernelType = kernelType;\r
100         pca->degree = kernelDegree;\r
101         pca->gamma = kernelGamma;\r
102     pca->offset = kernelOffset;\r
103 \r
104         pca->kernel_pca(data, dim);\r
105         MatrixXd projections = pca->get();\r
106         results.clear();\r
107         results.resize(projections.rows());\r
108         fvec sample;\r
109         sample.resize(projections.cols());\r
110         minValues.clear();\r
111         maxValues.clear();\r
112         minValues.resize(projections.cols(), FLT_MAX);\r
113         maxValues.resize(projections.cols(), -FLT_MAX);\r
114         FOR(i, projections.rows())\r
115         {\r
116                 FOR(d, projections.cols())\r
117                 {\r
118                         sample[d] = projections(i,d) + 0.5; // we recenter the data\r
119                         if(sample[d] < minValues[d]) minValues[d] = sample[d];\r
120                         if(sample[d] > maxValues[d]) maxValues[d] = sample[d];\r
121                 }\r
122                 results[i] = sample;\r
123         }\r
124         fvec diffValues = maxValues - minValues;\r
125         // we renormalize the results in a 0-1 space\r
126         FOR(i, results.size())\r
127         {\r
128                 FOR(d, results[0].size())\r
129                 {\r
130                         results[i][d] = ((results[i][d]-minValues[d])/diffValues[d])*0.9f + 0.05f;\r
131                 }\r
132         }\r
133 }\r
134 \r
135 float ClassifierKPCA::Test( const fvec &sample ) const\r
136 {\r
137         float estimate = 0;\r
138         if(!pca) return estimate;\r
139 \r
140         VectorXd point(sample.size());\r
141         FOR(i, sample.size()) point(i) = sample[i];\r
142         estimate = pca->test(point);\r
143 \r
144         return estimate;\r
145 }\r
146 \r
147 float ClassifierKPCA::Test( const fVec &sample ) const\r
148 {\r
149         float estimate = 0;\r
150         if(!pca) return estimate;\r
151 \r
152         VectorXd point(2);\r
153         FOR(i, sample.size()) point(i) = sample._[i];\r
154         estimate = pca->test(point);\r
155 \r
156         return estimate;\r
157 }\r
158 void ClassifierKPCA::SetParams(int kernelType, int kernelDegree, float kernelGamma, float kernelOffset)\r
159 {\r
160         this->kernelType = kernelType;\r
161         this->kernelDegree = kernelDegree;\r
162         this->kernelGamma = kernelGamma;\r
163     this->kernelOffset = kernelOffset;\r
164 }\r
165 \r
166 const char *ClassifierKPCA::GetInfoString() const\r
167 {\r
168         char *text = new char[1024];\r
169         /*\r
170  if(!svm) return NULL;\r
171  sprintf(text, "%s\n", param.svm_type == NU_SVC ? "nu-KPCA" : "C-KPCA");\r
172  sprintf(text, "%sKernel: ", text);\r
173  switch(param.kernel_type)\r
174  {\r
175  case LINEAR:\r
176   sprintf(text, "%s linear\n", text);\r
177   break;\r
178  case POLY:\r
179   sprintf(text, "%s polynomial (deg: %f bias: %f width: %f)\n", text, param.degree, param.coef0, param.gamma);\r
180   break;\r
181  case RBF:\r
182   sprintf(text, "%s rbf (gamma: %f)\n", text, param.gamma);\r
183   break;\r
184  case SIGMOID:\r
185   sprintf(text, "%s sigmoid (%f %f)\n", text, param.gamma, param.coef0);\r
186   break;\r
187  }\r
188  sprintf(text, "%sC: %f \t nu: %f\n", text, param.C, param.nu);\r
189  sprintf(text, "%sSupport Vectors: %d\n", text, svm->l);\r
190  */\r
191         return text;\r
192 }\r