FIXED: Update the column class to follow the number displayed in the spinbox
[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 = false;\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 \r
103         pca->kernel_pca(data, dim);\r
104         MatrixXd projections = pca->get();\r
105         results.clear();\r
106         results.resize(projections.rows());\r
107         fvec sample;\r
108         sample.resize(projections.cols());\r
109         minValues.clear();\r
110         maxValues.clear();\r
111         minValues.resize(projections.cols(), FLT_MAX);\r
112         maxValues.resize(projections.cols(), -FLT_MAX);\r
113         FOR(i, projections.rows())\r
114         {\r
115                 FOR(d, projections.cols())\r
116                 {\r
117                         sample[d] = projections(i,d) + 0.5; // we recenter the data\r
118                         if(sample[d] < minValues[d]) minValues[d] = sample[d];\r
119                         if(sample[d] > maxValues[d]) maxValues[d] = sample[d];\r
120                 }\r
121                 results[i] = sample;\r
122         }\r
123         fvec diffValues = maxValues - minValues;\r
124         // we renormalize the results in a 0-1 space\r
125         FOR(i, results.size())\r
126         {\r
127                 FOR(d, results[0].size())\r
128                 {\r
129                         results[i][d] = ((results[i][d]-minValues[d])/diffValues[d])*0.9f + 0.05f;\r
130                 }\r
131         }\r
132 }\r
133 \r
134 float ClassifierKPCA::Test( const fvec &sample )\r
135 {\r
136         float estimate = 0;\r
137         if(!pca) return estimate;\r
138 \r
139         VectorXd point(sample.size());\r
140         FOR(i, sample.size()) point(i) = sample[i];\r
141         estimate = pca->test(point);\r
142 \r
143         return estimate;\r
144 }\r
145 \r
146 float ClassifierKPCA::Test( const fVec &sample )\r
147 {\r
148         float estimate = 0;\r
149         if(!pca) return estimate;\r
150 \r
151         VectorXd point(2);\r
152         FOR(i, sample.size()) point(i) = sample._[i];\r
153         estimate = pca->test(point);\r
154 \r
155         return estimate;\r
156 }\r
157 void ClassifierKPCA::SetParams(int kernelType, int kernelDegree, float kernelGamma)\r
158 {\r
159         this->kernelType = kernelType;\r
160         this->kernelDegree = kernelDegree;\r
161         this->kernelGamma = kernelGamma;\r
162 }\r
163 \r
164 const char *ClassifierKPCA::GetInfoString()\r
165 {\r
166         char *text = new char[1024];\r
167         /*\r
168  if(!svm) return NULL;\r
169  sprintf(text, "%s\n", param.svm_type == NU_SVC ? "nu-KPCA" : "C-KPCA");\r
170  sprintf(text, "%sKernel: ", text);\r
171  switch(param.kernel_type)\r
172  {\r
173  case LINEAR:\r
174   sprintf(text, "%s linear\n", text);\r
175   break;\r
176  case POLY:\r
177   sprintf(text, "%s polynomial (deg: %f bias: %f width: %f)\n", text, param.degree, param.coef0, param.gamma);\r
178   break;\r
179  case RBF:\r
180   sprintf(text, "%s rbf (gamma: %f)\n", text, param.gamma);\r
181   break;\r
182  case SIGMOID:\r
183   sprintf(text, "%s sigmoid (%f %f)\n", text, param.gamma, param.coef0);\r
184   break;\r
185  }\r
186  sprintf(text, "%sC: %f \t nu: %f\n", text, param.C, param.nu);\r
187  sprintf(text, "%sSupport Vectors: %d\n", text, svm->l);\r
188  */\r
189         return text;\r
190 }\r