@datagrok/eda 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/detectors.js +9 -0
- package/dist/111.js +2 -0
- package/dist/146.js +2 -0
- package/dist/155.js +2 -0
- package/dist/355.js +2 -0
- package/dist/584.js +2 -0
- package/dist/604.js +2 -0
- package/dist/632.js +2 -0
- package/dist/645.js +2 -0
- package/dist/93.js +2 -0
- package/dist/d711f70338306e5bddc4.wasm +0 -0
- package/dist/package-test.js +2 -0
- package/dist/package.js +2 -0
- package/package.json +49 -0
- package/package.png +0 -0
- package/scripts/command.txt +1 -0
- package/scripts/exportForTS.py +862 -0
- package/scripts/exportForTSConstants.py +93 -0
- package/scripts/func.json +1 -0
- package/scripts/module.json +11 -0
- package/src/EDAtools.ts +46 -0
- package/src/EDAui.ts +118 -0
- package/src/dataGenerators.ts +74 -0
- package/src/demos.ts +38 -0
- package/src/package-test.ts +12 -0
- package/src/package.ts +248 -0
- package/src/svm.ts +485 -0
- package/src/utils.ts +51 -0
- package/tsconfig.json +71 -0
- package/wasm/EDA.js +443 -0
- package/wasm/EDA.wasm +0 -0
- package/wasm/EDAAPI.js +131 -0
- package/wasm/EDAForWebWorker.js +21 -0
- package/wasm/PCA/PCA.cpp +151 -0
- package/wasm/PCA/PCA.h +48 -0
- package/wasm/PLS/PLS.h +64 -0
- package/wasm/PLS/pls.cpp +393 -0
- package/wasm/callWasm.js +475 -0
- package/wasm/callWasmForWebWorker.js +706 -0
- package/wasm/dataGenerators.h +169 -0
- package/wasm/dataMining.h +116 -0
- package/wasm/pcaExport.cpp +64 -0
- package/wasm/plsExport.cpp +75 -0
- package/wasm/svm.h +608 -0
- package/wasm/svmApi.cpp +323 -0
- package/wasm/workers/errorWorker.js +13 -0
- package/wasm/workers/generateDatasetWorker.js +13 -0
- package/wasm/workers/normalizeDatasetWorker.js +13 -0
- package/wasm/workers/partialLeastSquareRegressionWorker.js +13 -0
- package/wasm/workers/predictByLSSVMWorker.js +13 -0
- package/wasm/workers/principalComponentAnalysisWorker.js +13 -0
- package/wasm/workers/trainAndAnalyzeLSSVMWorker.js +13 -0
- package/wasm/workers/trainLSSVMWorker.js +13 -0
- package/webpack.config.js +37 -0
package/wasm/svm.h
ADDED
|
@@ -0,0 +1,608 @@
|
|
|
1
|
+
// svm.h
|
|
2
|
+
|
|
3
|
+
/* Implementation of the method LS-SVM (Least Squares Support Vector Machine) for DATAGROK.
|
|
4
|
+
|
|
5
|
+
The following references are used:
|
|
6
|
+
[1] Suykens, J., Vandewalle, J. "Least Squares Support Vector Machine Classifiers",
|
|
7
|
+
Neural Processing Letters 9, 293�300 (1999). https://doi.org/10.1023/A:1018628609742
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
#ifndef SVM_H
|
|
11
|
+
#define SVM_H
|
|
12
|
+
|
|
13
|
+
#include <cmath>
|
|
14
|
+
using std::sqrt;
|
|
15
|
+
using std::fabs;
|
|
16
|
+
|
|
17
|
+
#include "../../../../Eigen/Eigen/Dense"
|
|
18
|
+
using namespace Eigen;
|
|
19
|
+
|
|
20
|
+
namespace svm {
|
|
21
|
+
|
|
22
|
+
// computation result code
|
|
23
|
+
enum ResultCode {
|
|
24
|
+
NO_ERRORS = 0,
|
|
25
|
+
UNKNOWN_PROBLEM,
|
|
26
|
+
INCORRECT_HYPERPARAMETER,
|
|
27
|
+
INCORRECT_PARAMETER_OF_KERNEL,
|
|
28
|
+
UNKNOWN_KERNEL_TYPE,
|
|
29
|
+
INCORRECT_KERNEL_PARAMS_COUNT,
|
|
30
|
+
INCORRECT_PROBABILITY,
|
|
31
|
+
INCORRECT_PERCENTAGE,
|
|
32
|
+
INCORRECT_SIZE
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// types of model kernels
|
|
36
|
+
enum KernelType { LINEAR = 0, POLYNOMIAL, RBF, SIGMOID };
|
|
37
|
+
|
|
38
|
+
// constants for kernel params
|
|
39
|
+
const int MAX_NUM_OF_KERNEL_PARAM = 2;
|
|
40
|
+
const int RBF_SIGMA_INDEX = 0;
|
|
41
|
+
const int POLYNOMIAL_C_INDEX = 0;
|
|
42
|
+
const int POLYNOMIAL_D_INDEX = 1;
|
|
43
|
+
const int SIGMOID_KAPPA_INDEX = 0;
|
|
44
|
+
const int SIGMOID_THETA_INDEX = 1;
|
|
45
|
+
|
|
46
|
+
// Check correctness of LS-SVM hyperparameter gamma
|
|
47
|
+
template<typename Float>
|
|
48
|
+
bool isGammaCorrect(Float gamma) noexcept
|
|
49
|
+
{
|
|
50
|
+
return (gamma > static_cast<Float>(0));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* Check correctness of kernel parameters.
|
|
54
|
+
kernel - kernel type,
|
|
55
|
+
kernelParameters - parameters of kernel. */
|
|
56
|
+
template<typename Float>
|
|
57
|
+
bool areKernelParametersCorrect(int kernel, Float kernelParameters[MAX_NUM_OF_KERNEL_PARAM]) noexcept
|
|
58
|
+
{
|
|
59
|
+
Float zero = static_cast<Float>(0);
|
|
60
|
+
Float c = kernelParameters[POLYNOMIAL_C_INDEX];
|
|
61
|
+
Float d = kernelParameters[POLYNOMIAL_D_INDEX];
|
|
62
|
+
Float sigma = kernelParameters[RBF_SIGMA_INDEX];
|
|
63
|
+
|
|
64
|
+
switch (kernel)
|
|
65
|
+
{
|
|
66
|
+
case LINEAR:
|
|
67
|
+
return true;
|
|
68
|
+
case POLYNOMIAL:
|
|
69
|
+
return ((c > zero) && (d > zero));
|
|
70
|
+
case RBF:
|
|
71
|
+
return (c > zero);
|
|
72
|
+
case SIGMOID:
|
|
73
|
+
return true;
|
|
74
|
+
default:
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
} // areKernelParametersCorrect
|
|
78
|
+
|
|
79
|
+
/* Value of SVM-kernel function.
|
|
80
|
+
kernel - type of kernel
|
|
81
|
+
kernelParams - parameters of kernel
|
|
82
|
+
v1, v2 - kernel arguments. */
|
|
83
|
+
template<typename Float, typename VecType1, typename VecType2>
|
|
84
|
+
Float kernelFunc(int kernel, Float kernelParams[MAX_NUM_OF_KERNEL_PARAM], VecType1& v1, VecType2& v2) noexcept
|
|
85
|
+
{
|
|
86
|
+
switch (kernel)
|
|
87
|
+
{
|
|
88
|
+
case LINEAR:
|
|
89
|
+
return v1.dot(v2);
|
|
90
|
+
case RBF:
|
|
91
|
+
return exp(-(v1 - v2).squaredNorm() / (kernelParams[0] * kernelParams[0]));
|
|
92
|
+
default:
|
|
93
|
+
return 0;
|
|
94
|
+
}
|
|
95
|
+
} // kernelFunc
|
|
96
|
+
|
|
97
|
+
/* Compute matrix of the linear system for the LS-SVM method
|
|
98
|
+
with LINEAR kernel.
|
|
99
|
+
gammaInv - value inverse to hyperparameter gamma
|
|
100
|
+
xTrain - feature vectors for training model
|
|
101
|
+
yTrain - labels of feature vectors
|
|
102
|
+
samplesCount - number of training samples
|
|
103
|
+
featuresCount - number of features, i.e. feature space dimension
|
|
104
|
+
A - matrix of linear system for the LS-SVM method */
|
|
105
|
+
template<typename Float, typename MatrixType>
|
|
106
|
+
int computeMatrixOfLSSVMsystemWithLinearKernel(Float gammaInv,
|
|
107
|
+
Float* xTrain, Float* yTrain, int samplesCount, int featuresCount,
|
|
108
|
+
MatrixType& A) noexcept
|
|
109
|
+
{
|
|
110
|
+
// assign train data pointer with the matrix X
|
|
111
|
+
Map<Matrix<Float, Dynamic, Dynamic, RowMajor>> X(xTrain, samplesCount, featuresCount);
|
|
112
|
+
|
|
113
|
+
// compute left upper block
|
|
114
|
+
for (int i = 0; i < samplesCount; ++i)
|
|
115
|
+
{
|
|
116
|
+
for (int j = 0; j < i; ++j)
|
|
117
|
+
A(i, j) = A(j, i) = yTrain[i] * yTrain[j] * X.row(i).dot(X.row(j));
|
|
118
|
+
|
|
119
|
+
A(i, i) = X.row(i).squaredNorm() + gammaInv;
|
|
120
|
+
}
|
|
121
|
+
// compute left lower and rigth upper block
|
|
122
|
+
for (int j = 0; j < samplesCount; ++j)
|
|
123
|
+
A(samplesCount, j) = A(j, samplesCount) = yTrain[j];
|
|
124
|
+
|
|
125
|
+
// right lower element
|
|
126
|
+
A(samplesCount, samplesCount) = 0;
|
|
127
|
+
|
|
128
|
+
return NO_ERRORS;
|
|
129
|
+
} // computeMatrixOfLSSVMsystemWithLinearKernel
|
|
130
|
+
|
|
131
|
+
/* Compute matrix of the linear system for the LS-SVM method
|
|
132
|
+
with RBF kernel.
|
|
133
|
+
gammaInv - value inverse to hyperparameter gamma
|
|
134
|
+
sigma - parameter of RBF kernel
|
|
135
|
+
xTrain - feature vectors for training model
|
|
136
|
+
yTrain - labels of feature vectors
|
|
137
|
+
samplesCount - number of training samples
|
|
138
|
+
featuresCount - number of features, i.e. feature space dimension
|
|
139
|
+
A - matrix of linear system for the LS-SVM method */
|
|
140
|
+
template<typename Float, typename MatrixType>
|
|
141
|
+
int computeMatrixOfLSSVMsystemWithRBFkernel(Float gammaInv, Float sigma,
|
|
142
|
+
Float* xTrain, Float* yTrain, int samplesCount, int featuresCount,
|
|
143
|
+
MatrixType& A) noexcept
|
|
144
|
+
{
|
|
145
|
+
Float sigmaSquared = sigma * sigma;
|
|
146
|
+
|
|
147
|
+
// assign train data pointer with the matrix X
|
|
148
|
+
Map<Matrix<Float, Dynamic, Dynamic, RowMajor>> X(xTrain, samplesCount, featuresCount);
|
|
149
|
+
|
|
150
|
+
// compute left upper block
|
|
151
|
+
for (int i = 0; i < samplesCount; ++i)
|
|
152
|
+
{
|
|
153
|
+
for (int j = 0; j < i; j++)
|
|
154
|
+
A(i, j) = A(j, i) = yTrain[i] * yTrain[j] * exp(-(X.row(i) - X.row(j)).squaredNorm() / sigmaSquared);
|
|
155
|
+
|
|
156
|
+
A(i, i) = gammaInv + 1; // here, 1 = exp(-|x_i - x_i|^2 / sigma^2) = exp( 0 )
|
|
157
|
+
}
|
|
158
|
+
// compute left lower and rigth upper block
|
|
159
|
+
for (int j = 0; j < samplesCount; ++j)
|
|
160
|
+
A(samplesCount, j) = A(j, samplesCount) = yTrain[j];
|
|
161
|
+
|
|
162
|
+
// right lower element
|
|
163
|
+
A(samplesCount, samplesCount) = 0;
|
|
164
|
+
|
|
165
|
+
return NO_ERRORS;
|
|
166
|
+
} // computeMatrixOfLSSVMsystemWithRBFkernel
|
|
167
|
+
|
|
168
|
+
/* Compute matrix of the linear system for the LS-SVM method
|
|
169
|
+
with POLYNOMIAL kernel.
|
|
170
|
+
gammaInv - value inverse to hyperparameter gamma
|
|
171
|
+
cParam - parameter of polynomial kernel (c)
|
|
172
|
+
dParam - parameter of polynomial kernel (d)
|
|
173
|
+
xTrain - feature vectors for training model
|
|
174
|
+
yTrain - labels of feature vectors
|
|
175
|
+
samplesCount - number of training samples
|
|
176
|
+
featuresCount - number of features, i.e. feature space dimension
|
|
177
|
+
A - matrix of linear system for the LS-SVM method */
|
|
178
|
+
template<typename Float, typename MatrixType>
|
|
179
|
+
int computeMatrixOfLSSVMsystemWithPolynomialKernel(Float gammaInv, Float cParam, Float dParam,
|
|
180
|
+
Float* xTrain, Float* yTrain, int samplesCount, int featuresCount,
|
|
181
|
+
MatrixType& A) noexcept
|
|
182
|
+
{
|
|
183
|
+
// assign train data pointer with the matrix X
|
|
184
|
+
Map<Matrix<Float, Dynamic, Dynamic, RowMajor>> X(xTrain, samplesCount, featuresCount);
|
|
185
|
+
|
|
186
|
+
// compute left upper block
|
|
187
|
+
for (int i = 0; i < samplesCount; i++)
|
|
188
|
+
{
|
|
189
|
+
for (int j = 0; j < i; ++j)
|
|
190
|
+
// here, 1 is used by the formula from [1]
|
|
191
|
+
A(i, j) = A(j, i) = yTrain[i] * yTrain[j] * pow(X.row(i).dot(X.row(j)) / cParam + 1, dParam);
|
|
192
|
+
|
|
193
|
+
// here, 1 is used by the formula from [1]
|
|
194
|
+
A(i, i) = gammaInv + pow(X.row(i).squaredNorm() / cParam + 1, dParam);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// compute left lower and rigth upper block
|
|
198
|
+
for (int j = 0; j < samplesCount; ++j)
|
|
199
|
+
A(samplesCount, j) = A(j, samplesCount) = yTrain[j];
|
|
200
|
+
|
|
201
|
+
// right lower element
|
|
202
|
+
A(samplesCount, samplesCount) = 0;
|
|
203
|
+
|
|
204
|
+
return NO_ERRORS;
|
|
205
|
+
} // computeMatrixOfLSSVMsystemWithPolynomialKernel
|
|
206
|
+
|
|
207
|
+
/* Compute matrix of the linear system for the LS-SVM method
|
|
208
|
+
with SIGMOID kernel.
|
|
209
|
+
gammaInv - value inverse to hyperparameter gamma
|
|
210
|
+
kappa - parameter of sigmoid kernel
|
|
211
|
+
theta - parameter of sigmoid kernel
|
|
212
|
+
xTrain - feature vectors for training model
|
|
213
|
+
yTrain - labels of feature vectors
|
|
214
|
+
samplesCount - number of training samples
|
|
215
|
+
featuresCount - number of features, i.e. feature space dimension
|
|
216
|
+
A - matrix of linear system for the LS-SVM method */
|
|
217
|
+
template<typename Float, typename MatrixType>
|
|
218
|
+
int computeMatrixOfLSSVMsystemWithSigmoidKernel(Float gammaInv, Float kappa, Float theta,
|
|
219
|
+
Float* xTrain, Float* yTrain, int samplesCount, int featuresCount,
|
|
220
|
+
MatrixType& A) noexcept
|
|
221
|
+
{
|
|
222
|
+
// assign train data pointer with the matrix X
|
|
223
|
+
Map<Matrix<Float, Dynamic, Dynamic, RowMajor>> X(xTrain, samplesCount, featuresCount);
|
|
224
|
+
|
|
225
|
+
// compute left upper block
|
|
226
|
+
for (int i = 0; i < samplesCount; ++i)
|
|
227
|
+
{
|
|
228
|
+
for (int j = 0; j < i; ++j)
|
|
229
|
+
A(i, j) = A(j, i) = yTrain[i] * yTrain[j] * tanh(kappa * X.row(i).dot(X.row(j)) + theta);
|
|
230
|
+
|
|
231
|
+
A(i, i) = gammaInv + tanh(kappa * X.row(i).squaredNorm() + theta);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// compute left lower and rigth upper block
|
|
235
|
+
for (int j = 0; j < samplesCount; ++j)
|
|
236
|
+
A(samplesCount, j) = A(j, samplesCount) = yTrain[j];
|
|
237
|
+
|
|
238
|
+
// right lower element
|
|
239
|
+
A(samplesCount, samplesCount) = 0;
|
|
240
|
+
|
|
241
|
+
return NO_ERRORS;
|
|
242
|
+
} // computeMatrixOfLSSVMsystemWithSigmoidKernel
|
|
243
|
+
|
|
244
|
+
/* Compute matrix of the linear system for the LS-SVM method.
|
|
245
|
+
Linear, polynomial, RBF and sigmoid kernels are suuported.
|
|
246
|
+
gammaInv - value inverse to hyperparameter gamma
|
|
247
|
+
kernelType - type of the kernel applied
|
|
248
|
+
kernelParams - parameters of kernel
|
|
249
|
+
xTrain - feature vectors for training model
|
|
250
|
+
yTrain - labels of feature vectors
|
|
251
|
+
samplesCount - number of training samples
|
|
252
|
+
featuresCount - number of features, i.e. feature space dimension
|
|
253
|
+
A - matrix of linear system for the LS-SVM method */
|
|
254
|
+
template<typename Float, typename MatrixType>
|
|
255
|
+
int computeMatrixOfLSSVMsystem(Float gammaInv, int kernelType, Float* kernelParams,
|
|
256
|
+
Float* xTrain, Float* yTrain, int samplesCount, int featuresCount,
|
|
257
|
+
MatrixType& A) noexcept
|
|
258
|
+
{
|
|
259
|
+
switch (kernelType)
|
|
260
|
+
{
|
|
261
|
+
case LINEAR: // linear kernel case
|
|
262
|
+
return computeMatrixOfLSSVMsystemWithLinearKernel(gammaInv, xTrain, yTrain, samplesCount, featuresCount, A);
|
|
263
|
+
|
|
264
|
+
case RBF: // RBF kernel case
|
|
265
|
+
return computeMatrixOfLSSVMsystemWithRBFkernel(gammaInv, kernelParams[RBF_SIGMA_INDEX],
|
|
266
|
+
xTrain, yTrain, samplesCount, featuresCount, A);
|
|
267
|
+
|
|
268
|
+
case POLYNOMIAL: // polynomial kernel case
|
|
269
|
+
return computeMatrixOfLSSVMsystemWithPolynomialKernel(gammaInv,
|
|
270
|
+
kernelParams[POLYNOMIAL_C_INDEX], kernelParams[POLYNOMIAL_D_INDEX],
|
|
271
|
+
xTrain, yTrain, samplesCount, featuresCount, A);
|
|
272
|
+
|
|
273
|
+
case SIGMOID: // sigmoid kernel case
|
|
274
|
+
return computeMatrixOfLSSVMsystemWithSigmoidKernel(gammaInv,
|
|
275
|
+
kernelParams[SIGMOID_KAPPA_INDEX], kernelParams[SIGMOID_THETA_INDEX],
|
|
276
|
+
xTrain, yTrain, samplesCount, featuresCount, A);
|
|
277
|
+
|
|
278
|
+
default:
|
|
279
|
+
return UNKNOWN_KERNEL_TYPE;
|
|
280
|
+
}
|
|
281
|
+
} // computeMatrixOfLSSVMsystem
|
|
282
|
+
|
|
283
|
+
/* Train Least Square Support Vector Machine (LS-SVM).
|
|
284
|
+
gamma - hyperparameter
|
|
285
|
+
kernelType - type of the kernel applied
|
|
286
|
+
kernelParams - parameters of kernel
|
|
287
|
+
xTrain - feature vectors for training model (normalized)
|
|
288
|
+
yTrain - labels of feature vectors
|
|
289
|
+
samplesCount - number of training samples
|
|
290
|
+
featuresCount - number of features, i.e. feature space dimension
|
|
291
|
+
modelParams - parameters of model that is trained
|
|
292
|
+
weights - weights of the cos function, they computed in the case of linear kernel
|
|
293
|
+
|
|
294
|
+
WARNING. Training data should be normalized, i.e. mean value of each feature is 0
|
|
295
|
+
and standard deviantion is 1.
|
|
296
|
+
*/
|
|
297
|
+
template<typename Float>
|
|
298
|
+
int trainLSSVM(Float gamma, int kernel, Float kernelParams[MAX_NUM_OF_KERNEL_PARAM],
|
|
299
|
+
Float* xTrain, Float* yTrain, int samplesCount, int featuresCount,
|
|
300
|
+
Float* modelParams, Float* weights) noexcept
|
|
301
|
+
{
|
|
302
|
+
/* In order to find paramters of LS - SVM model, a special system of linear algebraic equations
|
|
303
|
+
should be solved (see [1] for more details).
|
|
304
|
+
So, the following pricipal steps are:
|
|
305
|
+
1) compute the matrix of this system (A);
|
|
306
|
+
2) compute the rigth hand side of this system (b);
|
|
307
|
+
3) solve the system Ax = b.
|
|
308
|
+
Also, model weights are computed in the case of linear kernel. */
|
|
309
|
+
|
|
310
|
+
// check gamma value
|
|
311
|
+
if (gamma <= static_cast<Float>(0.0))
|
|
312
|
+
return INCORRECT_HYPERPARAMETER;
|
|
313
|
+
|
|
314
|
+
//check kernel parameters
|
|
315
|
+
if (!areKernelParametersCorrect(kernel, kernelParams))
|
|
316
|
+
return INCORRECT_PARAMETER_OF_KERNEL;
|
|
317
|
+
|
|
318
|
+
Float gammaInv = static_cast<Float>(1.0) / gamma;
|
|
319
|
+
|
|
320
|
+
// matrix of the system to be further solved
|
|
321
|
+
Matrix<Float, Dynamic, Dynamic, RowMajor> A(samplesCount + 1, samplesCount + 1);
|
|
322
|
+
|
|
323
|
+
// compute the matrix A
|
|
324
|
+
int resCode = computeMatrixOfLSSVMsystem(gammaInv, kernel, kernelParams,
|
|
325
|
+
xTrain, yTrain, samplesCount, featuresCount, A);
|
|
326
|
+
|
|
327
|
+
// check results of the matrix A computation
|
|
328
|
+
if (resCode != NO_ERRORS)
|
|
329
|
+
return resCode;
|
|
330
|
+
|
|
331
|
+
// create rigth hand side of
|
|
332
|
+
Vector<Float, Dynamic> b = Vector<Float, Dynamic>::Ones(samplesCount + 1);
|
|
333
|
+
b(samplesCount) = 0;
|
|
334
|
+
|
|
335
|
+
// assign modelParams with a vector
|
|
336
|
+
Map<Vector<Float, Dynamic>> x(modelParams, samplesCount + 1);
|
|
337
|
+
|
|
338
|
+
// solve the system required:
|
|
339
|
+
x = A.fullPivLu().solve(b);
|
|
340
|
+
|
|
341
|
+
// finish computations in the case of non-linear kernel
|
|
342
|
+
if (kernel != LINEAR)
|
|
343
|
+
return NO_ERRORS;
|
|
344
|
+
|
|
345
|
+
// compute bias
|
|
346
|
+
weights[featuresCount] = modelParams[samplesCount];
|
|
347
|
+
|
|
348
|
+
// assign weights with w-vector
|
|
349
|
+
Map<Vector<Float, Dynamic>> w(weights, featuresCount);
|
|
350
|
+
|
|
351
|
+
// initialization
|
|
352
|
+
w = Vector<Float, Dynamic>::Zero(featuresCount);
|
|
353
|
+
|
|
354
|
+
// assign normalized train data with
|
|
355
|
+
Map<Matrix<Float, Dynamic, Dynamic, RowMajor>> X(xTrain, samplesCount, featuresCount);
|
|
356
|
+
|
|
357
|
+
// compute weigths
|
|
358
|
+
for (int i = 0; i < samplesCount; ++i)
|
|
359
|
+
w += x(i) * yTrain[i] * X.row(i);
|
|
360
|
+
|
|
361
|
+
return NO_ERRORS;
|
|
362
|
+
} // trainLSSVM
|
|
363
|
+
|
|
364
|
+
/* Predict labels of the target data using linear kernel model and precomputed weigths.
|
|
365
|
+
precomputedWeights - precomputed weights of the model
|
|
366
|
+
targetDataMatrix - matrix of the target data
|
|
367
|
+
prediction - target labels
|
|
368
|
+
targetSamplesCount - number of target samples */
|
|
369
|
+
template<typename Float, typename MatrixType>
|
|
370
|
+
int predictByLSSVMwithLinearKernel(Float* precomputedWeights,
|
|
371
|
+
MatrixType & targetDataMatrix, Float* prediction) noexcept
|
|
372
|
+
{
|
|
373
|
+
// get target data sizes
|
|
374
|
+
auto targetSamplesCount = targetDataMatrix.rows();
|
|
375
|
+
auto featuresCount = targetDataMatrix.cols();
|
|
376
|
+
|
|
377
|
+
// bias of the model
|
|
378
|
+
Float bias = precomputedWeights[featuresCount];
|
|
379
|
+
|
|
380
|
+
// assign weights-vector with the corresponding data pointer
|
|
381
|
+
Map<Vector<Float, Dynamic>> w(precomputedWeights, featuresCount);
|
|
382
|
+
|
|
383
|
+
// predict labels of the target data
|
|
384
|
+
for (int i = 0; i < targetSamplesCount; ++i)
|
|
385
|
+
{
|
|
386
|
+
// put target data to the model
|
|
387
|
+
Float cost = bias + w.dot(targetDataMatrix.row(i));
|
|
388
|
+
|
|
389
|
+
// check sign and get label (see [1] for more details)
|
|
390
|
+
if (cost > static_cast<Float>(0))
|
|
391
|
+
prediction[i] = static_cast<Float>(1);
|
|
392
|
+
else
|
|
393
|
+
prediction[i] = static_cast<Float>(-1);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return NO_ERRORS;
|
|
397
|
+
} // predictByLSSVMwithLinearKernel
|
|
398
|
+
|
|
399
|
+
/* Predict labels of the target data using RBF-kernel model.
|
|
400
|
+
sigma - parameter of RBF-kernel
|
|
401
|
+
xTrain - feature vectors for training model (normalized)
|
|
402
|
+
yTrain - labels of training vectors
|
|
403
|
+
trainSamplesCount - number of training vectors
|
|
404
|
+
featuresCount - number of features
|
|
405
|
+
modelParams - parameters of model
|
|
406
|
+
targetDataMatrix - matrix of the target data
|
|
407
|
+
prediction - target labels */
|
|
408
|
+
template<typename Float, typename MatrixType>
|
|
409
|
+
int predictByLSSVMwithRBFkernel(Float sigma,
|
|
410
|
+
Float* xTrain, Float* yTrain, int trainSamplesCount, int featuresCount,
|
|
411
|
+
Float* modelParams, MatrixType& targetDataMatrix, Float* prediction)
|
|
412
|
+
{
|
|
413
|
+
Float sigmaSquared = sigma * sigma;
|
|
414
|
+
|
|
415
|
+
// assign normalized traine data matrix with normalized train data pointer
|
|
416
|
+
Map<Matrix<Float, Dynamic, Dynamic, RowMajor>> X(xTrain, trainSamplesCount, featuresCount);
|
|
417
|
+
|
|
418
|
+
auto targetSamplesCount = targetDataMatrix.rows();
|
|
419
|
+
|
|
420
|
+
// bias of the model
|
|
421
|
+
Float bias = modelParams[trainSamplesCount];
|
|
422
|
+
|
|
423
|
+
// compute prediction for each target vector
|
|
424
|
+
for (int j = 0; j < targetSamplesCount; ++j)
|
|
425
|
+
{
|
|
426
|
+
// put target data to the model
|
|
427
|
+
Float cost = bias;
|
|
428
|
+
|
|
429
|
+
// compute cost for the current target vector
|
|
430
|
+
for(int i = 0; i < trainSamplesCount; ++i)
|
|
431
|
+
cost += modelParams[i] * yTrain[i] * exp(-(X.row(i) - targetDataMatrix.row(j)).squaredNorm() / sigmaSquared);
|
|
432
|
+
|
|
433
|
+
// check sign and get label (see [1] for more details)
|
|
434
|
+
if (cost > static_cast<Float>(0))
|
|
435
|
+
prediction[j] = static_cast<Float>(1);
|
|
436
|
+
else
|
|
437
|
+
prediction[j] = static_cast<Float>(-1);
|
|
438
|
+
} // for j
|
|
439
|
+
|
|
440
|
+
return NO_ERRORS;
|
|
441
|
+
} // predictByLSSVMwithRBFkernel
|
|
442
|
+
|
|
443
|
+
/* Predict labels of the target data using polynomial kernel model.
|
|
444
|
+
cParam - parameter of polynomial kernel
|
|
445
|
+
dParam - parameter of polynomial kernel
|
|
446
|
+
xTrain - feature vectors for training model (normalized)
|
|
447
|
+
yTrain - labels of training vectors
|
|
448
|
+
trainSamplesCount - number of training vectors
|
|
449
|
+
featuresCount - number of features
|
|
450
|
+
modelParams - parameters of model
|
|
451
|
+
targetDataMatrix - matrix of the target data
|
|
452
|
+
prediction - target labels */
|
|
453
|
+
template<typename Float, typename MatrixType>
|
|
454
|
+
int predictByLSSVMwithPolynomialKernel(Float cParam, Float dParam,
|
|
455
|
+
Float* xTrain, Float* yTrain, int trainSamplesCount, int featuresCount,
|
|
456
|
+
Float* modelParams, MatrixType& targetDataMatrix, Float* prediction)
|
|
457
|
+
{
|
|
458
|
+
// assign normalized traine data matrix with normalized train data pointer
|
|
459
|
+
Map<Matrix<Float, Dynamic, Dynamic, RowMajor>> X(xTrain, trainSamplesCount, featuresCount);
|
|
460
|
+
|
|
461
|
+
auto targetSamplesCount = targetDataMatrix.rows();
|
|
462
|
+
|
|
463
|
+
// bias of the model
|
|
464
|
+
Float bias = modelParams[trainSamplesCount];
|
|
465
|
+
|
|
466
|
+
// compute prediction for each target vector
|
|
467
|
+
for (int j = 0; j < targetSamplesCount; ++j)
|
|
468
|
+
{
|
|
469
|
+
// put target data to the model
|
|
470
|
+
Float cost = bias;
|
|
471
|
+
|
|
472
|
+
// compute cost for the current target vector
|
|
473
|
+
for (int i = 0; i < trainSamplesCount; ++i)
|
|
474
|
+
cost += modelParams[i] * yTrain[i] * pow(X.row(i).dot(targetDataMatrix.row(j)) / cParam + 1, dParam);
|
|
475
|
+
|
|
476
|
+
// check sign and get label (see [1] for more details)
|
|
477
|
+
if (cost > static_cast<Float>(0))
|
|
478
|
+
prediction[j] = static_cast<Float>(1);
|
|
479
|
+
else
|
|
480
|
+
prediction[j] = static_cast<Float>(-1);
|
|
481
|
+
} // for j
|
|
482
|
+
|
|
483
|
+
return NO_ERRORS;
|
|
484
|
+
} // predictByLSSVMwithPolynomialKernel
|
|
485
|
+
|
|
486
|
+
/* Predict labels of the target data using sigmoid kernel model.
|
|
487
|
+
kappa - parameter of sigmoid kernel
|
|
488
|
+
theta - parameter of sigmoid kernel
|
|
489
|
+
xTrain - feature vectors for training model (normalized)
|
|
490
|
+
yTrain - labels of training vectors
|
|
491
|
+
trainSamplesCount - number of training vectors
|
|
492
|
+
featuresCount - number of features
|
|
493
|
+
modelParams - parameters of model
|
|
494
|
+
targetDataMatrix - matrix of the target data
|
|
495
|
+
prediction - target labels */
|
|
496
|
+
template<typename Float, typename MatrixType>
|
|
497
|
+
int predictByLSSVMwithSigmoidKernel(Float kappa, Float theta,
|
|
498
|
+
Float* xTrain, Float* yTrain, int trainSamplesCount, int featuresCount,
|
|
499
|
+
Float* modelParams, MatrixType& targetDataMatrix, Float* prediction)
|
|
500
|
+
{
|
|
501
|
+
// assign normalized traine data matrix with normalized train data pointer
|
|
502
|
+
Map<Matrix<Float, Dynamic, Dynamic, RowMajor>> X(xTrain, trainSamplesCount, featuresCount);
|
|
503
|
+
|
|
504
|
+
auto targetSamplesCount = targetDataMatrix.rows();
|
|
505
|
+
|
|
506
|
+
// bias of the model
|
|
507
|
+
Float bias = modelParams[trainSamplesCount];
|
|
508
|
+
|
|
509
|
+
// compute prediction for each target vector
|
|
510
|
+
for (int j = 0; j < targetSamplesCount; ++j)
|
|
511
|
+
{
|
|
512
|
+
// put target data to the model
|
|
513
|
+
Float cost = bias;
|
|
514
|
+
|
|
515
|
+
// compute cost for the current target vector
|
|
516
|
+
for (int i = 0; i < trainSamplesCount; ++i)
|
|
517
|
+
cost += modelParams[i] * yTrain[i] * tanh(kappa * X.row(i).dot(targetDataMatrix.row(j)) + theta);
|
|
518
|
+
|
|
519
|
+
// check sign and get label (see [1] for more details)
|
|
520
|
+
if (cost > static_cast<Float>(0))
|
|
521
|
+
prediction[j] = static_cast<Float>(1);
|
|
522
|
+
else
|
|
523
|
+
prediction[j] = static_cast<Float>(-1);
|
|
524
|
+
} // for j
|
|
525
|
+
|
|
526
|
+
return NO_ERRORS;
|
|
527
|
+
} // predictByLSSVMwithSigmoidKernel
|
|
528
|
+
|
|
529
|
+
/* Predict labels using LS-SVM model.
|
|
530
|
+
kernelType - type of the kernel
|
|
531
|
+
kernelParams - parameters of kernel
|
|
532
|
+
xTrain - feature vectors for training model (normalized)
|
|
533
|
+
yTrain - labels of training vectors
|
|
534
|
+
trainSamplesCount - number of training vectors
|
|
535
|
+
featuresCount - number of features
|
|
536
|
+
means - mean values of training data features
|
|
537
|
+
stdDevs - standard deviations of training data features
|
|
538
|
+
modelParams - parameters of models
|
|
539
|
+
precomputedWeights - weights of the hyperplane
|
|
540
|
+
targetData - target data
|
|
541
|
+
labels - target labels
|
|
542
|
+
targetSamplesCount - number of target samples
|
|
543
|
+
|
|
544
|
+
REMARK. Precomputed weights reduce computations in the case of the linear kernel.
|
|
545
|
+
In other cases, model parameters (modelParams) are used. */
|
|
546
|
+
template<typename Float>
|
|
547
|
+
int predictByLSSVM(int kernelType, Float kernelParams[MAX_NUM_OF_KERNEL_PARAM],
|
|
548
|
+
Float* xTrain, Float* yTrain, int trainSamplesCount, int featuresCount,
|
|
549
|
+
Float* means, Float* stdDevs, Float* modelParams, Float* precomputedWeights,
|
|
550
|
+
Float* targetData, Float* prediction, int targetSamplesCount) noexcept
|
|
551
|
+
{
|
|
552
|
+
//check kernel parameters
|
|
553
|
+
if (!areKernelParametersCorrect(kernelType, kernelParams))
|
|
554
|
+
return INCORRECT_PARAMETER_OF_KERNEL;
|
|
555
|
+
|
|
556
|
+
// assign target data matrix (TD) with target data pointer
|
|
557
|
+
Map<Matrix<Float, Dynamic, Dynamic, ColMajor>> TD(targetData, targetSamplesCount, featuresCount);
|
|
558
|
+
|
|
559
|
+
// assign means with a vector
|
|
560
|
+
Map<Vector<Float, Dynamic>> mu(means, featuresCount);
|
|
561
|
+
|
|
562
|
+
// matrix for normalized target data (NTD)
|
|
563
|
+
Matrix<Float, Dynamic, Dynamic, RowMajor> NTD(targetSamplesCount, featuresCount);
|
|
564
|
+
|
|
565
|
+
// center target data
|
|
566
|
+
NTD = TD.rowwise() - mu.transpose();
|
|
567
|
+
|
|
568
|
+
// normilize target data
|
|
569
|
+
for (int i = 0; i < featuresCount; ++i)
|
|
570
|
+
{
|
|
571
|
+
Float sigma = stdDevs[i];
|
|
572
|
+
|
|
573
|
+
if (sigma > static_cast<Float>(0))
|
|
574
|
+
NTD.col(i) /= sigma;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
// compute prediction
|
|
578
|
+
switch (kernelType)
|
|
579
|
+
{
|
|
580
|
+
case LINEAR: // the case of linear kernel
|
|
581
|
+
return predictByLSSVMwithLinearKernel(precomputedWeights, NTD, prediction);
|
|
582
|
+
|
|
583
|
+
case RBF: // the case of RBF kernel
|
|
584
|
+
return predictByLSSVMwithRBFkernel(kernelParams[RBF_SIGMA_INDEX],
|
|
585
|
+
xTrain, yTrain, trainSamplesCount, featuresCount, modelParams,
|
|
586
|
+
NTD, prediction);
|
|
587
|
+
|
|
588
|
+
case POLYNOMIAL: // the case of polynomial kernel
|
|
589
|
+
return predictByLSSVMwithPolynomialKernel(
|
|
590
|
+
kernelParams[POLYNOMIAL_C_INDEX], kernelParams[POLYNOMIAL_D_INDEX],
|
|
591
|
+
xTrain, yTrain, trainSamplesCount, featuresCount, modelParams,
|
|
592
|
+
NTD, prediction);
|
|
593
|
+
|
|
594
|
+
case SIGMOID: // the case of sigmoid kernel
|
|
595
|
+
return predictByLSSVMwithSigmoidKernel(
|
|
596
|
+
kernelParams[SIGMOID_KAPPA_INDEX], kernelParams[SIGMOID_THETA_INDEX],
|
|
597
|
+
xTrain, yTrain, trainSamplesCount, featuresCount, modelParams,
|
|
598
|
+
NTD, prediction);
|
|
599
|
+
|
|
600
|
+
default:
|
|
601
|
+
return UNKNOWN_KERNEL_TYPE;
|
|
602
|
+
}
|
|
603
|
+
} // predictByLSSVM
|
|
604
|
+
}; // svm
|
|
605
|
+
|
|
606
|
+
#endif // SVM_H
|
|
607
|
+
|
|
608
|
+
|