Skip to main content

Value-driven and cost-sensitive tools for scikit-learn

Project description

PyPI Downloads Python Version GitHub license Tests Docs Ruff DOI

Empulse

Empulse Logo

Empulse is a package aimed to enable value-driven and cost-sensitive analysis in Python. The package implements popular value-driven and cost-sensitive metrics and algorithms in accordance to sci-kit learn conventions. This allows the measures to seamlessly integrate into existing ML workflows.

Installation

Empulse requires python 3.10 or higher.

Install empulse via pip with

pip install empulse

Documentation

You can find the documentation here.

Features

Take the tour

Ready to use out of the box with scikit-learn

All components of the package are designed to work seamlessly with scikit-learn.

Models are implemented as scikit-learn estimators and can be used anywhere a scikit-learn estimator can be used.

Pipelines

from empulse.models import CSLogitClassifier
from sklearn.datasets import make_classification
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler

X, y = make_classification()
pipeline = Pipeline([
    ("scaler", StandardScaler()),
    ("model", CSLogitClassifier())
])
pipeline.fit(X, y, model__fp_cost=2, model__fn_cost=1)

Cross-validation

from sklearn.model_selection import cross_val_score

cross_val_score(
    pipeline, 
    X, 
    y, 
    scoring="roc_auc", 
    params={"model__fp_cost": 2, "model__fn_cost": 1}
)

Grid search

from sklearn.model_selection import GridSearchCV

param_grid = {"model__C": [0.1, 1, 10]}
grid_search = GridSearchCV(pipeline, param_grid, scoring="roc_auc")
grid_search.fit(X, y, model__fp_cost=2, model__fn_cost=1)

All metrics can easily be converted as scikit-learn scorers and can be used in the same way as any other scikit-learn scorer.

from empulse.metrics import expected_cost_loss
from sklearn.metrics import make_scorer

scorer = make_scorer(
    expected_cost_loss, 
    response_method="predict_proba", 
    greater_is_better=False,
    fp_cost=2,
    fn_cost=1
)
cross_val_score(pipeline, X, y, scoring=scorer)

Use case specific profit and cost metrics

Empulse offers a wide range of profit and cost metrics that are tailored to specific use cases such as:

For other use cases, the package provides a generic implementations for:

Flexible profit-driven and cost-sensitive models

Empulse provides a range of profit-driven and cost-sensitive models such as:

Each classifier tries to balance ease of use through good defaults and flexibility through a wide range of parameters.

For instance, the CSLogitClassifier allows you to change the loss function and the optimization method:

import numpy as np
from empulse.models import CSLogitClassifier
from empulse.metrics import expected_savings_score
from scipy.optimize import minimize, OptimizeResult

def optimize(objective, X, **kwargs) -> OptimizeResult:
    initial_guess = np.zeros(X.shape[1])
    result = minimize(
        lambda x: -objective(x),  # inverse objective function to maximize
        initial_guess,
        method='BFGS',
        **kwargs
    )
    return result
model = CSLogitClassifier(loss=expected_savings_score, optimize_fn=optimize)

Easy passing of instance-dependent costs

Instance-dependent costs can easily be passed to the models through metadata routing.

For instance, the instance-dependent costs are passed dynamically to each fold of the cross-validation through requesting the costs in the set_fit_request method of the model and the set_score_request method of the scorer.

import numpy as np
from empulse.models import CSLogitClassifier
from empulse.metrics import expected_cost_loss
from sklearn import set_config
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.metrics import make_scorer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler

set_config(enable_metadata_routing=True)

X, y = make_classification()
fp_cost = np.random.rand(y.size)
fn_cost = np.random.rand(y.size)

pipeline = Pipeline([
    ("scale", StandardScaler()),
    ("model", CSLogitClassifier().set_fit_request(fp_cost=True, fn_cost=True))
])

scorer = make_scorer(
    expected_cost_loss,
    response_method="predict_proba",
    greater_is_better=False,
).set_score_request(fp_cost=True, fn_cost=True)

cross_val_score(pipeline, X, y, scoring=scorer, params={"fp_cost": fp_cost, "fn_cost": fn_cost})

Cost-aware resampling and relabeling

Empulse uses the imbalanced-learn package to provide cost-aware resampling and relabeling techniques:

from empulse.samplers import CostSensitiveSampler
from sklearn.datasets import make_classification

X, y = make_classification()
sampler = CostSensitiveSampler()
X_resampled, y_resampled = sampler.fit_resample(X, y, fp_cost=2, fn_cost=1)

