Я пытаюсь использовать Реализация kmeans VLFeat в C но мне очень трудно понять, как это работает.
Примечание: я использую C API в программе C ++, поэтому любой код, размещенный мной здесь, является C ++. Кроме того, я использую библиотеку заголовков Eigean, вот откуда берутся эти типы данных Matrix.
Из этого примера и API неясны следующие вещи:
Код:
int numData = 1000;
int dims = 10;
// Use float data and the L1 distance for clustering
VlKMeans * kmeans = vl_kmeans_new (VL_TYPE_FLOAT, VlDistanceL1) ;
// Use Lloyd algorithm
vl_kmeans_set_algorithm (kmeans, VlKMeansLloyd) ;
// Initialize the cluster centers by randomly sampling the data
Matrix<float, 1000,10, RowMajor> data = buildData(numData, dims);
vl_kmeans_init_centers_with_rand_data (kmeans, data.data(), dims, numData, 5);
// Run at most 100 iterations of cluster refinement using Lloyd algorithm
vl_kmeans_set_max_num_iterations (kmeans, 100) ;
vl_kmeans_refine_centers (kmeans, &data, numData) ;
// Obtain the energy of the solution
energy = vl_kmeans_get_energy(kmeans) ;
// Obtain the cluster centers
centers = (double*)vl_kmeans_get_centers(kmeans);
cout << *centers << endl;
Пример вывода: центров = 0.0376879 (скаляр)
Как мне получить все центры? Я пытался использовать массив для хранения центров, но он не принимает тип.
Я также попробовал следующее, предполагая, что, возможно, я просто неправильно обращался к информации центра:
cout << centers[0]<< endl;
cout << centers[1]<< endl;
cout << centers[2]<< endl;
cout << centers[3]<< endl;
cout << centers[4]<< endl;
cout << centers[5]<< endl;
cout << centers[6]<< endl;
cout << centers[7]<< endl;
cout << centers[8]<< endl;
Но у меня должны быть только ненулевые значения для индексов 0-4 (учитывая 5 центров кластера). Я действительно ожидал исключения для более высоких показателей. Если это правильный подход, может кто-нибудь объяснить мне, откуда взялись эти другие значения (индексы 5-8)?
Я уверен, что есть и другие запутанные части, но я еще даже не обращался к ним, так как я застрял на этих двух довольно важных частях (я имею в виду, что такое kmeans, если вы не можете правильно начать кластеризацию).
Заранее спасибо за вашу помощь!
В каком формате должны быть данные?
руководство говорит:
Поддержка всех алгоритмов float
или же double
данные и может использовать расстояние l1 или l2 для кластеризации.
Вы указываете это при создании дескриптора kmeans, например:
VlKMeans *kmeans = vl_kmeans_new(VL_TYPE_FLOAT, VlDistanceL2);
эта матрица должна быть основной или основной строкой?
Должно быть в майор ряда, то есть: data + dimension * i
это i-й центр.
Как я могу получить доступ к информации центра кластера?
С vl_kmeans_get_centers
, Например, если вы работаете с float
-s:
/* no need to cast here since get centers returns a `void *` */
const float *centers = vl_kmeans_get_centers(kmeans);
(видеть это ответ по поводу актерского состава)
Общий размер (в байтах) этого массива sizeof(float) * dimension * numCenters
, Если вы хотите распечатать центры, вы можете сделать:
int i, j;
for (i = 0; i < numCenters; i++) {
printf("center # %d:\n", i);
for (j = 0; j < dimension; j++) {
printf(" coord[%d] = %f\n", j, centers[dimension * i + j]);
}
}