2017-02-15 68 views
8

我正在使用GA Package,我的目标是找到k-means聚类算法的最佳初始质心位置。我的数据是在TF-IDF得分的话稀疏矩阵和可下载here.下面是一些我已经实现了阶段:K-means:初始中心并不明显

0库和数据集

library(clusterSim)   ## for index.DB() 
library(GA)     ## for ga() 

corpus <- read.csv("Corpus_EnglishMalay_tfidf.csv")  ## a dataset of 5000 x 1168 

1.二进制编码并生成初始种群。

k_min <- 15 

initial_population <- function(object) { 
    ## generate a population to turn-on 15 cluster bits 
    init <- t(replicate([email protected], sample(rep(c(1, 0), c(k_min, [email protected] - k_min))), TRUE)) 
    return(init) 
} 

2.健身功能最大限度地减少戴维斯 - 尔丁(DB)指数。我在哪里评估从initial_population生成的每个解决方案的DBI。

DBI2 <- function(x) { 
    ## x is a vector of solution of nBits 
    ## exclude first column of corpus 
    initial_centroid <- corpus[x==1, -1] 
    cl <- kmeans(corpus[-1], initial_centroid) 
    dbi <- index.DB(corpus[-1], cl=cl$cluster, centrotypes = "centroids") 
    score <- -dbi$DB 
    return(score) 
} 

3.运行GA。使用这些设置。

g2<- ga(type = "binary", 
    fitness = DBI2, 
    population = initial_population, 
    selection = ga_rwSelection, 
    crossover = gabin_spCrossover, 
    pcrossover = 0.8, 
    pmutation = 0.1, 
    popSize = 100, 
    nBits = nrow(corpus), 
    seed = 123) 

4.问题。 kmeans(语料库[-1],initial_centroid)中的错误:初始中心不明确。

我发现了一个类似的问题here,其中用户还必须使用一个参数动态传递要使用的簇数。这是通过硬编码簇的数量来解决的。但是对于我的情况,我确实需要动态传递簇的数量,因为它是从随机生成的二进制向量中进入的,其中那些1's将表示初始质心。

kmeans()code检查,我注意到,错误是由重复的中心造成的:

if(any(duplicated(centers))) 
     stop("initial centers are not distinct") 

我编辑的kmeans功能与trace打印出复制中心。输出:

[1] "206" "520" "564" "1803" "2059" "2163" "2652" "2702" "3195" "3206" "3254" "3362" "3375" 
[14] "4063" "4186" 

这都说明在随机选择initial_centroids没有重复,我不知道为什么这个错误持续发生。还有什么会导致这个错误?

P/S:我明白有些人可能会建议GA + K-means并不是一个好主意。但我希望能完成我已经开始的工作。最好把这个问题看作K均值问题(至少在解决initial centers are not distinct错误时)。

回答

4

遗传算法不适合根据问题的性质优化k-均值 - 初始化种子相互作用太多,ga不会比随机取样所有可能的种子好。

所以我的主要建议是不要在这里使用遗传算法!

如果你坚持,你需要做的是检测不良参数,然后简单地返回一个坏分数,因为它不会“生存”。

+0

我在这个问题总初学者,你能解释更多关于“初始化种子互动太多”?这是什么造成了“初始中心不明显”的问题?并感谢您就如何消除不良染色体的建议,这对我来说是新的! –

2

要回答你的问题只是做:

any(corpus[520, -1] != corpus[564, -1]) 

你的520和564行的corpus是相同的,在属性row.names唯一的区别,请参阅:

identical(colnames(corpus[520, -1]), colnames(corpus[564, -1])) # just to be sure 
rownames(corpus[520, -1]) 
rownames(corpus[564, -1]) 

关于GA和k-means,参见例如:

  1. Bashar Al-Shboul, Myaeng Sung-Hyon, "Initializing K-Means using Genetic Algorithms", World Academy of Science, Engineering & Technology, Jun2009, Issue 30, p. 114,(特别是第IIB部分);或
  2. BAIN KHUSUL KHOTIMAH, FIRLI IRHAMNI, AND TRI SUNDARWATI, "A GENETIC ALGORITHM FOR OPTIMIZED INITIAL CENTERS K-MEANS CLUSTERING IN SMEs", Journal of Theoretical and Applied Information Technology, 2016, Vol. 90, No. 1
+0

谢谢指出。所以在两行中的值相同的情况下,处理它的更好方法是什么? –

+1

我最初的尝试是确保GA创建具有独特质心的个体(即用于k-means评估的'initial_centroid'),因此您必须创建自定义交叉和变异函数。这就是为什么“默认”遗传算法需要针对每个正在解决的问题进行定制的原因。另一个更简单但几乎肯定更糟的想法是检查'initial_centroid'的唯一性,如果有任何重复项返回一个“非常差”的分数,这个人希望GA从总体中删除它们。 –