27 using namespace Eigen;
33 m_tolerance=tolerance;
34 m_store_cov=store_cov;
43 m_tolerance=tolerance;
44 m_store_cov=store_cov;
76 void CMCLDA::cleanup()
86 SG_ERROR(
"Specified features are not of type CDotFeatures\n")
107 for (
int i = 0; i < num_vecs; i++)
109 vec = rf->get_feature_vector(i, vlen, vfree);
114 X.row(i) = Evec - Em_xbar;
116 rf->free_feature_vector(vec, i, vfree);
120 SG_PRINT(
"\n>>> Displaying X ...\n")
130 SG_PRINT(
"\n>>> Displaying Xs ...\n")
135 MatrixXd d(num_vecs, m_num_classes);
138 d = (Xs*Em_coef.transpose()).rowwise() + Em_intercept.transpose();
141 SG_PRINT(
"\n>>> Displaying d ...\n")
147 for (
int i = 0; i < num_vecs; i++)
156 SG_ERROR(
"No labels allocated in MCLDA training\n")
161 SG_ERROR(
"Speficied features are not of type CDotFeatures\n")
167 SG_ERROR(
"No features allocated in MCLDA training\n")
172 SG_ERROR(
"No train_labels allocated in MCLDA training\n")
180 if (num_vec != train_labels.
vlen)
181 SG_ERROR(
"Dimension mismatch between features and labels in MCLDA training")
183 int32_t* class_idxs = SG_MALLOC(int32_t, num_vec*m_num_classes);
184 int32_t* class_nums = SG_MALLOC(int32_t, m_num_classes);
185 memset(class_nums, 0, m_num_classes*
sizeof(int32_t));
187 for (
int i = 0; i < train_labels.
vlen; i++)
189 int32_t class_idx = train_labels.
vector[i];
191 if (class_idx < 0 || class_idx >= m_num_classes)
193 SG_ERROR(
"found label out of {0, 1, 2, ..., num_classes-1}...")
198 class_idxs[ class_idx*num_vec + class_nums[class_idx]++ ] = i;
202 for (
int i = 0; i < m_num_classes; i++)
204 if (class_nums[i] <= 0)
206 SG_ERROR(
"What? One class with no elements\n")
217 cov_dims[2] = m_num_classes;
223 MatrixXd X = MatrixXd::Zero(num_vec, m_dim);
231 for (
int k = 0; k < m_num_classes; k++)
234 MatrixXd buffer(class_nums[k], m_dim);
236 for (
int i = 0; i < class_nums[k]; i++)
243 buffer.row(i) = Evec;
248 Em_mean /= class_nums[k];
251 for (
int i = 0; i < class_nums[k]; i++)
253 buffer.row(i) -= Em_mean;
254 X.row(iX) += buffer.row(i);
262 Em_cov_k = buffer.transpose() * buffer;
267 SG_PRINT(
"\n>>> Displaying means ...\n")
277 for (
int k = 0; k < m_num_classes; k++)
283 Em_cov /= m_num_classes;
289 SG_PRINT(
"\n>>> Displaying cov ...\n")
301 Em_xbar = X.colwise().sum();
304 VectorXd
std = VectorXd::Zero(m_dim);
305 std = (X.rowwise() - Em_xbar.transpose()).array().pow(2).colwise().sum();
306 std = std.array() / num_vec;
308 for (
int j = 0; j < m_dim; j++)
312 float64_t fac = 1.0 / (num_vec - m_num_classes);
315 SG_PRINT(
"\n>>> Displaying m_xbar ...\n")
318 SG_PRINT(
"\n>>> Displaying std ...\n")
324 for (
int i = 0; i < num_vec; i++)
325 X.row(i) = sqrt(fac) * X.row(i).array() / std.transpose().array();
332 Eigen::JacobiSVD<MatrixXd> eSvd;
333 eSvd.compute(X,Eigen::ComputeFullV);
334 sg_memcpy(S.data(), eSvd.singularValues().data(), m_dim*
sizeof(
float64_t));
335 sg_memcpy(V.data(), eSvd.matrixV().data(), m_dim*m_dim*
sizeof(
float64_t));
336 V.transposeInPlace();
339 while (rank < m_dim && S[rank] > m_tolerance)
345 SG_ERROR(
"Warning: Variables are collinear\n")
348 for (
int i = 0; i < m_dim; i++)
349 for (
int j = 0; j < rank; j++)
350 scalings(i,j) = V(j,i) / std[j] / S[j];
353 SG_PRINT(
"\n>>> Displaying scalings ...\n")
363 Xc = (Em_means.transpose()*scalings);
365 for (
int i = 0; i < m_num_classes; i++)
366 Xc.row(i) *= sqrt(class_nums[i] * fac);
374 eSvd.compute(Xc,Eigen::ComputeFullV);
375 sg_memcpy(S.data(), eSvd.singularValues().data(), rank*
sizeof(
float64_t));
376 sg_memcpy(V.data(), eSvd.matrixV().data(), rank*rank*
sizeof(
float64_t));
379 while (m_rank < rank && S[m_rank] > m_tolerance*S[0])
387 Em_scalings = scalings * V.leftCols(m_rank);
390 SG_PRINT(
"\n>>> Displaying m_scalings ...\n")
395 MatrixXd meansc(m_dim, m_num_classes);
396 meansc = Em_means.colwise() - Em_xbar;
400 Em_coef = meansc.transpose() * Em_scalings;
403 SG_PRINT(
"\n>>> Displaying m_coefs ...\n")
410 for (
int j = 0; j < m_num_classes; j++)
411 m_intercept[j] = -0.5*m_coef[j]*m_coef[j] + log(class_nums[j]/
float(num_vec));
414 SG_PRINT(
"\n>>> Displaying m_intercept ...\n")
T * get_matrix(index_t matIdx) const
CMCLDA(float64_t tolerance=1e-4, bool store_cov=false)
static int32_t arg_max(T *vec, int32_t inc, int32_t len, T *maxv_ptr=NULL)
experimental abstract native multiclass machine class
virtual CMulticlassLabels * apply_multiclass(CFeatures *data=NULL)
virtual bool train_machine(CFeatures *data=NULL)
The class Labels models labels, i.e. class assignments of objects.
bool has_property(EFeatureProperty p) const
virtual int32_t get_num_vectors() const =0
void display_matrix(const char *name="matrix") const
virtual void set_features(CDotFeatures *feat)
Features that support dot products among other operations.
ST * get_feature_vector(int32_t num, int32_t &len, bool &dofree)
virtual int32_t get_dim_feature_space() const =0
Multiclass Labels for multi-class classification.
T * get_column_vector(index_t col) const
Class SGObject is the base class of all shogun objects.
void free_feature_vector(ST *feat_vec, int32_t num, bool dofree)
Matrix< float64_t,-1,-1, 0,-1,-1 > MatrixXd
all of classes and functions are contained in the shogun namespace
The class Features is the base class of all feature objects.
virtual void set_labels(CLabels *lab)
void display_vector(const char *name="vector", const char *prefix="") const