VLFeat kmeans C API объяснение

Я пытаюсь использовать Реализация kmeans VLFeat в C но мне очень трудно понять, как это работает.

Примечание: я использую C API в программе C ++, поэтому любой код, размещенный мной здесь, является C ++. Кроме того, я использую библиотеку заголовков Eigean, вот откуда берутся эти типы данных Matrix.

Из этого примера и API неясны следующие вещи:

  1. В каком формате должны быть данные? Библиотечные функции kmeans, по-видимому, требуют одномерного массива, который может быть взят из основы матрицы. Однако должна ли эта матрица быть основной или основной строкой? То есть как функция узнает, что нужно различать измерения данных и разные векторы данных?
  2. Как я могу получить доступ к информации центра кластера? Я выполнил тест, в котором объявил, что мне нужно 5 кластеров, но, используя приведенный выше пример кода, я получаю только 1.

Код:

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, если вы не можете правильно начать кластеризацию).

Заранее спасибо за вашу помощь!

1

Решение

В каком формате должны быть данные?

руководство говорит:

Поддержка всех алгоритмов 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]);
}
}
2

Другие решения


По вопросам рекламы [email protected]