## `eigenkit.torch.estimators.timeseries`

## `eigenkit.torch.estimators.timeseries.QuantumTimeSeriesRegressor`

Bases: `BaseQuantumRegressor`

Supervised wrapper with a single output, for time-series regression.

It builds sliding windows over the rows of `X` (one row for each time step). Each window has shape `(in_size, n_features)`. Stacked along the batch axis, they form an array of shape `(n_windows, in_size, n_features)`, ready for sequence models such as `torch.nn.LSTM`. When `autoregressive=True`, an extra last channel holds the target value of each timestep, so each step has `n_features + 1` values. For a window that starts at row `i`, the regression target is `y[i + in_size - 1 + shift]`.

Parameters:

| Name             | Type   | Description                                                                                                                                                             | Default                                                               |
| ---------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| `estimator`      | `Any`  | The inner estimator. It must have fit(X, y) and predict(X).                                                                                                             | *required*                                                            |
| `in_size`        | \`int  | None\`                                                                                                                                                                  | The length of the window, in time steps. If None, it is treated as 1. |
| `shift`          | `int`  | How many steps after the last timestep of the window the target is. It must be zero or more. shift=0 predicts the target at the last timestep.                          | `1`                                                                   |
| `autoregressive` | `bool` | If True, a channel with y[i + k] for k = 0, ..., in_size - 1 is added to each window. With shift=0, this leaks the target into the inputs, and a UserWarning is raised. | `False`                                                               |

Attributes:

| Name            | Type | Description                                                                                                                                                       |
| --------------- | ---- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `train_losses_` |      | The training loss of each epoch, copied from the inner estimator if it has train_losses\_ (HQNR, RecurrentHQNR), and an empty list otherwise. It is set by fit(). |

Example

```python
import numpy as np
from eigenkit.torch.estimators import QuantumTimeSeriesRegressor, RecurrentHQNR

rng = np.random.default_rng(0)
X_train, X_test = rng.normal(size=(40, 3)), rng.normal(size=(15, 3))
y_train = np.sin(np.arange(40) / 4)

