Fast, vectorized lexicase selection in NumPy and JAX
Project description
🧬 Lexicase Selection Library
A fast, vectorized lexicase selection implementation supporting both NumPy and JAX backends.
🎯 What it does
Lexicase selection is a parent selection method used in evolutionary computation that evaluates individuals on test cases in random order, keeping only those that perform best on each case. This library provides efficient implementations of several lexicase variants:
- Base Lexicase: Standard lexicase selection algorithm
- Epsilon Lexicase: Allows individuals within epsilon of the best to be considered equally good (uses adaptive MAD-based epsilon by default)
- Downsampled Lexicase: Uses random subsets of test cases to increase diversity
📦 Installation
PyPI
pip install lexicase
To use the numpy backend, you can use the following command:
pip install lexicase[numpy]
To use the JAX backend, you need to install JAX and JAXlib and then use the following command:
pip install lexicase[jax]
Source Installation
To install from source, clone the repository and then run the following command:
pip install -e .
Development Installation
pip install .[dev] # Includes pytest and coverage tools
🚀 Quick Start
import numpy as np
import lexicase
# Create a fitness matrix (individuals × test cases)
# Higher values = better performance
fitness_matrix = np.array([
[10, 5, 8], # Individual 0
[8, 9, 6], # Individual 1
[6, 7, 9], # Individual 2
[4, 3, 7] # Individual 3
])
# Select 5 individuals using standard lexicase
selected = lexicase.lexicase_selection(
fitness_matrix,
num_selected=5,
seed=42
)
print(f"Selected individuals: {selected}")
# Use epsilon lexicase with adaptive MAD-based epsilon (recommended)
selected_eps = lexicase.epsilon_lexicase_selection(
fitness_matrix,
num_selected=5,
seed=42
)
print(f"Epsilon lexicase selected: {selected_eps}")
🔧 Backend Selection
Switch between NumPy and JAX backends:
import lexicase
# Use NumPy backend (default)
lexicase.set_backend("numpy")
# Use JAX backend for GPU acceleration
lexicase.set_backend("jax")
# Check current backend
print(f"Current backend: {lexicase.get_backend()}")
📊 All Selection Methods
Standard Lexicase
selected = lexicase.lexicase_selection(fitness_matrix, num_selected=10, seed=42)
Epsilon Lexicase
# Recommended: Use adaptive MAD-based epsilon (automatic)
selected = lexicase.epsilon_lexicase_selection(
fitness_matrix,
num_selected=10,
seed=42
)
# Alternative: Manual epsilon specification
selected = lexicase.epsilon_lexicase_selection(
fitness_matrix,
num_selected=10,
epsilon=0.5, # Tolerance for "equal" performance
seed=42
)
Downsampled Lexicase
selected = lexicase.downsample_lexicase_selection(
fitness_matrix,
num_selected=10,
downsample_size=5, # Use only 5 random test cases per selection
seed=42
)
🧪 Testing
Run the test suite:
pytest tests/
Run with coverage:
pytest tests/ --cov=lexicase --cov-report=html
🔬 Algorithm Details
Lexicase Selection Process:
- Shuffle the order of test cases
- Start with all individuals as candidates
- For each test case (in shuffled order):
- Find the best performance on this case
- Keep only individuals matching the best performance
- If only one individual remains, select it
- If multiple individuals remain after all cases, select randomly
Epsilon Lexicase: Considers individuals within epsilon of the best performance as equally good. By default, uses adaptive epsilon values based on the Median Absolute Deviation (MAD) of fitness values for each test case, providing robust and data-driven tolerance levels.
Downsampled Lexicase: Uses only a random subset of test cases, increasing selection diversity.
📈 Performance Tips
- Use JAX backend for large matrices and GPU acceleration
- Downsampled variants are faster and often more diverse
- For epsilon lexicase, the adaptive MAD-based epsilon (default) is recommended for most use cases
- Use seeds for reproducible results
📚 Citation
If you use this library in your research, please cite:
@software{lexicase_selection,
title={Lexicase Selection Library},
author={Ryan Bahlous-Boldi},
year={2024},
url={https://github.com/ryanboldi/lexicase}
}
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
TODOs:
- make jax implementaion faster, and jittable.
- Add informed down-sampling
- Add some demo notebooks
🔗 References
- Spector, L. (2012). Assessment of Problem Modality by Differential Performance of Lexicase Selection in Genetic Programming: A Preliminary Report. In Companion Publication of the 2012 Genetic and Evolutionary Computation Conference, GECCO’12 Companion. ACM Press. pp. 401 - 408.
- Helmuth, T., L. Spector, and J. Matheson. (2014). Solving Uncompromising Problems with Lexicase Selection. In IEEE Transactions on Evolutionary Computation, vol. 19, no. 5, pp. 630 - 643.
- La Cava, W., L. Spector, and K. Danai (2016). Epsilon-lexicase selection for regression. GECCO '16: Proceedings of the Genetic and Evolutionary Computation Conference, pp. 741 - 748.
- Hernandez, J. G., A. Lalejini, E. Dolson, and C. Ofria (2019). Random subsampling improves performance in lexicase selection. GECCO '19: Proceedings of the Genetic and Evolutionary Computation Conference Companion, pp. 2028 - 2031
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lexicase-0.1.1.tar.gz.
File metadata
- Download URL: lexicase-0.1.1.tar.gz
- Upload date:
- Size: 10.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
332f39be9e08d27672a2ce56613bd21ce87d696f9bedb7e8800d225bada83127
|
|
| MD5 |
18b243a0dd2d98196a095a392cd50829
|
|
| BLAKE2b-256 |
d72e7bdc5eb21650f5ac9d494529317b0d41121fed71dc7d74111739588927c5
|
File details
Details for the file lexicase-0.1.1-py3-none-any.whl.
File metadata
- Download URL: lexicase-0.1.1-py3-none-any.whl
- Upload date:
- Size: 10.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f94e9bbdd1e741ab5b30646084912cf218bd3ceab2b0afe4f8806e331e71dafe
|
|
| MD5 |
a66b8fc0a264f0c9be858f2492b5bf27
|
|
| BLAKE2b-256 |
ac440c3dcebe1cfa95a59f9fcc9a1f48a57871c39ad9e7bb0056e035b71c97f7
|