# Spectrally constrained LVMs
![GitHub license](https://img.shields.io/github/license/RyanBalshaw/spectrally-constrained-LVMs)
![GitHub last commit](https://img.shields.io/github/last-commit/RyanBalshaw/spectrally-constrained-LVMs)
![PyPI](https://img.shields.io/pypi/v/spectrally-constrained-lvms)
![PyPI - Wheel](https://img.shields.io/pypi/wheel/spectrally-constrained-lvms?color=blueviolet)
![Read the Docs](https://img.shields.io/readthedocs/spectrally-constrained-lvms?color=informational)
![GitHub issues](https://img.shields.io/github/issues/RyanBalshaw/spectrally-constrained-LVMs?color=critical)
*Current version:* 0.1.3
Spectrally-constrained-LVMs is a Python-based package which facilitates the estimation of the linear latent variable model (LVM) parameters with a unique spectral constraint in single-channel time-series applications.
## Purpose
LVMs are a statistical methodology which tries to capture the underlying structure in some observed data. This package caters to single channel time-series applications and provides a methodology to estimate the LVM parameters. The model parameters are encouraged to be diverse via a spectral constraint which enforces non-duplication of the spectral information captured by the latent sources.
The purpose of this package is to provide a complete methodology that caters to a variety of LVM objective functions.
# Documentation
Please visit [the docs](http://spectrally-constrained-lvms.readthedocs.io/) for all supporting documentation for this package.
# Installation
The package is designed to be used through the Python API, and can be installed using [pip](https://pypi.org/project/pip/):
```console
$ pip install spectrally-constrained-LVMs
```
# Requirements
This package used Python ≥ 3.10 or later to run. For other python dependencies, please check the `pyproject.toml`
[file](https://github.com/RyanBalshaw/spectrally-constrained-LVMs/blob/main/pyproject.toml) included in this repository. The dependencies of this package are as follows:
| Package | Version |
|:----------------------------------------------:|:----------:|
| [Python](https://www.python.org/) | ≥ 3.10 |
| [Numpy](https://numpy.org/) | ≥ 1.23.1 |
| [Matplotlib](https://matplotlib.org/) | ≥ 3.5.2 |
| [SciPy](https://scipy.org/) | ≥ 1.8.1 |
| [scikit-learn](https://scikit-learn.org/) | ≥ 1.1.2 |
| [tqdm](https://github.com/tqdm/tqdm) | ≥ 4.64.1 |
| [SymPy](https://www.sympy.org/en/index.html) | ≥ 1.1.1 |
# API usage
## Model parameter estimation
A generic example is shown below:
```python
import spectrally_constrained_LVMs as scLVMs
# Load in some data
signal_data = ... # Load a single channel time-series signal
Fs = ... # Sampling frequency of the data
# Hankelise the data
X = scLVMs.hankel_matrix(signal_data,
Lw = 512,
Lsft = 1)
# Define a cost function for latent sources with maximum variance
cost_inst = scLVMs.VarianceCost()
# Define a model instance
model_inst = scLVMs.LinearModel(n_sources=10,
cost_instance=cost_inst,
whiten=False,
alpha_reg=1.0)
# Estimate the model parameters
model_inst.fit(X, Fs = Fs)
```
## Cost function implementation
This package allows users to implement their own objective functions. Two examples are shown here.
### Method one - user defined
This method allows users to implement their objective function and all required higher order derivatives manually. This is demonstrated through:
```python
import numpy as np
import spectrally_constrained_LVMs as scLVMs
# Define objective function (maximise source variance)
def cost(X, w, y):
return -1 * np.mean((X @ w) ** 2, axis=0) # Framework performs minimisation
# Define gradient vector
def grad(X, w, y):
return -2 * np.mean(y * X, axis=0, keepdims=True).T
# Define Hessian matrix
def hess(X, w, y):
return -2 * np.cov(X, rowvar=False)
# Initialise the cost instance
user_cost = scLVMs.UserCost(use_hessian = True)
# Define the objective function, gradient and Hessian
user_cost.set_cost(cost)
user_cost.set_gradient(grad)
user_cost.set_hessian(hess)
# Check the implementation
X_ = np.random.randn(1000, 16)
w_ = np.random.randn(16, 1)
y_ = X_ @ w_
res_grad = user_cost.check_gradient(X_, w_, y_,step_size = 1e-4)
res_hess = user_cost.check_hessian(X_, w_, y_,step_size = 1e-4)
```
### Method two - SymPy defined
Users can also use [SymPy](https://www.sympy.org/en/index.html) to implement their objective function, which allows for all higher order derivatives to be obtained symbolically. An example of this is given through
```python
import sympy as sp
import numpy as np
import spectrally_constrained_LVMs as scLVMs
n_samples = 1000 # Fix the number of samples in the data
n_features = 16 # Fix the number of features
# Initialise the cost function instance
user_cost = scLVMs.SympyCost(n_samples, n_features, use_hessian=True)
# Get the SymPy representations of the model parameters
X_sp, w_sp, iter_params = user_cost.get_model_parameters()
i, j = iter_params
# Calculate the objective function (maximise source variance)
loss_i = sp.Sum(w_sp[j, 0] * X_sp[i, j], (j, 0, n_features - 1))
loss = -1 / n_samples * sp.Sum(loss_i**2, (i, 0, n_samples - 1))
# Set the properties within the instance
user_cost.set_cost(loss)
# Use SymPy to calculate the first and second order derivatives
user_cost.implement_methods()
# Check the implementation
X_ = np.random.randn(n_samples, n_features)
w_ = np.random.randn(n_features, 1)
y_ = X_ @ w_
res_grad = user_cost.check_gradient(X_, w_, y_,step_size = 1e-4)
res_hess = user_cost.check_hessian(X_, w_, y_,step_size = 1e-4)
```
# Contributing
This package uses [Poetry](https://python-poetry.org/) for dependency management and Python packaging and [git](https://git-scm.com/) for version control. To get started, first install git and Poetry and then clone this repository via
```console
$ git clone git@github.com:RyanBalshaw/spectrally-constrained-LVMs.git
$ cd spectrally-constrained-LVMs
```
Then, install the necessary dependencies in a local environment via
```console
$ poetry install --with dev,docs
$ poetry shell
```
This will install all necessary package dependencies and activate the virtual environment. You can then set up the [pre-commit](https://pre-commit.com/) hooks via
```console
$ pre-commit install
pre-commit installed at .git/hooks/pre-commit
```
# License
This project is licensed under MIT License - see the [LICENSE](https://github.com/RyanBalshaw/spectrally-constrained-LVMs/blob/main/LICENSE) file for details.
Raw data
{
"_id": null,
"home_page": "https://github.com/RyanBalshaw/spectrally-constrained-LVMs",
"name": "spectrally-constrained-lvms",
"maintainer": "Ryan Balshaw",
"docs_url": null,
"requires_python": ">=3.10,<4.0",
"maintainer_email": "ryanbalshaw81@gmail.com",
"keywords": "Linear LVMs,spectral constraint,PCA,ICA",
"author": "Ryan Balshaw",
"author_email": "ryanbalshaw81@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/c4/c4/f1500cb28c05fa2c0af8b651de93759dd63493262cd2890e7611aaf7c6d0/spectrally_constrained_lvms-0.1.3.tar.gz",
"platform": null,
"description": "# Spectrally constrained LVMs\n![GitHub license](https://img.shields.io/github/license/RyanBalshaw/spectrally-constrained-LVMs)\n![GitHub last commit](https://img.shields.io/github/last-commit/RyanBalshaw/spectrally-constrained-LVMs)\n![PyPI](https://img.shields.io/pypi/v/spectrally-constrained-lvms)\n![PyPI - Wheel](https://img.shields.io/pypi/wheel/spectrally-constrained-lvms?color=blueviolet)\n![Read the Docs](https://img.shields.io/readthedocs/spectrally-constrained-lvms?color=informational)\n![GitHub issues](https://img.shields.io/github/issues/RyanBalshaw/spectrally-constrained-LVMs?color=critical)\n\n*Current version:* 0.1.3\n\nSpectrally-constrained-LVMs is a Python-based package which facilitates the estimation of the linear latent variable model (LVM) parameters with a unique spectral constraint in single-channel time-series applications.\n\n## Purpose\nLVMs are a statistical methodology which tries to capture the underlying structure in some observed data. This package caters to single channel time-series applications and provides a methodology to estimate the LVM parameters. The model parameters are encouraged to be diverse via a spectral constraint which enforces non-duplication of the spectral information captured by the latent sources.\n\nThe purpose of this package is to provide a complete methodology that caters to a variety of LVM objective functions.\n\n# Documentation\nPlease visit [the docs](http://spectrally-constrained-lvms.readthedocs.io/) for all supporting documentation for this package.\n\n# Installation\nThe package is designed to be used through the Python API, and can be installed using [pip](https://pypi.org/project/pip/):\n```console\n$ pip install spectrally-constrained-LVMs\n```\n\n# Requirements\n\nThis package used Python \u2265 3.10 or later to run. For other python dependencies, please check the `pyproject.toml`\n[file](https://github.com/RyanBalshaw/spectrally-constrained-LVMs/blob/main/pyproject.toml) included in this repository. The dependencies of this package are as follows:\n\n| Package \t | Version \t |\n|:----------------------------------------------:|:----------:|\n| [Python](https://www.python.org/) \t | \u2265 3.10 \t |\n| [Numpy](https://numpy.org/) \t | \u2265 1.23.1 \t |\n| [Matplotlib](https://matplotlib.org/) \t | \u2265 3.5.2 \t |\n| [SciPy](https://scipy.org/) \t | \u2265 1.8.1 \t |\n| [scikit-learn](https://scikit-learn.org/) \t | \u2265 1.1.2 \t |\n| [tqdm](https://github.com/tqdm/tqdm) \t | \u2265 4.64.1 \t |\n| [SymPy](https://www.sympy.org/en/index.html) \t | \u2265 1.1.1 \t |\n\n# API usage\n\n## Model parameter estimation\nA generic example is shown below:\n```python\nimport spectrally_constrained_LVMs as scLVMs\n\n# Load in some data\nsignal_data = ... # Load a single channel time-series signal\nFs = ... # Sampling frequency of the data\n\n# Hankelise the data\nX = scLVMs.hankel_matrix(signal_data,\n Lw = 512,\n Lsft = 1)\n\n# Define a cost function for latent sources with maximum variance\ncost_inst = scLVMs.VarianceCost()\n\n# Define a model instance\nmodel_inst = scLVMs.LinearModel(n_sources=10,\n cost_instance=cost_inst,\n whiten=False,\n alpha_reg=1.0)\n\n# Estimate the model parameters\nmodel_inst.fit(X, Fs = Fs)\n```\n\n## Cost function implementation\nThis package allows users to implement their own objective functions. Two examples are shown here.\n\n### Method one - user defined\n\nThis method allows users to implement their objective function and all required higher order derivatives manually. This is demonstrated through:\n```python\nimport numpy as np\nimport spectrally_constrained_LVMs as scLVMs\n\n# Define objective function (maximise source variance)\ndef cost(X, w, y):\n\n return -1 * np.mean((X @ w) ** 2, axis=0) # Framework performs minimisation\n\n# Define gradient vector\ndef grad(X, w, y):\n\n return -2 * np.mean(y * X, axis=0, keepdims=True).T\n\n# Define Hessian matrix\ndef hess(X, w, y):\n\n return -2 * np.cov(X, rowvar=False)\n\n# Initialise the cost instance\nuser_cost = scLVMs.UserCost(use_hessian = True)\n\n# Define the objective function, gradient and Hessian\nuser_cost.set_cost(cost)\nuser_cost.set_gradient(grad)\nuser_cost.set_hessian(hess)\n\n# Check the implementation\nX_ = np.random.randn(1000, 16)\nw_ = np.random.randn(16, 1)\ny_ = X_ @ w_\n\nres_grad = user_cost.check_gradient(X_, w_, y_,step_size = 1e-4)\nres_hess = user_cost.check_hessian(X_, w_, y_,step_size = 1e-4)\n```\n\n### Method two - SymPy defined\nUsers can also use [SymPy](https://www.sympy.org/en/index.html) to implement their objective function, which allows for all higher order derivatives to be obtained symbolically. An example of this is given through\n```python\nimport sympy as sp\nimport numpy as np\nimport spectrally_constrained_LVMs as scLVMs\n\nn_samples = 1000 # Fix the number of samples in the data\nn_features = 16 # Fix the number of features\n\n# Initialise the cost function instance\nuser_cost = scLVMs.SympyCost(n_samples, n_features, use_hessian=True)\n\n# Get the SymPy representations of the model parameters\nX_sp, w_sp, iter_params = user_cost.get_model_parameters()\ni, j = iter_params\n\n# Calculate the objective function (maximise source variance)\nloss_i = sp.Sum(w_sp[j, 0] * X_sp[i, j], (j, 0, n_features - 1))\nloss = -1 / n_samples * sp.Sum(loss_i**2, (i, 0, n_samples - 1))\n\n# Set the properties within the instance\nuser_cost.set_cost(loss)\n\n# Use SymPy to calculate the first and second order derivatives\nuser_cost.implement_methods()\n\n# Check the implementation\nX_ = np.random.randn(n_samples, n_features)\nw_ = np.random.randn(n_features, 1)\ny_ = X_ @ w_\n\nres_grad = user_cost.check_gradient(X_, w_, y_,step_size = 1e-4)\nres_hess = user_cost.check_hessian(X_, w_, y_,step_size = 1e-4)\n```\n\n# Contributing\nThis package uses [Poetry](https://python-poetry.org/) for dependency management and Python packaging and [git](https://git-scm.com/) for version control. To get started, first install git and Poetry and then clone this repository via\n```console\n$ git clone git@github.com:RyanBalshaw/spectrally-constrained-LVMs.git\n$ cd spectrally-constrained-LVMs\n```\n\nThen, install the necessary dependencies in a local environment via\n```console\n$ poetry install --with dev,docs\n$ poetry shell\n```\n\nThis will install all necessary package dependencies and activate the virtual environment. You can then set up the [pre-commit](https://pre-commit.com/) hooks via\n```console\n$ pre-commit install\npre-commit installed at .git/hooks/pre-commit\n```\n\n# License\nThis project is licensed under MIT License - see the [LICENSE](https://github.com/RyanBalshaw/spectrally-constrained-LVMs/blob/main/LICENSE) file for details.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "An optimisation implementation of linear transforms with a spectral constraint.",
"version": "0.1.3",
"project_urls": {
"Bug tracker": "https://github.com/RyanBalshaw/spectrally-constrained-LVMs/issues",
"Documentation": "https://github.com/RyanBalshaw/spectrally-constrained-LVMs",
"Homepage": "https://github.com/RyanBalshaw/spectrally-constrained-LVMs",
"Repository": "https://github.com/RyanBalshaw/spectrally-constrained-LVMs"
},
"split_keywords": [
"linear lvms",
"spectral constraint",
"pca",
"ica"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "c5ab45fa466e773860e423dd9c8e566638a687cf34bde25e5d1a10fc97d8d1af",
"md5": "1f9c94f2c50d74f9509af260ca56675b",
"sha256": "9f426399ad2733c1a0dbc3c18249eeada17f3df21ec5cb6863b5627af072bb0e"
},
"downloads": -1,
"filename": "spectrally_constrained_lvms-0.1.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "1f9c94f2c50d74f9509af260ca56675b",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10,<4.0",
"size": 34270,
"upload_time": "2023-05-29T12:15:26",
"upload_time_iso_8601": "2023-05-29T12:15:26.327840Z",
"url": "https://files.pythonhosted.org/packages/c5/ab/45fa466e773860e423dd9c8e566638a687cf34bde25e5d1a10fc97d8d1af/spectrally_constrained_lvms-0.1.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "c4c4f1500cb28c05fa2c0af8b651de93759dd63493262cd2890e7611aaf7c6d0",
"md5": "11875348fe79db8daadade476f555bcc",
"sha256": "96b8381906163d07f03eebf255ae7aa6d3fd0c796234166359d15ad81c3dd1dd"
},
"downloads": -1,
"filename": "spectrally_constrained_lvms-0.1.3.tar.gz",
"has_sig": false,
"md5_digest": "11875348fe79db8daadade476f555bcc",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10,<4.0",
"size": 32454,
"upload_time": "2023-05-29T12:15:28",
"upload_time_iso_8601": "2023-05-29T12:15:28.567746Z",
"url": "https://files.pythonhosted.org/packages/c4/c4/f1500cb28c05fa2c0af8b651de93759dd63493262cd2890e7611aaf7c6d0/spectrally_constrained_lvms-0.1.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-05-29 12:15:28",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "RyanBalshaw",
"github_project": "spectrally-constrained-LVMs",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [],
"lcname": "spectrally-constrained-lvms"
}