From edb45e27966cf741d0443ee1228a707f17a6e433 Mon Sep 17 00:00:00 2001 From: vwmaus Date: Sun, 27 Nov 2016 15:00:49 +0100 Subject: [PATCH] Fix class order of class definitions. --- DESCRIPTION | 3 +- NAMESPACE | 2 +- R/class-twdtwMatches.R | 5 +- R/class-twdtwRaster.R | 3 +- R/class-twdtwTimeSeries.R | 6 +- R/crossValidation.R | 110 ++++++++++++++++++++ R/miscellaneous.R | 112 +-------------------- man/{Assessment.Rd => Cross-validation.Rd} | 21 ++-- man/twdtwRaster-class.Rd | 1 + man/twdtwTimeSeries-class.Rd | 1 + vignettes/applying_twdtw.Rmd | 6 +- 11 files changed, 137 insertions(+), 133 deletions(-) create mode 100644 R/crossValidation.R rename man/{Assessment.Rd => Cross-validation.Rd} (80%) diff --git a/DESCRIPTION b/DESCRIPTION index 84068e3..d258445 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -53,10 +53,11 @@ Maintainer: Victor Maus LazyData: true RoxygenNote: 5.0.1 Collate: + 'class-twdtwTimeSeries.R' 'class-twdtwMatches.R' 'class-twdtwRaster.R' - 'class-twdtwTimeSeries.R' 'createPatterns.R' + 'crossValidation.R' 'data.R' 'dtw.R' 'dwtSat.R' diff --git a/NAMESPACE b/NAMESPACE index 7797a07..97c63fc 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -59,8 +59,8 @@ exportMethods(show) exportMethods(splitDataset) exportMethods(subset) exportMethods(twdtwApply) -exportMethods(twdtwAssess) exportMethods(twdtwClassify) +exportMethods(twdtwCrossValidation) exportMethods(twdtwMatches) exportMethods(twdtwRaster) exportMethods(twdtwTimeSeries) diff --git a/R/class-twdtwMatches.R b/R/class-twdtwMatches.R index 37b8746..2c266b2 100644 --- a/R/class-twdtwMatches.R +++ b/R/class-twdtwMatches.R @@ -29,6 +29,8 @@ #' the same length as \code{timeseries} or a list of twdtwMatches. #' @param ... objects of class twdtwMatches. #' +#' @include class-twdtwTimeSeries.R +#' #' @section Slots : #' \describe{ #' \item{\code{timeseries}:}{An object of class \code{\link[dtwSat]{twdtwTimeSeries-class}} with the satellite time series.} @@ -73,8 +75,7 @@ #' length(matches) #' matches NULL -setOldClass("twdtwTimeSeries") -twdtwMatches = setClass( +setClass( Class = "twdtwMatches", slots = c(timeseries="twdtwTimeSeries", patterns = "twdtwTimeSeries", diff --git a/R/class-twdtwRaster.R b/R/class-twdtwRaster.R index cc16a61..f5814f4 100644 --- a/R/class-twdtwRaster.R +++ b/R/class-twdtwRaster.R @@ -83,7 +83,7 @@ #' rts = new("twdtwRaster", timeseries = evi, timeline = timeline) #' NULL -twdtwRaster = setClass( +setClass( Class = "twdtwRaster", slots = c(timeseries = "list", timeline="Date", layers = "character", labels = "character", levels="numeric"), validity = function(object){ @@ -158,6 +158,7 @@ setGeneric(name = "twdtwRaster", #' @inheritParams twdtwRaster +#' @aliases twdtwRaster-create #' @describeIn twdtwRaster Create object of class twdtwRaster. #' #' @examples diff --git a/R/class-twdtwTimeSeries.R b/R/class-twdtwTimeSeries.R index c7d2834..b2a58fe 100644 --- a/R/class-twdtwTimeSeries.R +++ b/R/class-twdtwTimeSeries.R @@ -12,7 +12,6 @@ # # ############################################################### - #' @title class "twdtwTimeSeries" #' @name twdtwTimeSeries-class #' @aliases twdtwTimeSeries @@ -50,7 +49,7 @@ #' ncol(ptt) #' dim(ptt) NULL -twdtwTimeSeries = setClass( +setClass( Class = "twdtwTimeSeries", slots = c(timeseries = "list", labels = "factor"), validity = function(object){ @@ -96,6 +95,7 @@ setGeneric(name = "twdtwTimeSeries", ) #' @inheritParams twdtwTimeSeries-class +#' @aliases twdtwTimeSeries-create #' @describeIn twdtwTimeSeries Create object of class twdtwTimeSeries. #' #' @examples @@ -146,4 +146,4 @@ setMethod(f = "twdtwTimeSeries", - \ No newline at end of file + diff --git a/R/crossValidation.R b/R/crossValidation.R new file mode 100644 index 0000000..2402be9 --- /dev/null +++ b/R/crossValidation.R @@ -0,0 +1,110 @@ +#' @title Cross-validation +#' @name Cross-validation +#' +#' @author Victor Maus, \email{vwmaus1@@gmail.com} +#' +#' @description This functions create data partitions and compute Cross-validation metrics. +#' +#' @param object an object of class \code{\link[dtwSat]{twdtwTimeSeries}} or +#' \code{\link[dtwSat]{twdtwMatches}}. +#' +#' @param times Number of partitions to create. +#' +#' @param p the percentage of data that goes to training. +#' See \code{\link[caret]{createDataPartition}} for details. +#' +#' @param ... Other arguments to be passed to \code{\link[dtwSat]{createPatterns}}. +#' +#' @param matrix logical. If TRUE retrieves the confusion matrix. +#' FALSE retrieves User's Accuracy (UA) and Producer's Accuracy (PA). +#' Dafault is FALSE. +#' +#' @details +#' \describe{ +#' \item{\code{splitDataset}:}{This function splits the a set of time +#' series into training and validation. The function uses stratified +#' sampling and a simple random sampling for each stratum. Each data partition +#' returned by this function has the temporal patterns and a set of time series for +#' validation.} +#' \item{\code{twdtwCrossValidation}:}{The function \code{splitDataset} performs the Cross-validation of +#' the classification based on the labels of the classified time series +#' (Reference) and the labels of the classification (Predicted). This function +#' returns a data.frame with User's and Produce's Accuracy or a list for confusion +#' matrices.} +#' } +#' +#' @seealso +#' \code{\link[dtwSat]{twdtwMatches-class}}, +#' \code{\link[dtwSat]{twdtwApply}}, and +#' \code{\link[dtwSat]{twdtwClassify}}. +#' +#' @examples +#' \dontrun{ +#' load(system.file("lucc_MT/field_samples_ts.RData", package="dtwSat")) +#' set.seed(1) +#' partitions = splitDataset(field_samples_ts, p=0.1, times=5, +#' freq = 8, formula = y ~ s(x, bs="cc")) +#' log_fun = logisticWeight(alpha=-0.1, beta=50) +#' twdtw_res = lapply(partitions, function(x){ +#' res = twdtwApply(x = x$ts, y = x$patterns, weight.fun = log_fun, n=1) +#' twdtwClassify(x = res) +#' }) +#' cross_validation = twdtwCrossValidation(twdtw_res) +# head(cross_validation, 5) +#' } +NULL + +setGeneric("splitDataset", function(object, times, p, ...) standardGeneric("splitDataset")) + +#' @rdname Cross-validation +#' @aliases splitDataset +#' @export +setMethod("splitDataset", "twdtwTimeSeries", + function(object, times=1, p=0.1, ...) splitDataset.twdtwTimeSeries(object, times=times, p=p, ...)) + +splitDataset.twdtwTimeSeries = function(object, times, p, ...){ + + partitions = createDataPartition(y = labels(object), times, p, list = TRUE) + + res = lapply(partitions, function(I){ + training_ts = subset(object, I) + validation_ts = subset(object, -I) + patt = createPatterns(training_ts, ...) + list(patterns=patt, ts=validation_ts) + }) + + res +} + +setGeneric("twdtwCrossValidation", function(object, matrix=FALSE) standardGeneric("twdtwCrossValidation")) + +#' @rdname Cross-validation +#' @aliases twdtwCrossValidation +#' @export +setMethod("twdtwCrossValidation", "list", + function(object, matrix) twdtwCrossValidation.twdtwTimeSeries(object, matrix=matrix)) + +twdtwCrossValidation.twdtwTimeSeries = function(object, matrix){ + + res = lapply(object, function(x){ + ref = labels(x)$timeseries + levels = sort(as.character(unique(ref))) + labels = levels + # pred = factor(do.call("rbind", x[])$label, levels, labels) + pred = do.call("rbind", lapply(x[], function(xx) as.character(xx$label[which.min(xx$distance)])) ) + ref = factor(ref, levels, labels) + table(Reference=ref, Predicted=pred) + }) + + if(!matrix){ + res = do.call("rbind", lapply(seq_along(res), function(i){ + x = res[[i]] + Users = diag(x) / rowSums(x) + Producers = diag(x) / colSums(x) + data.frame(resample=i,label=names(Users), UA = Users, PA = Producers, row.names=NULL) + })) + } + + res + +} diff --git a/R/miscellaneous.R b/R/miscellaneous.R index 881a5ee..a53af69 100644 --- a/R/miscellaneous.R +++ b/R/miscellaneous.R @@ -85,6 +85,7 @@ setMethod("shiftDates", "list", function(object, year) shiftDates(twdtwTimeSeries(object), year=year)[]) +setOldClass("zoo") #' @rdname shiftDates #' @aliases shiftDates-zoo #' @export @@ -104,115 +105,4 @@ shiftDates.twdtwTimeSeries = function(x, year){ } -#' @title Classification assessment -#' @name Assessment -#' -#' @author Victor Maus, \email{vwmaus1@@gmail.com} -#' -#' @description This functions create data partitions and compute assessment metrics. -#' -#' @param object an object of class \code{\link[dtwSat]{twdtwTimeSeries}} or -#' \code{\link[dtwSat]{twdtwMatches}}. -#' -#' @param times Number of partitions to create. -#' -#' @param p the percentage of data that goes to training. -#' See \code{\link[caret]{createDataPartition}} for details. -#' -#' @param ... Other arguments to be passed to \code{\link[dtwSat]{createPatterns}}. -#' -#' @param matrix logical. If TRUE retrieves the confusion matrix. -#' FALSE retrieves User's Accuracy (UA) and Producer's Accuracy (PA). -#' Dafault is FALSE. -#' -#' @details -#' \describe{ -#' \item{\code{splitDataset}:}{This function splits the a set of time -#' series into training and validation. The function uses stratified -#' sampling and a simple random sampling for each stratum. Each data partition -#' returned by this function has the temporal patterns and a set of time series for -#' validation.} -#' \item{\code{twdtwAssess}:}{The function \code{splitDataset} performs the assessment of -#' the classification based on the labels of the classified time series -#' (Reference) and the labels of the classification (Predicted). This function -#' returns a data.frame with User's and Produce's Accuracy or a list for confusion -#' matrices.} -#' } -#' -#' @seealso -#' \code{\link[dtwSat]{twdtwMatches-class}}, -#' \code{\link[dtwSat]{twdtwApply}}, and -#' \code{\link[dtwSat]{twdtwClassify}}. -#' -#' @examples -#' \dontrun{ -#' load(system.file("lucc_MT/field_samples_ts.RData", package="dtwSat")) -#' set.seed(1) -#' partitions = splitDataset(field_samples_ts, p=0.1, times=5, -#' freq = 8, formula = y ~ s(x, bs="cc")) -#' log_fun = logisticWeight(alpha=-0.1, beta=50) -#' twdtw_res = lapply(partitions, function(x){ -#' res = twdtwApply(x = x$ts, y = x$patterns, weight.fun = log_fun, n=1) -#' twdtwClassify(x = res) -#' }) -#' assessment = twdtwAssess(twdtw_res) -#' head(assessment, 5) -#' } -NULL - -setGeneric("splitDataset", function(object, times, p, ...) standardGeneric("splitDataset")) - -#' @rdname Assessment -#' @aliases splitDataset -#' @export -setMethod("splitDataset", "twdtwTimeSeries", - function(object, times=1, p=0.1, ...) splitDataset.twdtwTimeSeries(object, times=times, p=p, ...)) - -splitDataset.twdtwTimeSeries = function(object, times, p, ...){ - - partitions = createDataPartition(y = labels(object), times, p, list = TRUE) - - res = lapply(partitions, function(I){ - training_ts = subset(object, I) - validation_ts = subset(object, -I) - patt = createPatterns(training_ts, ...) - list(patterns=patt, ts=validation_ts) - }) - - res -} - - -setGeneric("twdtwAssess", function(object, matrix=FALSE) standardGeneric("twdtwAssess")) - -#' @rdname Assessment -#' @aliases twdtwAssess -#' @export -setMethod("twdtwAssess", "list", - function(object, matrix) twdtwAssess.twdtwTimeSeries(object, matrix=matrix)) - -twdtwAssess.twdtwTimeSeries = function(object, matrix){ - - res = lapply(object, function(x){ - ref = labels(x)$timeseries - levels = sort(as.character(unique(ref))) - labels = levels - # pred = factor(do.call("rbind", x[])$label, levels, labels) - pred = do.call("rbind", lapply(x[], function(xx) as.character(xx$label[which.min(xx$distance)])) ) - ref = factor(ref, levels, labels) - table(Reference=ref, Predicted=pred) - }) - - if(!matrix){ - res = do.call("rbind", lapply(seq_along(res), function(i){ - x = res[[i]] - Users = diag(x) / rowSums(x) - Producers = diag(x) / colSums(x) - data.frame(resample=i,label=names(Users), UA = Users, PA = Producers, row.names=NULL) - })) - } - - res - -} diff --git a/man/Assessment.Rd b/man/Cross-validation.Rd similarity index 80% rename from man/Assessment.Rd rename to man/Cross-validation.Rd index b7b1e27..3ee08f8 100644 --- a/man/Assessment.Rd +++ b/man/Cross-validation.Rd @@ -1,17 +1,17 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/miscellaneous.R +% Please edit documentation in R/crossValidation.R \docType{methods} -\name{Assessment} -\alias{Assessment} +\name{Cross-validation} +\alias{Cross-validation} \alias{splitDataset} \alias{splitDataset,twdtwTimeSeries-method} -\alias{twdtwAssess} -\alias{twdtwAssess,list-method} -\title{Classification assessment} +\alias{twdtwCrossValidation} +\alias{twdtwCrossValidation,list-method} +\title{Cross-validation} \usage{ \S4method{splitDataset}{twdtwTimeSeries}(object, times = 1, p = 0.1, ...) -\S4method{twdtwAssess}{list}(object, matrix = FALSE) +\S4method{twdtwCrossValidation}{list}(object, matrix = FALSE) } \arguments{ \item{object}{an object of class \code{\link[dtwSat]{twdtwTimeSeries}} or @@ -29,7 +29,7 @@ FALSE retrieves User's Accuracy (UA) and Producer's Accuracy (PA). Dafault is FALSE.} } \description{ -This functions create data partitions and compute assessment metrics. +This functions create data partitions and compute Cross-validation metrics. } \details{ \describe{ @@ -38,7 +38,7 @@ This functions create data partitions and compute assessment metrics. sampling and a simple random sampling for each stratum. Each data partition returned by this function has the temporal patterns and a set of time series for validation.} - \item{\code{twdtwAssess}:}{The function \code{splitDataset} performs the assessment of + \item{\code{twdtwCrossValidation}:}{The function \code{splitDataset} performs the Cross-validation of the classification based on the labels of the classified time series (Reference) and the labels of the classification (Predicted). This function returns a data.frame with User's and Produce's Accuracy or a list for confusion @@ -56,8 +56,7 @@ twdtw_res = lapply(partitions, function(x){ res = twdtwApply(x = x$ts, y = x$patterns, weight.fun = log_fun, n=1) twdtwClassify(x = res) }) -assessment = twdtwAssess(twdtw_res) -head(assessment, 5) +cross_validation = twdtwCrossValidation(twdtw_res) } } \author{ diff --git a/man/twdtwRaster-class.Rd b/man/twdtwRaster-class.Rd index fc7249a..a9ea91f 100644 --- a/man/twdtwRaster-class.Rd +++ b/man/twdtwRaster-class.Rd @@ -29,6 +29,7 @@ \alias{twdtwRaster} \alias{twdtwRaster,ANY-method} \alias{twdtwRaster-class} +\alias{twdtwRaster-create} \title{class "twdtwRaster"} \usage{ \S4method{twdtwRaster}{ANY}(..., timeline, doy = NULL, layers = NULL, diff --git a/man/twdtwTimeSeries-class.Rd b/man/twdtwTimeSeries-class.Rd index ec08d2b..f881985 100644 --- a/man/twdtwTimeSeries-class.Rd +++ b/man/twdtwTimeSeries-class.Rd @@ -18,6 +18,7 @@ \alias{twdtwTimeSeries} \alias{twdtwTimeSeries,ANY-method} \alias{twdtwTimeSeries-class} +\alias{twdtwTimeSeries-create} \title{class "twdtwTimeSeries"} \usage{ \S4method{twdtwTimeSeries}{ANY}(..., labels = NULL) diff --git a/vignettes/applying_twdtw.Rmd b/vignettes/applying_twdtw.Rmd index 82d204c..c3d2729 100644 --- a/vignettes/applying_twdtw.Rmd +++ b/vignettes/applying_twdtw.Rmd @@ -451,14 +451,14 @@ partitions = splitDataset(field_samples_ts, p=0.1, times=100, freq = 8, formula = y ~ s(x, bs="cc")) ``` -For each data partition we run the TWDTW analysis to classify the set of validation time series using the trained temporal patterns. The result is a list of \code{twdtwMatches} objects with the classified set of time series for each data partition. To compute the *User's Accuracy* (UA) and *Producer's Accuracy* (PA) of the classified time series we use the function \code{dtwSat::twdtwAssess} that retrieves a \code{data.frame} with the accuracy assessment for all data partitions. +For each data partition we run the TWDTW analysis to classify the set of validation time series using the trained temporal patterns. The result is a list of \code{twdtwMatches} objects with the classified set of time series for each data partition. To compute the *User's Accuracy* (UA) and *Producer's Accuracy* (PA) of the classified time series we use the function \code{dtwSat::twdtwCrossValidation} that retrieves a \code{data.frame} with the accuracy assessment for all data partitions. ```{r, echo = TRUE, eval = FALSE, results = 'markup'} log_fun = logisticWeight(alpha=-0.1, beta=50) twdtw_res = lapply(partitions, function(x){ res = twdtwApply(x = x$ts, y = x$patterns, weight.fun = log_fun, n=1) twdtwClassify(x = res) }) -assessment = twdtwAssess(twdtw_res) +assessment = twdtwCrossValidation(twdtw_res) head(assessment, 5) ``` ```{r, echo = FALSE, eval = TRUE} @@ -477,7 +477,7 @@ t1/60 # 51.86498333 0.01046667 51.85880000 t2 = system.time( - assessment <- twdtwAssess(twdtw_res) + assessment <- twdtwCrossValidation(twdtw_res) ) t2/60 # user system elapsed