# The inner estimator should accept X of shape (batch, in_size, n_features).
inner = RecurrentHQNR(seq_feature_dim=3, rnn_hidden_dim=4, epochs=5)
model = QuantumTimeSeriesRegressor(estimator=inner, in_size=10, shift=1)
model.fit(X_train, y_train)
predictions = model.predict(X_test)
```

### `output`

The number of outputs, which is always `1`.

### `fit(X, y)`

Fit the inner estimator on the windows and their targets.

Parameters:

| Name | Type      | Description                                                     | Default    |
| ---- | --------- | --------------------------------------------------------------- | ---------- |
| `X`  | `ndarray` | The features in time order, of shape (n_timesteps, n_features). | *required* |
| `y`  | `ndarray` | The targets, of shape (n_timesteps,) or (n_timesteps, 1).       | *required* |

Returns:

| Type                           | Description                                   |
| ------------------------------ | --------------------------------------------- |
| `'QuantumTimeSeriesRegressor'` | This estimator, so that calls can be chained. |

### `load(path, *, provider=None, model=None)`

Load a fitted time-series wrapper from a `.eigenkit` bundle.

Parameters:

| Name       | Type           | Description                                                                                                                                | Default                                                                                |
| ---------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------- |
| `path`     | \`str          | Path\`                                                                                                                                     | The path of the .eigenkit bundle.                                                      |
| `provider` | \`ProviderSpec | None\`                                                                                                                                     | An optional provider that replaces the saved one. It is passed to the inner estimator. |
| `model`    | `Any`          | The nn.Module architecture, required when the inner estimator is GenericRegressor. Pass the same architecture as the one used in training. | `None`                                                                                 |

Returns:

| Type                           | Description         |
| ------------------------------ | ------------------- |
| `'QuantumTimeSeriesRegressor'` | The loaded wrapper. |

Raises:

| Type                 | Description                                             |
| -------------------- | ------------------------------------------------------- |
| `TypeError`          | If the bundle holds a different class.                  |
| `SerializationError` | If the inner estimator needs model and it is not given. |

### `predict(X, y_history=None)`

Predict the regression targets of the windows of `X`.

Parameters:

| Name        | Type      | Description                                                     | Default                                                                                                                                     |
| ----------- | --------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `X`         | `ndarray` | The features in time order, of shape (n_timesteps, n_features). | *required*                                                                                                                                  |
| `y_history` | \`ndarray | None\`                                                          | The past targets, aligned with the rows of X. They fill the autoregressive channel of each window. It is required when autoregressive=True. |

Returns:

| Type      | Description                                                     |
| --------- | --------------------------------------------------------------- |
| `ndarray` | The predictions, of shape (n_timesteps - in_size - shift + 1,). |

### `score(X, y, *, return_dict=False)`

```python
score(
    X: np.ndarray,
    y: np.ndarray,
    *,
    return_dict: Literal[False] = False,
) -> float
```

```python
score(
    X: np.ndarray,
    y: np.ndarray,
    *,
    return_dict: Literal[True],
) -> dict[str, float]
```

Score the estimator on the window targets, aligned as in `predict`.

By default, it returns `R²`, for compatibility with scikit-learn (`cross_val_score`, `GridSearchCV`). Pass `return_dict=True` to get a dict with `r2`, `mse`, `mae`, `rmse` and `mape`.

Parameters:

| Name          | Type      | Description                                                                                    | Default    |
| ------------- | --------- | ---------------------------------------------------------------------------------------------- | ---------- |
| `X`           | `ndarray` | The samples, of shape (n_samples, n_features). The windows are built inside.                   | *required* |
| `y`           | `ndarray` | One target for each sample, of shape (n_samples,).                                             | *required* |
| `return_dict` | `bool`    | If True, every metric is returned in a dict, instead of the single main score. Default: False. | `False`    |

Returns:

| Type    | Description        |
| ------- | ------------------ |
| \`float | dict[str, float]\` |

### `save(path)`

Save a fitted model to a `.eigenkit` bundle.

The bundles of models that hold scikit-learn objects (`QSVC`, `QSVR`, the reservoir estimators and the time-series estimators) contain joblib pickles, so loading one can run code. Share them only with people who trust you.

Parameters:

| Name   | Type  | Description | Default                                                                   |
| ------ | ----- | ----------- | ------------------------------------------------------------------------- |
| `path` | \`str | Path\`      | The path of the bundle. The suffix .eigenkit is added when it is missing. |

## `eigenkit.torch.estimators.timeseries.QuantumTimeSeriesClassifier`

Bases: `BaseQuantumClassifier`

Supervised wrapper for time-series classification.

It builds sliding windows over the rows of `X` (one row for each time step). Each window has shape `(in_size, n_features)`. Stacked along the batch axis, they form an array of shape `(n_windows, in_size, n_features)`, ready for sequence models such as `RecurrentHQNC`. When `autoregressive=True`, an extra last channel holds the target value of each timestep, so each step has `n_features + 1` values. For a window that starts at row `i`, the classification target is `y[i + in_size - 1 + shift]`.

Parameters:

| Name             | Type   | Description                                                                                                                                                                                                                                                   | Default                                                               |
| ---------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| `estimator`      | `Any`  | The inner estimator. It must have fit(X, y) and predict(X).                                                                                                                                                                                                   | *required*                                                            |
| `in_size`        | \`int  | None\`                                                                                                                                                                                                                                                        | The length of the window, in time steps. If None, it is treated as 1. |
| `shift`          | `int`  | How many steps after the last timestep of the window the target is. It must be zero or more. shift=0 predicts the target at the last timestep.                                                                                                                | `1`                                                                   |
| `autoregressive` | `bool` | If True, a channel with y[i + k] for k = 0, ..., in_size - 1 is added to each window. With shift=0, this leaks the target into the inputs, and a UserWarning is raised. When autoregressive=True, predict() and predict_proba() require a y_history argument. | `False`                                                               |

Attributes:

| Name            | Type | Description                                                                                                                                                       |
| --------------- | ---- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `classes_`      |      | The distinct class labels seen by fit().                                                                                                                          |
| `train_losses_` |      | The training loss of each epoch, copied from the inner estimator if it has train_losses\_ (HQNC, RecurrentHQNC), and an empty list otherwise. It is set by fit(). |

Example

```python
import numpy as np
from eigenkit.torch.estimators import (
    QuantumTimeSeriesClassifier, RecurrentHQNC,
)

rng = np.random.default_rng(0)
X_train, X_test = rng.normal(size=(40, 4)), rng.normal(size=(15, 4))
y_train = np.arange(40) % 2

