X-Git-Url: https://git.auder.net/?p=epclust.git;a=blobdiff_plain;f=epclust%2FR%2Fclustering.R;h=6090517c6b6464d4c253ba52b8efdf29cb56c823;hp=578b2f399035023eb68b0b004be10f18d87cac84;hb=0e2dce80a3fddaca50c96c6c27a8b32468095d6c;hpb=48108c3999d28d973443fa5e78f73a0a9f2bfc07 diff --git a/epclust/R/clustering.R b/epclust/R/clustering.R index 578b2f3..6090517 100644 --- a/epclust/R/clustering.R +++ b/epclust/R/clustering.R @@ -1,9 +1,9 @@ # Cluster one full task (nb_curves / ntasks series) -clusteringTask = function(indices_clust) +clusteringTask = function(indices, ncores) { - cl_clust = parallel::makeCluster(ncores_clust) - parallel::clusterExport(cl_clust, - varlist=c("K1","K2","WER"), + cl = parallel::makeCluster(ncores) + parallel::clusterExport(cl, + varlist=c("K1","getCoefs"), envir=environment()) repeat { @@ -13,44 +13,45 @@ clusteringTask = function(indices_clust) min(nb_series_per_chunk*i,length(indices_clust)), length(indices_clust) ) indices_clust[(nb_series_per_chunk*(i-1)+1):upper_bound] }) - indices_clust = parallel::parLapply(cl, indices_workers, clusterChunk) - # TODO: soft condition between K2 and K1, before applying final WER step - if ((WER=="end" && length(indices_clust)==K1) || (WER=="mix" && length(indices_clust)==K2)) + indices_clust = unlist( parallel::parLapply(cl, indices_workers, function(indices) + computeClusters1(indices, getCoefs, K1)) ) + if (length(indices_clust) == K1) break } parallel::stopCluster(cl_clust) - unlist(indices_clust) + if (WER == "end") + return (indices_clust) + #WER=="mix" + computeClusters2(indices_clust, K2, getSeries, to_file=TRUE) } +# Apply the clustering algorithm (PAM) on a coeffs or distances matrix +computeClusters1 = function(indices, getCoefs, K1) + indices[ cluster::pam(getCoefs(indices), K1, diss=FALSE)$id.med ] + # Cluster a chunk of series inside one task (~max nb_series_per_chunk) -clusterChunk = function(indices_chunk) +computeClusters2 = function(indices, K2, getSeries, to_file) { - coeffs = readCoeffs(indices_chunk) - cl = computeClusters(as.matrix(coeffs[,2:ncol(coeffs)]), K1, diss=FALSE) + if (is.null(indices)) + { + #get series from file + } +#Puis K-means après WER... if (WER=="mix" > 0) { - curves = computeSynchrones(cl) + curves = computeSynchrones(indices) dists = computeWerDists(curves) - cl = computeClusters(dists, K2, diss=TRUE) + indices = computeClusters(dists, K2, diss=TRUE) } - indices_chunk[cl] -} - -# Apply the clustering algorithm (PAM) on a coeffs or distances matrix -computeClusters = function(md, K, diss) -{ - if (!require(cluster, quietly=TRUE)) - stop("Unable to load cluster library") - cluster::pam(md, K, diss=diss)$id.med + if (to_file) + #write results to file (JUST series ; no possible ID here) } # Compute the synchrones curves (sum of clusters elements) from a clustering result -computeSynchrones = function(indices) -{ - colSums( getData(indices) ) -} +computeSynchrones = function(inds) + sapply(seq_along(inds), colMeans(getSeries(inds[[i]]$indices,inds[[i]]$ids))) -# Compute the WER distance between the synchrones curves +# Compute the WER distance between the synchrones curves (in columns) computeWerDist = function(curves) { if (!require("Rwave", quietly=TRUE)) @@ -73,7 +74,7 @@ computeWerDist = function(curves) # (normalized) observations node with CWT Xcwt4 <- lapply(seq_len(n), function(i) { - ts <- scale(ts(curves[i,]), center=TRUE, scale=scaled) + ts <- scale(ts(curves[,i]), center=TRUE, scale=scaled) totts.cwt = Rwave::cwt(ts,totnoct,nvoice,w0,plot=0) ts.cwt = totts.cwt[,s0log:(s0log+noctave*nvoice)] #Normalization @@ -88,7 +89,7 @@ computeWerDist = function(curves) { for (j in (i+1):n) { - #TODO: later, compute CWT here (because not enough storage space for 32M series) + #TODO: later, compute CWT here (because not enough storage space for 200k series) # 'circular=TRUE' is wrong, should just take values on the sides; to rewrite in C num <- filter(Mod(Xcwt4[[i]] * Conj(Xcwt4[[j]])), fcoefs, circular=TRUE) WX <- filter(Mod(Xcwt4[[i]] * Conj(Xcwt4[[i]])), fcoefs, circular=TRUE)