X-Git-Url: https://git.auder.net/doc/html/img/rock_paper_scissors_lizard_spock.gif?a=blobdiff_plain;f=epclust%2FR%2Fmain.R;h=9e9b6411088f031a31e72bd3cdcc361430807378;hb=0486fbadb122cb4d78c5d9f248c29800a59eb24e;hp=a039d1cc029f94f641d6943b7aacc63d27c38002;hpb=37c82bbafbffc19e8b47a521952bac58f189e9ea;p=epclust.git
diff --git a/epclust/R/main.R b/epclust/R/main.R
index a039d1c..9e9b641 100644
--- a/epclust/R/main.R
+++ b/epclust/R/main.R
@@ -11,7 +11,7 @@
#' \item Divide series into \code{ntasks} groups to process in parallel. In each task:
#' \enumerate{
#' \item iterate the first clustering algorithm on its aggregated outputs,
-#' on inputs of size \code{nb_items_clust}
+#' on inputs of size \code{nb_items_clust1}
#' \item optionally, if WER=="mix":
#' a) compute the K1 synchrones curves,
#' b) compute WER distances (K1xK1 matrix) between synchrones and
@@ -40,12 +40,15 @@
#' @param K1 Number of clusters to be found after stage 1 (K1 << N [number of series])
#' @param K2 Number of clusters to be found after stage 2 (K2 << K1)
#' @param nb_series_per_chunk (Maximum) number of series to retrieve in one batch
-#' @param algo_clust1 Clustering algorithm for stage 1. A function which takes (data, K)
+#' @param algoClust1 Clustering algorithm for stage 1. A function which takes (data, K)
#' as argument where data is a matrix in columns and K the desired number of clusters,
-#' and outputs K medoids ranks. Default: PAM
-#' @param algo_clust2 Clustering algorithm for stage 2. A function which takes (dists, K)
+#' and outputs K medoids ranks. Default: PAM.
+#' In our method, this function is called on iterated medoids during stage 1
+#' @param algoClust2 Clustering algorithm for stage 2. A function which takes (dists, K)
#' as argument where dists is a matrix of distances and K the desired number of clusters,
-#' and outputs K clusters representatives (curves). Default: k-means
+#' and outputs K clusters representatives (curves). Default: PAM.
+#' In our method, this function is called on a matrix of K1 x K1 (WER) distances computed
+# between synchrones
#' @param nb_items_clust1 (~Maximum) number of items in input of the clustering algorithm
#' for stage 1. At worst, a clustering algorithm might be called with ~2*nb_items_clust1
#' items; but this could only happen at the last few iterations.
@@ -53,6 +56,7 @@
#' @param contrib_type Type of contribution: "relative", "logit" or "absolute" (any prefix)
#' @param WER "end" to apply stage 2 after stage 1 has fully iterated, or "mix" to apply
#' stage 2 at the end of each task
+#' @param sync_mean TRUE to compute a synchrone as a mean curve, FALSE for a sum
#' @param random TRUE (default) for random chunks repartition
#' @param ntasks Number of tasks (parallel iterations to obtain K1 [if WER=="end"]
#' or K2 [if WER=="mix"] medoids); default: 1.
@@ -136,10 +140,10 @@
#' @export
claws <- function(getSeries, K1, K2, nb_series_per_chunk,
nb_items_clust1=7*K1,
- algo_clust1=function(data,K) cluster::pam(data,K,diss=FALSE),
- algo_clust2=function(dists,K) stats::kmeans(dists,K,iter.max=50,nstart=3),
+ algoClust1=function(data,K) cluster::pam(t(data),K,diss=FALSE)$id.med,
+ algoClust2=function(dists,K) t( cluster::pam(dists,K,diss=TRUE)$medoids ),
wav_filt="d8", contrib_type="absolute",
- WER="end",
+ WER="end",sync_mean=TRUE,
random=TRUE,
ntasks=1, ncores_tasks=1, ncores_clust=4,
sep=",",
@@ -162,17 +166,15 @@ claws <- function(getSeries, K1, K2, nb_series_per_chunk,
stop("'K1' cannot exceed 'nb_series_per_chunk'")
nb_items_clust1 <- .toInteger(nb_items_clust1, function(x) x>K1)
random <- .toLogical(random)
- tryCatch
- (
- {ignored <- wavelets::wt.filter(wav_filt)},
- error = function(e) stop("Invalid wavelet filter; see ?wavelets::wt.filter")
- )
+ tryCatch( {ignored <- wavelets::wt.filter(wav_filt)},
+ error = function(e) stop("Invalid wavelet filter; see ?wavelets::wt.filter") )
ctypes = c("relative","absolute","logit")
contrib_type = ctypes[ pmatch(contrib_type,ctypes) ]
if (is.na(contrib_type))
stop("'contrib_type' in {'relative','absolute','logit'}")
if (WER!="end" && WER!="mix")
stop("'WER': in {'end','mix'}")
+ sync_mean <- .toLogical(sync_mean)
random <- .toLogical(random)
ntasks <- .toInteger(ntasks, function(x) x>=1)
ncores_tasks <- .toInteger(ncores_tasks, function(x) x>=1)
@@ -234,8 +236,8 @@ claws <- function(getSeries, K1, K2, nb_series_per_chunk,
# Initialize parallel runs: outfile="" allow to output verbose traces in the console
# under Linux. All necessary variables are passed to the workers.
cl = parallel::makeCluster(ncores_tasks, outfile="")
- varlist = c("getSeries","getContribs","K1","K2","algo_clust1","algo_clust2",
- "nb_series_per_chunk","nb_items_clust","ncores_clust","sep",
+ varlist = c("getSeries","getContribs","K1","K2","algoClust1","algoClust2",
+ "nb_series_per_chunk","nb_items_clust1","ncores_clust","sep",
"nbytes","endian","verbose","parll")
if (WER=="mix")
varlist = c(varlist, "medoids_file")
@@ -253,14 +255,14 @@ claws <- function(getSeries, K1, K2, nb_series_per_chunk,
if (parll && ntasks>1)
require("epclust", quietly=TRUE)
indices_medoids = clusteringTask1(
- inds, getContribs, K1, nb_series_per_chunk, ncores_clust, verbose, parll)
+ inds, getContribs, K1, algoClust1, nb_series_per_chunk, ncores_clust, verbose, parll)
if (WER=="mix")
{
if (parll && ntasks>1)
require("bigmemory", quietly=TRUE)
medoids1 = bigmemory::as.big.matrix( getSeries(indices_medoids) )
- medoids2 = clusteringTask2(medoids1, K2, getSeries, nb_curves, nb_series_per_chunk,
- nbytes, endian, ncores_clust, verbose, parll)
+ medoids2 = clusteringTask2(medoids1, K2, algoClust2, getSeries, nb_curves,
+ nb_series_per_chunk, sync_mean, nbytes, endian, ncores_clust, verbose, parll)
binarize(medoids2, medoids_file, nb_series_per_chunk, sep, nbytes, endian)
return (vector("integer",0))
}
@@ -321,11 +323,11 @@ claws <- function(getSeries, K1, K2, nb_series_per_chunk,
# Run step2 on resulting indices or series (from file)
if (verbose)
cat("...Run final // stage 1 + stage 2\n")
- indices_medoids = clusteringTask1(
- indices, getContribs, K1, nb_series_per_chunk, ncores_tasks*ncores_clust, verbose, parll)
+ indices_medoids = clusteringTask1(indices, getContribs, K1, algoClust1,
+ nb_series_per_chunk, ncores_tasks*ncores_clust, verbose, parll)
medoids1 = bigmemory::as.big.matrix( getSeries(indices_medoids) )
- medoids2 = clusteringTask2(medoids1, K2, getRefSeries, nb_curves, nb_series_per_chunk,
- nbytes, endian, ncores_tasks*ncores_clust, verbose, parll)
+ medoids2 = clusteringTask2(medoids1, K2, algoClust2, getRefSeries, nb_curves,
+ nb_series_per_chunk, sync_mean, nbytes, endian, ncores_tasks*ncores_clust, verbose, parll)
# Cleanup: remove temporary binary files and their folder
unlink(bin_dir, recursive=TRUE)