inner = RecurrentHQNC(seq_feature_dim=4, rnn_hidden_dim=4, depth=2)
model = QuantumTimeSeriesClassifier(estimator=inner, in_size=10, shift=1)
model.fit(X_train, y_train)
predictions = model.predict(X_test)
```

### `output`

The number of classes.

After `fit()`, it is the number of classes seen. Before, it is the `n_classes` of the inner estimator, or None if it has none.

### `fit(X, y)`

Fit the inner classifier on the windows and their labels.

Parameters:

| Name | Type      | Description                                                     | Default    |
| ---- | --------- | --------------------------------------------------------------- | ---------- |
| `X`  | `ndarray` | The features in time order, of shape (n_timesteps, n_features). | *required* |
| `y`  | `ndarray` | The class labels, of shape (n_timesteps,) or (n_timesteps, 1).  | *required* |

Returns:

| Type                            | Description                                   |
| ------------------------------- | --------------------------------------------- |
| `'QuantumTimeSeriesClassifier'` | This estimator, so that calls can be chained. |

### `load(path, *, provider=None, model=None)`

Load a fitted time-series classifier wrapper from a `.eigenkit` bundle.

Parameters:

| Name       | Type           | Description                                                                                                                                 | Default                                                                                |
| ---------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| `path`     | \`str          | Path\`                                                                                                                                      | The path of the .eigenkit bundle.                                                      |
| `provider` | \`ProviderSpec | None\`                                                                                                                                      | An optional provider that replaces the saved one. It is passed to the inner estimator. |
| `model`    | `Any`          | The nn.Module architecture, required when the inner estimator is GenericClassifier. Pass the same architecture as the one used in training. | `None`                                                                                 |

Returns:

| Type                            | Description         |
| ------------------------------- | ------------------- |
| `'QuantumTimeSeriesClassifier'` | The loaded wrapper. |

Raises:

| Type                 | Description                                             |
| -------------------- | ------------------------------------------------------- |
| `TypeError`          | If the bundle holds a different class.                  |
| `SerializationError` | If the inner estimator needs model and it is not given. |

### `predict(X, y_history=None)`

Predict the class labels of the windows of `X`.

Parameters:

| Name        | Type      | Description                                                     | Default                                                                                                                                                                                                                                                             |
| ----------- | --------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `X`         | `ndarray` | The features in time order, of shape (n_timesteps, n_features). | *required*                                                                                                                                                                                                                                                          |
| `y_history` | \`ndarray | None\`                                                          | The past class labels, aligned with the rows of X. They fill the autoregressive channel of each window. It is required when autoregressive=True, and it must have at least n_timesteps - shift elements (that is, n_timesteps - in_size - shift + 1 + in_size - 1). |

Returns:

| Type      | Description                                                          |
| --------- | -------------------------------------------------------------------- |
| `ndarray` | The predicted labels, of shape (n_timesteps - in_size - shift + 1,). |

### `predict_proba(X, y_history=None)`

Return the estimated class probabilities of the windows of `X`.

Parameters:

| Name        | Type      | Description                                                     | Default                                                                        |
| ----------- | --------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| `X`         | `ndarray` | The features in time order, of shape (n_timesteps, n_features). | *required*                                                                     |
| `y_history` | \`ndarray | None\`                                                          | The past class labels. It is required when autoregressive=True. See predict(). |

Returns:

| Type      | Description                                      |
| --------- | ------------------------------------------------ |
| `ndarray` | A float32 array of shape (n_windows, n_classes). |

Raises:

| Type                  | Description                                  |
| --------------------- | -------------------------------------------- |
| `NotImplementedError` | If the inner estimator has no predict_proba. |

### `score(X, y, *, return_dict=False)`

```python
score(
    X: np.ndarray,
    y: np.ndarray,
    *,
    return_dict: Literal[False] = False,
) -> float
```

```python
score(
    X: np.ndarray,
    y: np.ndarray,
    *,
    return_dict: Literal[True],
) -> dict[str, float]
```

Score the estimator on the window targets, aligned as in `predict`.

By default, it returns the accuracy, for compatibility with scikit-learn (`cross_val_score`, `GridSearchCV`). Pass `return_dict=True` to get a dict with `accuracy`, `f1` (weighted), `precision` (weighted) and `recall` (weighted).

Note

When `autoregressive=True`, the true labels `y` are used as the autoregressive history channel (teacher forcing). This is the correct behaviour for held-out evaluation, but it means that `score` cannot be called without the true labels of all the timesteps in `X`.

Parameters:

| Name          | Type      | Description                                                                                    | Default    |
| ------------- | --------- | ---------------------------------------------------------------------------------------------- | ---------- |
| `X`           | `ndarray` | The samples, of shape (n_samples, n_features). The windows are built inside.                   | *required* |
| `y`           | `ndarray` | One target for each sample, of shape (n_samples,).                                             | *required* |
| `return_dict` | `bool`    | If True, every metric is returned in a dict, instead of the single main score. Default: False. | `False`    |

Returns:

| Type    | Description        |
| ------- | ------------------ |
| \`float | dict[str, float]\` |

### `save(path)`

Save a fitted model to a `.eigenkit` bundle.

The bundles of models that hold scikit-learn objects (`QSVC`, `QSVR`, the reservoir estimators and the time-series estimators) contain joblib pickles, so loading one can run code. Share them only with people who trust you.

Parameters:

| Name   | Type  | Description | Default                                                                   |
| ------ | ----- | ----------- | ------------------------------------------------------------------------- |
| `path` | \`str | Path\`      | The path of the bundle. The suffix .eigenkit is added when it is missing. |
