Binary Crested Porcupine Optimizer (BCPO) for feature selection
Project description
bcpo-feature-selector
bcpo-feature-selector is a Python library that implements the Binary Crested Porcupine Optimizer (BCPO) for feature selection. It provides a robust, scikit-learn compatible interface to select the optimal subset of features for both classification and regression tasks.
The library is based on the Crested Porcupine Optimizer (CPO), a nature-inspired meta-heuristic algorithm that mimics the defensive behaviors of the crested porcupine. By adapting CPO to a binary search space, bcpo-feature-selector efficiently explores the feature space to maximize model performance while minimizing the number of selected features.
Key Features
- Scikit-learn Compatibility: Designed to work seamlessly with
scikit-learnestimators, pipelines, and cross-validation tools. - Dual Support: Supports both Classification (
BCPOClassifierSelector) and Regression (BCPORegressorSelector) tasks. - Customizable Metrics: Optimizes for various built-in metrics (Accuracy, F1-score, ROC-AUC, MAE, MSE, R2) or accepts custom scoring functions.
- Efficiency: Leverages swarm intelligence to solve the NP-hard problem of feature selection more efficiently than exhaustive search.
Installation
From PyPI
You can install the package directly from PyPI:
pip install bcpo-feature-selector
From Source
This project uses pyproject.toml. You can install it directly from the source:
# Clone the repository
git clone https://github.com/ThienNguyen3001/bcpo-feature-selector.git
cd bcpo-feature-selector
# Install in editable mode
pip install -e .
For development (including testing dependencies):
pip install -e .[dev]
Quick Start
Classification Example
Optimize accuracy using a Naive Bayes classifier on the Breast Cancer dataset.
from sklearn.datasets import load_breast_cancer
from sklearn.naive_bayes import GaussianNB
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from bcpo_feature_selector.classification import BCPOClassifierSelector
# Load data
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Initialize selector
selector = BCPOClassifierSelector(
estimator=GaussianNB(),
metric="accuracy",
num_agents=30,
max_iter=50,
random_state=42,
verbose=1
)
# Fit and transform
selector.fit(X_train, y_train)
X_train_selected = selector.transform(X_train)
X_test_selected = selector.transform(X_test)
# Evaluate
print(f"Original features: {X.shape[1]}")
print(f"Selected features: {X_train_selected.shape[1]}")
print(f"Selected indices: {selector.get_support(indices=True)}")
# Train a model on selected features
model = GaussianNB()
model.fit(X_train_selected, y_train)
y_pred = model.predict(X_test_selected)
print(f"Test Accuracy: {accuracy_score(y_test, y_pred):.4f}")
Regression Example
Optimize Mean Absolute Error (MAE) using ElasticNet on the Diabetes dataset.
from sklearn.datasets import load_diabetes
from sklearn.linear_model import ElasticNet
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_absolute_error
from bcpo_feature_selector.regression import BCPORegressorSelector
# Load data
X, y = load_diabetes(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Initialize selector (Note: for regression, metrics like 'mae', 'mse' are minimized internally)
selector = BCPORegressorSelector(
estimator=ElasticNet(random_state=42),
metric="neg_mean_absolute_error",
num_agents=20,
max_iter=30,
random_state=42
)
# Fit
selector.fit(X_train, y_train)
# Transform
X_train_sel = selector.transform(X_train)
X_test_sel = selector.transform(X_test)
print(f"Best internal validation score (MAE): {selector.best_score_:.4f}")
print(f"Features reduced from {X.shape[1]} to {X_train_sel.shape[1]}")
Configuration
The BCPOClassifierSelector and BCPORegressorSelector expose several parameters to control the optimization process:
estimator: The base estimator used to evaluate feature subsets. If None, usesKNeighborsClassifier(n_neighbors=5) for classification andRidgeregression for regression.metric: The metric to optimize.- Classification:
'accuracy','f1','precision','recall','roc_auc'. - Regression:
'neg_mean_squared_error','neg_root_mean_squared_error','neg_mean_absolute_error','r2'.
- Classification:
metric_average: (Classification only) Averaging method for multi-class metrics (e.g.,'binary','micro','macro','weighted'). Default is'binary'.num_agents: Number of search agents (population size). Higher values explore more but are slower (default: 30).max_iter: Maximum number of iterations for the optimization (default: 100).max_features: The maximum number of features to select. Can be an integer, a callable, or None (default: None).test_size: Proportion of the dataset to include in the internal validation split (default: 0.3).w_error(Classification) /w_loss(Regression): Weight for the error/loss component in the fitness function (default: 0.99).w_feat: Weight for the feature reduction component (default: 0.01).t_cycle: Cycle length parameter for the population reduction mechanism (default: 2).n_min: Minimum number of agents to keep during population reduction (default: 5).alpha_max: Maximum value for the alpha parameter in the update rule (default: 0.2).verbose: Level of verbosity (0, 1, or 2).
The Fitness Function
The library uses a weighted fitness function to balance prediction performance and dimensionality reduction:
$$ Fitness = \alpha \times Error + \beta \times \frac{|S|}{|Total|} $$
Where:
- $Error = 1 - Metric$ (for maximization metrics) or the normalized loss (for regression).
- $|S|$ is the number of selected features.
- $\alpha$ (
w_errororw_loss) and $\beta$ (w_feat) control the trade-off.
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for details on how to report bugs, suggest features, or submit pull requests.
This project enforces a Code of Conduct. By participating, you are expected to uphold this code.
License
This project is licensed under the MIT License - see the LICENSE file for details.
References
Project details
Release history Release notifications | RSS feed
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 bcpo_feature_selector-0.1.0.post1.tar.gz.
File metadata
- Download URL: bcpo_feature_selector-0.1.0.post1.tar.gz
- Upload date:
- Size: 16.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2581d31ebdbda4b3e32d88bcebfc8a8e938a27217e32d54c63d8ba25ba61a6c3
|
|
| MD5 |
0a58e61239d008d9a9ec0060aa9b0e92
|
|
| BLAKE2b-256 |
3f9fda3a9096f9da46dc98e3fa5dbc76a14f0f87fc59b750ddc80c7a8e8858be
|
Provenance
The following attestation bundles were made for bcpo_feature_selector-0.1.0.post1.tar.gz:
Publisher:
publish-to-pypi.yml on ThienNguyen3001/bcpo-feature-selector
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bcpo_feature_selector-0.1.0.post1.tar.gz -
Subject digest:
2581d31ebdbda4b3e32d88bcebfc8a8e938a27217e32d54c63d8ba25ba61a6c3 - Sigstore transparency entry: 815786042
- Sigstore integration time:
-
Permalink:
ThienNguyen3001/bcpo-feature-selector@05582c5582a4153ce8e83d08f509b7a6d112cac1 -
Branch / Tag:
refs/tags/0.1.0.post1 - Owner: https://github.com/ThienNguyen3001
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@05582c5582a4153ce8e83d08f509b7a6d112cac1 -
Trigger Event:
release
-
Statement type:
File details
Details for the file bcpo_feature_selector-0.1.0.post1-py3-none-any.whl.
File metadata
- Download URL: bcpo_feature_selector-0.1.0.post1-py3-none-any.whl
- Upload date:
- Size: 17.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c0e21aac6a99a69acac0b5a295277eac85ecc0005d6b69cbc94d97427b231de7
|
|
| MD5 |
73b70a23e90fe0a20fdcdeef1ae8deed
|
|
| BLAKE2b-256 |
31a6d741bb97ab50afaa8ea9c49e6ed756ee43abad8f4d94213c4d9187c12b7c
|
Provenance
The following attestation bundles were made for bcpo_feature_selector-0.1.0.post1-py3-none-any.whl:
Publisher:
publish-to-pypi.yml on ThienNguyen3001/bcpo-feature-selector
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bcpo_feature_selector-0.1.0.post1-py3-none-any.whl -
Subject digest:
c0e21aac6a99a69acac0b5a295277eac85ecc0005d6b69cbc94d97427b231de7 - Sigstore transparency entry: 815786043
- Sigstore integration time:
-
Permalink:
ThienNguyen3001/bcpo-feature-selector@05582c5582a4153ce8e83d08f509b7a6d112cac1 -
Branch / Tag:
refs/tags/0.1.0.post1 - Owner: https://github.com/ThienNguyen3001
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@05582c5582a4153ce8e83d08f509b7a6d112cac1 -
Trigger Event:
release
-
Statement type: