cutcutcodec.core.signal.predict.LinearPredictor
- class cutcutcodec.core.signal.predict.LinearPredictor(*args, n_alpha: Integral | None = None, **kwargs)[source]
Prediction by linear combination of observations.
The prediction of the next observation is defined as follow:
\[\hat{o}_{n+1} = \sum_{k=1}^{n_\alpha} \alpha_k o_{n+1-k}\]Notation:
\[\begin{split}\begin{align} \begin{pmatrix} \hat{o}_n \\ \vdots \\ \hat{o}_{n-h} \end{pmatrix} &= \begin{pmatrix} o_{n-1} & \ldots & o_{n-1-n_\alpha} \\ \vdots & \ddots & \vdots \\ o_{n-1-h} & \ldots & o_{n-1-h-n_\alpha} \\ \end{pmatrix} \begin{pmatrix} \alpha_1 \\ \vdots \\ \alpha_{n_\alpha} \end{pmatrix} \\ \Leftrightarrow \boldsymbol{\hat{o}} &= \boldsymbol{X} \boldsymbol{\alpha} \end{align}\end{split}\]The \(\alpha_k\) scalars are founded to minimise the mse:
\[\begin{split}\begin{align} &\boldsymbol{\alpha} = \underset{\boldsymbol{\alpha}}{\operatorname{argmin}}\left( \left\| \begin{pmatrix} \hat{o}_n \\ \vdots \\ \hat{o}_{n-h} \end{pmatrix} - \begin{pmatrix} o_n \\ \vdots \\ o_{n-h} \end{pmatrix} \right\|^2 \right) \\ \Leftrightarrow &\boldsymbol{\alpha} = \underset{\boldsymbol{\alpha}}{\operatorname{argmin}}\left( \left\| \boldsymbol{\hat{o}} - \boldsymbol{o} \right\|^2 \right) \\ \Leftrightarrow &\boldsymbol{\alpha} = \underset{\boldsymbol{\alpha}}{\operatorname{argmin}}\left( \left( \boldsymbol{X} \boldsymbol{\alpha} - \boldsymbol{o} \right)^\intercal \left( \boldsymbol{X} \boldsymbol{\alpha} - \boldsymbol{o} \right) \right) \\ \Leftrightarrow &\frac{ \partial \left( \left( \boldsymbol{X} \boldsymbol{\alpha} - \boldsymbol{o} \right)^\intercal \left( \boldsymbol{X} \boldsymbol{\alpha} - \boldsymbol{o} \right) \right) }{\partial \boldsymbol{\alpha}} = \boldsymbol{0} \\ \Leftrightarrow &\boldsymbol{\alpha} = \left( \boldsymbol{X}^\intercal \boldsymbol{X} \right)^{-1} \boldsymbol{X}^\intercal \boldsymbol{o} \\ \end{align}\end{split}\]Examples
>>> from cutcutcodec.core.signal.predict import LinearPredictor >>> # simple case >>> predictor = LinearPredictor(memory=4) >>> predictor.update([4.0, 3.0, 2.0, 1.0]) # arithmetic sequence (more recent first) >>> round(predictor.predict_next(), 6) 5.0 >>> # complicated case >>> predictor = LinearPredictor(memory=6) >>> predictor.update([4.0, 2.0, 3.0, 1.0, 2.0, 0.0]) # less trivial sequence >>> [round(p, 6) for p in predictor.predict(4)] [6.0, 4.0, 5.0, 3.0] >>>
Initialise the predictor.
Parameters