They can be used in an imbalanced-learn pipeline:

import numpy as np
from empulse.samplers import CostSensitiveSampler
from imblearn.pipeline import Pipeline
from sklearn import set_config
from sklearn.datasets import make_classification
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression

set_config(enable_metadata_routing=True)

X, y = make_classification()
fp_cost = np.random.rand(y.size)
fn_cost = np.random.rand(y.size)
pipeline = Pipeline([
    ("scaler", StandardScaler()),
    ("sampler", CostSensitiveSampler().set_fit_resample_request(fp_cost=True, fn_cost=True)),
    ("model", LogisticRegression())
])

pipeline.fit(X, y, fp_cost=fp_cost, fn_cost=fn_cost)

Find the optimal decision threshold

Empulse provides the CSThresholdClassifier which allows you to find the optimal decision threshold for a given cost matrix to minimize the expected cost loss.

The meta-estimator changes the predict method of the base estimator to predict the class with the lowest expected cost.

from empulse.models import CSThresholdClassifier
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression

X, y = make_classification()
model = CSThresholdClassifier(estimator=LogisticRegression())
model.fit(X, y)
model.predict(X, fp_cost=2, fn_cost=1)

Metrics like the maximum profit score conveniently return the optimal target threshold. For example the Expected Maximum Profit measure for customer churn (EMPC) tells you what fraction of the customer base should be targeted to maximize profit.

from empulse.metrics import empc
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression

X, y = make_classification()
model = LogisticRegression()
predictions = model.fit(X, y).predict_proba(X)[:, 1]

score, threshold = empc(y, predictions, clv=50)

This score can then be converted to a decision threshold by using the classification_threshold function.

from empulse.metrics import classification_threshold

decision_threshold = classification_threshold(y, predictions, customer_threshold=threshold)

This can then be combined with sci-kit learn's FixedThresholdClassifier to create a model that predicts the class with the highest expected profit.

from sklearn.model_selection import FixedThresholdClassifier

model = FixedThresholdClassifier(estimator=model, threshold=decision_threshold)
model.predict(X)

Easy access to real-world datasets for benchmarking

Empulse provides easy access to real-world datasets for benchmarking cost-sensitive models.

Each dataset returns the features, the target, and the instance-dependent costs, ready to use in a cost-sensitive model.

from empulse.datasets import load_give_me_some_credit
from empulse.models import CSLogitClassifier
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler

X, y, tp_cost, fp_cost, tn_cost, fn_cost = load_give_me_some_credit(return_X_y_costs=True)

pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('model', CSLogitClassifier())
])
pipeline.fit(
    X, 
    y, 
    model__tp_cost=tp_cost, 
    model__fp_cost=fp_cost, 
    model__tn_cost=tn_cost, 
    model__fn_cost=fn_cost
)

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

empulse-0.9.0.tar.gz (4.0 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

empulse-0.9.0-py3-none-any.whl (4.1 MB view details)

Uploaded Python 3

File details

Details for the file empulse-0.9.0.tar.gz.

File metadata

  • Download URL: empulse-0.9.0.tar.gz
  • Upload date:
  • Size: 4.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for empulse-0.9.0.tar.gz
Algorithm Hash digest
SHA256 3e4cf4b80889228897fa523ad0f58b54f1853f1957ee156400071abe8c743061
MD5 97c0976354f727a79a622c87a44a29c1
BLAKE2b-256 040ef05b44fe0b96f10df9389a1fe610db44bd2b2a26e5b2bbf723ea8d26d51a

See more details on using hashes here.

Provenance

The following attestation bundles were made for empulse-0.9.0.tar.gz:

Publisher: release.yml on ShimantoRahman/empulse

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file empulse-0.9.0-py3-none-any.whl.

File metadata

  • Download URL: empulse-0.9.0-py3-none-any.whl
  • Upload date:
  • Size: 4.1 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for empulse-0.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c12d1289f6696355d73bca1fdaabf7de8b84662347ec9391e3b9c87a603998ea
MD5 e878ebaf1b66aa2a3663cc98a25fc321
BLAKE2b-256 8afc2864ae566b7fdfde5d87d98c52f8a5fab330eee9fad2217c0eba7d5c7837

See more details on using hashes here.

Provenance

The following attestation bundles were made for empulse-0.9.0-py3-none-any.whl:

Publisher: release.yml on ShimantoRahman/empulse

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page