1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
/**
* @file gensvm_pred.c
* @author Gertjan van den Burg
* @date August 9, 2013
* @brief Main functions for predicting class labels..
*
* @details
* This file contains functions for predicting the class labels of instances
* and a function for calculating the predictive performance (hitrate) of
* a prediction given true class labels.
*
*/
#include <cblas.h>
#include <math.h>
#include "libGenSVM.h"
#include "gensvm.h"
#include "gensvm_kernel.h"
#include "gensvm_matrix.h"
#include "gensvm_pred.h"
/**
* @brief Predict class labels of data given and output in predy
*
* @details
* The labels are predicted by mapping each instance in data to the
* simplex space using the matrix V in the given model. Next, for each
* instance the nearest simplex vertex is determined using an Euclidean
* norm. The nearest simplex vertex determines the predicted class label,
* which is recorded in predy.
*
* @param[in] data GenData to predict labels for
* @param[in] model GenModel with optimized V
* @param[out] predy pre-allocated vector to record predictions in
*/
void gensvm_predict_labels(struct GenData *testdata, struct GenModel *model,
long *predy)
{
long i, j, k, n, m, K, label;
double norm, min_dist, *S, *ZV, *U;
n = testdata->n;
m = testdata->r;
K = model->K;
// allocate necessary memory
S = Calloc(double, K-1);
if (S == NULL) {
fprintf(stderr, "Failed to allocate memory for S in "
"gensvm_predict_labels.\n");
exit(1);
}
ZV = Calloc(double, n*(K-1));
if (ZV == NULL) {
fprintf(stderr, "Failed to allocate memory for ZV in "
"gensvm_predict_labels.\n");
exit(1);
}
U = Calloc(double, K*(K-1));
if (U == NULL) {
fprintf(stderr, "Failed to allocate memory for U in "
"gensvm_predict_labels.\n");
exit(1);
}
// Generate the simplex matrix
gensvm_simplex_gen(K, U);
// Generate the simplex space vectors
cblas_dgemm(
CblasRowMajor,
CblasNoTrans,
CblasNoTrans,
n,
K-1,
m+1,
1.0,
testdata->Z,
m+1,
model->V,
K-1,
0.0,
ZV,
K-1);
// Calculate the distance to each of the vertices of the simplex.
// The closest vertex defines the class label
for (i=0; i<n; i++) {
label = 0;
min_dist = INFINITY;
for (j=0; j<K; j++) {
for (k=0; k<K-1; k++) {
S[k] = matrix_get(ZV, K-1, i, k) -
matrix_get(U, K-1, j, k);
}
norm = cblas_dnrm2(K-1, S, 1);
if (norm < min_dist) {
label = j+1;
min_dist = norm;
}
}
predy[i] = label;
}
free(ZV);
free(U);
free(S);
}
/**
* @brief Calculate the predictive performance (percentage correct)
*
* @details
* The predictive performance is calculated by simply counting the number
* of correctly classified samples and dividing by the total number of
* samples, multiplying by 100.
*
* @param[in] data the GenData dataset with known labels
* @param[in] predy the predicted class labels
*
* @returns percentage correctly classified.
*/
double gensvm_prediction_perf(struct GenData *data, long *predy)
{
long i, correct = 0;
double performance;
for (i=0; i<data->n; i++)
if (data->y[i] == predy[i])
correct++;
performance = ((double) correct)/((double) data->n)* 100.0;
return performance;
}
|