Это может или не может быть полезно для вас, в зависимости от ваших потребностей. Предполагая, что вы заинтересованы в сходстве между кластеризационными заданиями:
Коэффициент подобия Жакара или индекс Жакара могут быть использованы для расчета сходства двух кластерных назначений.
Учитывая маркировки L1
и L2
, Бен-Гур, Elisseeff и Гийон (2002) показали , что индекс Jaccard можно рассчитать с помощью дот-продукты промежуточной матрицы. Приведенный ниже код использует это для быстрого вычисления индекса Жакара без необходимости хранить промежуточные матрицы в памяти.
Код написан на C ++, но может быть загружен в R с помощью sourceCpp
команды.
/**
* The Jaccard Similarity Coefficient or Jaccard Index is used to compare the
* similarity/diversity of sample sets. It is defined as the size of the
* intersection of the sets divided by the size of the union of the sets. Here,
* it is used to determine how similar to clustering assignments are.
*
* INPUTS:
* L1: A list. Each element of the list is a number indicating the cluster
* assignment of that number.
* L2: The same as L1. Must be the same length as L1.
*
* RETURNS:
* The Jaccard Similarity Index
*
* SIDE-EFFECTS:
* None
*
* COMPLEXITY:
* Time: O(K^2+n), where K = number of clusters
* Space: O(K^2)
*
* SOURCES:
* Asa Ben-Hur, Andre Elisseeff, and Isabelle Guyon (2001) A stability based
* method for discovering structure in clustered data. Biocomputing 2002: pp.
* 6-17.
*/
// [[Rcpp::export]]
NumericVector JaccardIndex(const NumericVector L1, const NumericVector L2){
int n = L1.size();
int K = max(L1);
int overlaps[K][K];
int cluster_sizes1[K], cluster_sizes2[K];
for(int i = 0; i < K; i++){ // We can use NumericMatrix (default 0)
cluster_sizes1[i] = 0;
cluster_sizes2[i] = 0;
for(int j = 0; j < K; j++)
overlaps[i][j] = 0;
}
//O(n) time. O(K^2) space. Determine the size of each cluster as well as the
//size of the overlaps between the clusters.
for(int i = 0; i < n; i++){
cluster_sizes1[(int)L1[i] - 1]++; // -1's account for zero-based indexing
cluster_sizes2[(int)L2[i] - 1]++;
overlaps[(int)L1[i] - 1][(int)L2[i] - 1]++;
}
// O(K^2) time. O(1) space. Square the overlap values.
int C1dotC2 = 0;
for(int j = 0; j < K; j++){
for(int k = 0; k < K; k++){
C1dotC2 += pow(overlaps[j][k], 2);
}
}
// O(K) time. O(1) space. Square the cluster sizes
int C1dotC1 = 0, C2dotC2 = 0;
for(int i = 0; i < K; i++){
C1dotC1 += pow(cluster_sizes1[i], 2);
C2dotC2 += pow(cluster_sizes2[i], 2);
}
return NumericVector::create((double)C1dotC2/(double)(C1dotC1+C2dotC2-C1dotC2));
}
vegan
пакете уже реализован ряд индексов подобия (включая Jaccard) . Я думаю, что они также довольно хорошо оптимизированы для скорости.