VLFeat kmeans C API 解释
VLFeat kmeans C API explanation
我正在尝试使用 VLFeat's kmeans implementation in C,但我很难理解它是如何工作的。
注意:我在C++程序中使用CAPI,所以我在这里发布的所有代码都是C++。此外,我使用的是 Eigean 头库,所以这就是那些 Matrix 数据类型的来源。
示例和 API 中不清楚的地方是:
- 数据必须采用什么格式? kmeans 库函数似乎需要一个一维数组,它可以从矩阵的支持中获取。但是,这个矩阵需要列主还是行主?也就是说,该函数如何知道区分数据的维度和不同的数据向量?
- 我如何实际访问集群中心信息?我 运行 一个测试,我声明我想要 5 个集群,但是使用上面 link 中的示例代码,我只 return 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 个聚类中心),我应该只有 none- 零值。我实际上希望为更高的索引抛出异常。如果这是正确的方法,有人可以向我解释这些其他值(索引 5-8)的来源吗?
我敢肯定还有其他令人困惑的部分,但我什至还没有解决它们,因为我一直停留在这两个非常重要的部分(我的意思是,如果你不能聚类,kmeans 是什么正确启动)。
提前感谢您的帮助!
What format does the data have to be in?
manual 说:
所有算法都支持float
或double
数据,可以使用l1或l2距离进行聚类.
您在创建 kmeans 句柄时指定,例如:
VlKMeans *kmeans = vl_kmeans_new(VL_TYPE_FLOAT, VlDistanceL2);
does this matrix need to be column major or row major?
必须在row major,即:data + dimension * i
是第i个中心。
How do I actually access the cluster center info?
与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);
(有关演员表请参阅此 answer)
此数组的总大小(以字节为单位)为 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]);
}
}
我正在尝试使用 VLFeat's kmeans implementation in C,但我很难理解它是如何工作的。
注意:我在C++程序中使用CAPI,所以我在这里发布的所有代码都是C++。此外,我使用的是 Eigean 头库,所以这就是那些 Matrix 数据类型的来源。
示例和 API 中不清楚的地方是:
- 数据必须采用什么格式? kmeans 库函数似乎需要一个一维数组,它可以从矩阵的支持中获取。但是,这个矩阵需要列主还是行主?也就是说,该函数如何知道区分数据的维度和不同的数据向量?
- 我如何实际访问集群中心信息?我 运行 一个测试,我声明我想要 5 个集群,但是使用上面 link 中的示例代码,我只 return 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 个聚类中心),我应该只有 none- 零值。我实际上希望为更高的索引抛出异常。如果这是正确的方法,有人可以向我解释这些其他值(索引 5-8)的来源吗?
我敢肯定还有其他令人困惑的部分,但我什至还没有解决它们,因为我一直停留在这两个非常重要的部分(我的意思是,如果你不能聚类,kmeans 是什么正确启动)。
提前感谢您的帮助!
What format does the data have to be in?
manual 说:
所有算法都支持float
或double
数据,可以使用l1或l2距离进行聚类.
您在创建 kmeans 句柄时指定,例如:
VlKMeans *kmeans = vl_kmeans_new(VL_TYPE_FLOAT, VlDistanceL2);
does this matrix need to be column major or row major?
必须在row major,即:data + dimension * i
是第i个中心。
How do I actually access the cluster center info?
与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);
(有关演员表请参阅此 answer)
此数组的总大小(以字节为单位)为 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]);
}
}