--- title: "Time series data" output: pdf_document: toc: false bibliography: ptLasso.bib vignette: > %\VignetteIndexEntry{Time series data} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ```{r, echo=TRUE} require(ptLasso) ``` We may have repeated measurements of $X$ and $y$ across time; for example, we may observe patients at two different points in time. We expect that the relationship between $X$ and $y$ will be different at time 1 and time 2, but not completely unrelated. Therefore, pretraining can be useful: we can use the model fitted at time 1 to inform the model for time 2. `ptLasso` supports this setting, and below is an example. We first assume that $X$ is constant across time, and $y$ changes. Later, we will show an example where $X$ changes across time. To do pretraining with time series data, we: 1. fit a model for time 1 and extract its offset and support, 2. use the offset and support (the usual pretraining) to train a model for time 2. We could continue this for $k$ time points: after fitting a model for time 2, we would extract the offset and support. Now, the offset will include the offset from time 1 and the prediction from time 2; the support will be the _union_ of supports from the first two models. ## Example 1: covariates are constant over time We'll start by simulating data -- more details in the comments. ```{r} set.seed(1234) # Define constants n = 600 # Total number of samples ntrain = 300 # Number of training samples p = 100 # Number of features sigma = 3 # Standard deviation of noise # Generate covariate matrix x = matrix(rnorm(n * p), n, p) # Define coefficients for time points 1 and 2 beta1 = c(rep(2, 10), rep(0, p - 10)) # Coefs at time 1 beta2 = runif(p, 0.5, 2) * beta1 # Coefs at time 2, shared support with time 1 # Generate response variables for times 1 and 2 y = cbind( x %*% beta1 + sigma * rnorm(n), x %*% beta2 + sigma * rnorm(n) ) # Split data into training and testing sets xtest = x[-(1:ntrain), ] # Test covariates ytest = y[-(1:ntrain), ] # Test response x = x[1:ntrain, ] # Train covariates y = y[1:ntrain, ] # Train response ``` Having simulated data, we are ready to call `ptLasso`; the call to `ptLasso` looks much the same as in all our other examples, only now (1) $y$ is a matrix with one column for each time point and (2) we specify `use.case = "timeSeries"`. After fitting, a call to `plot` shows the models fitted for both of the time points with and without using pretraining. ```{r} fit = ptLasso(x, y, use.case = "timeSeries", alpha = 0) plot(fit) ``` And as before, we can `predict` with `xtest`. In this example, pretraining helps performance: the two time points share the same support, and pretraining discovers and leverages this. ```{r} preds = predict(fit, xtest, ytest = ytest) preds ``` We specified `alpha = 0` in this example, but cross validation would advise us to choose $\alpha = 0.2$. Plotting shows us the average performance across the two time points. Importantly, at time 1, the individual model and the pretrained model are the same; we do not see the advantage of pretraining until time 2 (when we use information from time 1). ```{r} cvfit = cv.ptLasso(x, y, use.case = "timeSeries") plot(cvfit) predict(cvfit, xtest, ytest = ytest) ``` Note that we could also have treated this as a _multireponse_ problem, and ignored the time-ordering of the responses. See more in the section called "Multi-response data with Gaussian responses". (However, time ordering can be informative, and the multi-response approach does not make use of this.) ```{r} fit = ptLasso(x, y, use.case = "multiresponse") ``` ## Example 2: covariates change over time Now, we'll repeat what we did above, but we'll simulate data where $x$ changes with time. In this setting, `ptLasso` expects $x$ to be a list with one covariate matrix for each time. ```{r} set.seed(1234) # Set seed for reproducibility # Define constants n = 600 # Total number of samples ntrain = 300 # Number of training samples p = 100 # Number of features sigma = 3 # Standard deviation of noise # Covariates for times 1 and 2 x1 = matrix(rnorm(n * p), n, p) x2 = x1 + matrix(0.2 * rnorm(n * p), n, p) # Perturbed covariates for time 2 x = list(x1, x2) # Define coefficients for time points 1 and 2 beta1 = c(rep(2, 10), rep(0, p - 10)) # Coefs at time 1 beta2 = runif(p, 0.5, 2) * beta1 # Coefs at time 2, shared support with time 1 # Response variables for times 1 and 2: y = cbind( x[[1]] %*% beta1 + sigma * rnorm(n), x[[2]] %*% beta2 + sigma * rnorm(n) ) # Split data into training and testing sets xtest = lapply(x, function(xx) xx[-(1:ntrain), ]) # Test covariates ytest = y[-(1:ntrain), ] # Test response x = lapply(x, function(xx) xx[1:ntrain, ]) # Train covariates y = y[1:ntrain, ] # Train response ``` Now, $x$ is a list of length two: ```{r} str(x) ``` We can call `ptLasso`, `cv.ptLasso`, `plot` and `predict` just as before: ```{r} fit = ptLasso(x, y, use.case = "timeSeries", alpha = 0) plot(fit) # Plot the fitted model predict(fit, xtest, ytest = ytest) # Predict using the fitted model # With cross validation: cvfit = cv.ptLasso(x, y, use.case = "timeSeries") plot(cvfit, plot.alphahat = TRUE) # Plot cross-validated model predict(cvfit, xtest, ytest = ytest) # Predict using cross-validated model ```