Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

We will use the cvxpy library for computing estimates in this lecture. cvxpy allows the use of many solvers. We shall use here the solver coming from the library ‘mosek’. Mosek is a commercial solver for convex optimization. I will use “solver = MOSEK” in the convex optimization schemes below for computing estimators. Mosek is more reliable than the other solvers that cvxpy uses. To use MOSEK, you first have to install it in your python environment (e.g., using “pip install mosek” or “conda install -c conda-forge mosek”), then you need to request a personal mosek academic license (at this address: https://www.mosek.com/products/academic-licenses/ by using your email address). The license will be emailed to you. You need to download the license file and place it in the correct directory (this information is given in the license email). After this, the mosek solver should work in cvxpy.

We shall discuss three simple high-dimensional models for time series. The first model coincides with the high-dimensional linear regression model from the previous few lectures. The second model is a variance model that was briefly introduced near the end of the last lecture. The third model is a variance model in terms of the DFT (it will be referred to as the spectrum model).

Model ONE

This is the model

yt∼indN(μt,σ2)y_t \overset{\text{ind}}{\sim} N(\mu_t, \sigma^2)

where μt\mu_t (which can be interpreted as the trend function) is smooth in tt. μt\mu_t can be estimated from the data using one of the following two regularized estimators obtained by minimizing

∑t=1n(yt−μt)2+λ∑t=2n−1((μt−μt−1)−(μt−1−μt))2\sum_{t=1}^n (y_t - \mu_t)^2 + \lambda \sum_{t=2}^{n-1} \left((\mu_t - \mu_{t-1}) - (\mu_{t-1} - \mu_t) \right)^2

or

∑t=1n(yt−μt)2+λ∑t=2n−1∣(μt−μt−1)−(μt−1−μt)∣\sum_{t=1}^n (y_t - \mu_t)^2 + \lambda \sum_{t=2}^{n-1} \left|(\mu_t - \mu_{t-1}) - (\mu_{t-1} - \mu_t) \right|

As we saw previously, these are the same as the estimators obtained by employing the ridge and LASSO penalties to the high-dimensional linear regression model:

μt=β0+β1(t−1)+β2(t−2)++⋯+βn−1(t−(n−1))+\mu_t = \beta_0 + \beta_1 (t-1) + \beta_2 (t-2)_+ + \dots + \beta_{n-1} (t - (n-1))_+

Below is an application of this model to smooth trend estimation. We simulate data by adding noise to a smooth function, and then estimate it using one of the two estimators above.

<Figure size 1200x600 with 1 Axes>

Below we compute the estimator μ^t\hat{\mu}_t directly without going to the regression representation (with the XX matrix that we previously used). We use the optimization functions from cvxpy directly on the optimization in terms of μt\mu_t.

<Figure size 1200x600 with 1 Axes>

Model TWO

This is the model

yt∼independentN(0,τt2)y_t \overset{\text{independent}}{\sim} N(0, \tau_t^2)

Negative log-likelihood parametrized by αt=log⁡τt\alpha_t = \log \tau_t is given by

∑t=1n(αt+yt22e−2αt)\sum_{t=1}^n \left(\alpha_t + \frac{y_t^2}{2} e^{-2 \alpha_t} \right)

We add regularization and minimize:

∑t=1n(αt+yt22e−2αt)+λ∑t=2n−1((αt+1−αt)−(αt−αt−1))2\sum_{t=1}^n \left(\alpha_t + \frac{y_t^2}{2} e^{-2 \alpha_t} \right) + \lambda \sum_{t=2}^{n-1} \left((\alpha_{t+1} - \alpha_{t})- (\alpha_{t} - \alpha_{t-1})\right)^2

or

∑t=1n(αt+yt22e−2αt)+λ∑t=2n−1∣(αt+1−αt)−(αt−αt−1)∣\sum_{t=1}^n \left(\alpha_t + \frac{y_t^2}{2} e^{-2 \alpha_t} \right) + \lambda \sum_{t=2}^{n-1} \left|(\alpha_{t+1} - \alpha_{t})- (\alpha_{t} - \alpha_{t-1})\right|

Below we describe two simulation settings for this model.

Simulation 1 for Model 2

<Figure size 1200x600 with 1 Axes>
<Figure size 1200x600 with 1 Axes>

The sufficient statistic in this model is y12,…,yn2y_1^2, \dots, y_n^2. Because yt2∼τt2χ12y_t^2 \sim \tau_t^2 \chi^2_1, the mean of yt2y_t^2 equals τt2\tau_t^2 and its variance is 2τ42 \tau^4. Below we plot yt2y_t^2 as well as τt2\tau_t^2.

<Figure size 1200x600 with 1 Axes>

Observe from the above plot that both the level (mean) of yt2y_t^2 as well as its variance changes with τt2\tau_t^2. This is because the mean of yt2y_t^2 equals τt2\tau_t^2, and its variance equals 2τt42 \tau_t^4.

Because yt2∼τt2χ12y_t^2 \sim \tau_t^2 \chi^2_1, we can write

log⁡(yt2)=log⁡(τt2)+log⁡(χ12)\log(y_t^2) = \log(\tau_t^2) + \log (\chi^2_1)

The mean of log⁡χ12\log \chi^2_1 is negative (internet says it is about -1.27). This means that if we plot log⁡yt2\log y_t^2 and log⁡τt2\log \tau_t^2 in one figure, most of the values for log⁡yt2\log y_t^2 will appear to be below log⁡τt2\log \tau_t^2.

<Figure size 1200x600 with 1 Axes>

Simulation 2 for Model 2

Here is the second simulation setting for this model.

<Figure size 1200x600 with 1 Axes>
<Figure size 1200x600 with 1 Axes>
<Figure size 1200x600 with 1 Axes>
<Figure size 1200x600 with 1 Axes>
<Figure size 1200x600 with 1 Axes>

A real dataset from finance for which Model 2 is applicable

Next, we examine a real dataset where this variance model (Model 2) may be applicable. The dataset consists of stock price data for the S&P 500 mutual fund, downloaded from Yahoo Finance using the yfinance library.

[*********************100%***********************]  1 of 1 completed
<Figure size 1200x600 with 1 Axes>

Instead of working with the prices directly, we work with percentage daily returns.

<Figure size 1200x600 with 1 Axes>

The plot above suggests that Model 2 might be useful for this dataset.

/Users/aditya/mambaforge/envs/stat153fall2026/lib/python3.14/site-packages/numpy/_core/fromnumeric.py:83: RuntimeWarning: overflow encountered in reduce
  return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
/Users/aditya/mambaforge/envs/stat153fall2026/lib/python3.14/site-packages/numpy/_core/fromnumeric.py:83: RuntimeWarning: invalid value encountered in reduce
  return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
<Figure size 1200x600 with 1 Axes>
<Figure size 1200x600 with 1 Axes>
<Figure size 1200x600 with 1 Axes>

Another way of checking how good this fit is by dividing the data using the estimated standard deviations, and then plotting the standardized data.

<Figure size 1200x600 with 3 Axes>

Model THREE

We shall discuss a third model which is related to the previous two but is much more popular in many sciences and engineering. We shall refer to as the spectrum model. It is simply the variance model applied to the Discrete Fourier Transform (DFT) of the data. Before writing down the model, here is a motivating example.

EEG Motor Movement Dataset

The following dataset was downloaded from https://physionet.org/content/eegmmidb/1.0.0/. The specific dataset details are here: https://physionet.org/content/eegmmidb/1.0.0/. The dataset consists of over 1500 one and two minute (64 channel) EEG recordings, obtained from 109 volunteers. We will pick data for just one subject (volunteer) and one of the EEG channels, and compare the data for eyes open vs eyes closed. A basic finding of cognitive neuroscience is that the power of occipital alpha-band (~10 Hz) brain waves is increased when peoples’ eyes are closed, rather than open (see, for example, the paper titled “Occipital alpha-band brain waves when the eyes are closed are shaped by ongoing visual processes” by Hohaia et al 2022).

The mne python library is necessary for loading the data file.

For each individual subject (here we are using the data for the first subject), there are 64 time series datasets for “open-eyes” and again 64 time series datasets for “closed-eyes”. These 64 datasets correspond to the 64 channels which are different electrodes recording brain activity. We pick one of the channels, and compare the “open-eyes” and “closed-eyes” data.

Extracting EDF parameters from S001R01.edf...
Setting channel info structure...
Creating raw.info structure...
Reading 0 ... 9759  =      0.000 ...    60.994 secs...
<Info | 8 non-empty values
 bads: []
 ch_names: Fc5., Fc3., Fc1., Fcz., Fc2., Fc4., Fc6., C5.., C3.., C1.., ...
 chs: 64 EEG
 custom_ref_applied: False
 highpass: 0.0 Hz
 lowpass: 80.0 Hz
 meas_date: 2009-08-12 16:15:00 UTC
 nchan: 64
 projs: []
 sfreq: 160.0 Hz
 subject_info: <subject_info | his_id: X, sex: 0, last_name: X>
>
<Figure size 640x480 with 1 Axes>
Extracting EDF parameters from S001R02.edf...
Setting channel info structure...
Creating raw.info structure...
Reading 0 ... 9759  =      0.000 ...    60.994 secs...
<Info | 8 non-empty values
 bads: []
 ch_names: Fc5., Fc3., Fc1., Fcz., Fc2., Fc4., Fc6., C5.., C3.., C1.., ...
 chs: 64 EEG
 custom_ref_applied: False
 highpass: 0.0 Hz
 lowpass: 80.0 Hz
 meas_date: 2009-08-12 16:15:00 UTC
 nchan: 64
 projs: []
 sfreq: 160.0 Hz
 subject_info: <subject_info | his_id: X, sex: 0, last_name: X>
>
<Figure size 640x480 with 1 Axes>

There is a sampling rate associated with these datasets. This is the number of times per second that the data is obtained.

Sampling rate: 160.0 Hz
Sampling rate: 160.0 Hz

The length of these time series is 9760 (see below). This corresponds to 160 observations per second, for a total of 61 seconds.

[0.000000e+00 6.250000e-03 1.250000e-02 ... 6.098125e+01 6.098750e+01
 6.099375e+01]
[0.000000e+00 6.250000e-03 1.250000e-02 ... 6.098125e+01 6.098750e+01
 6.099375e+01]
9760 61.0

Our two datasets are:

Our main goal is to compare these two datasets and to highlight the main ways in which they are different.

<Figure size 640x480 with 2 Axes>
<Figure size 640x480 with 1 Axes>

It is obviously very hard to articulate the differences between the two time series just by looking at their plots. For such datasets, the basic tool is the Periodogram. Recall that the periodogram is given by:

I(j/n):=∣bj∣2n\begin{align*} I(j/n) := \frac{|b_j|^2}{n} \end{align*}

where bjb_j is given by the Discrete Fourier Transform. We plot the periodogram when j/nj/n lies between 0 and 1/21/2.

<Figure size 640x480 with 2 Axes>

The differences are more apparent from the periodograms. To see them better, we plot the periodograms on the log-scale.

<Figure size 1200x500 with 2 Axes>

Below we plot the log-periodograms in the same plot.

<Figure size 640x480 with 1 Axes>

To visualize the differences better, we need to smooth the log-periodogram somehow. This is where our model 3 is helpful.

Model 3 (Spectrum Model)

Model 3 is

Re(bj),Im(bj)∼i.i.dN(0,γj2)\text{Re}(b_j), \text{Im}(b_j) \overset{\text{i.i.d}}{\sim} N(0, \gamma_j^2)

for j=1,…,mj = 1, \dots, m where bjb_j is the jthj^{th} DFT coefficient of the observed data y1,…,yny_1, \dots, y_n.

Likelihood in terms of the periodogram is:

∏j=1mnγj2exp⁡(−nI(j/n)2γj2)\prod_{j=1}^m \frac{n}{\gamma_j^2} \exp \left(-\frac{n I(j/n)}{2 \gamma_j^2} \right)

Negative log-likelihood is

∑j=1m(nI(j/n)2γj2+2log⁡γj)\sum_{j=1}^m \left(\frac{n I(j/n)}{2 \gamma_j^2} + 2 \log \gamma_j \right)

Letting αj=log⁡γj\alpha_j = \log \gamma_j, we can rewrite the above as

∑j=1m(nI(j/n)2e−2αj+2αj)\sum_{j=1}^m \left( \frac{nI(j/n)}{2} e^{-2 \alpha_j} + 2 \alpha_j \right)

Minimizing this without any regularization on {αj}\{\alpha_j\} leads to

αj=log⁡nI(j/n)2   and   γj2=e2αj=nI(j/n)2\alpha_j = \log \sqrt{\frac{nI(j/n)}{2}} ~~ \text{ and } ~~ \gamma_j^2 = e^{2\alpha_j} = \frac{nI(j/n)}{2}

We will use regularization and estimate αj\alpha_j (and γj\gamma_j) by minimizing:

∑j=1m(nI(j/n)2e−2αj+2αj)+λ∑j=2m−1((αj+1−αj)−(αj−αj−1))2\sum_{j=1}^m \left( \frac{nI(j/n)}{2} e^{-2 \alpha_j} + 2 \alpha_j \right) + \lambda \sum_{j=2}^{m-1} \left((\alpha_{j+1} - \alpha_j) - (\alpha_j - \alpha_{j-1}) \right)^2

or

∑j=1m(nI(j/n)2e−2αj+2αj)+λ∑j=2m−1∣(αj+1−αj)−(αj−αj−1)∣.\sum_{j=1}^m \left( \frac{nI(j/n)}{2} e^{-2 \alpha_j} + 2 \alpha_j \right) + \lambda \sum_{j=2}^{m-1} \left|(\alpha_{j+1} - \alpha_j) - (\alpha_j - \alpha_{j-1}) \right|.

Code for computing these estimators is given below. These functions (alpha_estimator_ridge and alpha_estimator_lasso) use yy and λ\lambda as input. In the first step, one computes the periodogram I(j/n)I(j/n) as the optimization is in terms of the periodogram. We apply these methods to the EEG dataset.

We will now apply these estimators to each of the two datasets (eyes open and eyes closed). We compute estimates of αj,j=1,…,m\alpha_j, j = 1, \dots, m and also compute the corresponding 2γj2/n2 \gamma_j^2/n (where γj=exp⁡(αj)\gamma_j = \exp(\alpha_j)). This quantity 2γj2/n2 \gamma_j^2/n equals the mean of I(j/n)I(j/n) in our model I(j/n)∼γj2nχ22I(j/n) \sim \frac{\gamma_j^2}{n} \chi^2_2.

Below we plot the periodogram and its mean 2γj2/n2 \gamma_j^2/n both on log-scale.

<Figure size 640x480 with 2 Axes>

Below we plot the estimated 2γj2/n2 \gamma_j^2/n (on the log-scale). These should be viewed as smoothed versions of the respective periodograms.

<Figure size 640x480 with 1 Axes>
<Figure size 640x480 with 1 Axes>

The peak in the ‘eyes closed’ curve above can be computed as follows.

[0.06270492 0.1079918  0.24518443]

The peak corresponds to the frequency 0.06270492. To convert the frequency to Hertz, we multiply it by the sampling rate.

np.float64(10.032786885245901)

So the differences between the two smoothed periodogram estimates is mainly at frequency 10.0328 Hz. This is very close to the 10Hz Alpha rhythm which apparently exists when eyes are closed as opposed to eyes being open (see, for example, the first sentence in this paper “Occipital alpha-band brain waves when the eyes are closed are shaped by ongoing visual processes” by Hohaia et al 2022). The wiki page on the alpha wave (see Alpha wave) says that alpha waves are neural oscillations in the frequency range 8-12 Hz. We can see from the plot above that at 8 - 12 Hz, the estimated spectrum for the closed eyes data is higher than the spectrm for open eyes data.