GaussianMixtureBinning
- class binlearn.methods.GaussianMixtureBinning(n_components: int | str | None = None, random_state: int | None = None, allow_fallback: bool | None = None, clip: bool | None = None, preserve_dataframe: bool | None = None, fit_jointly: bool | None = None, *, bin_edges: dict[Any, list[float]] | None = None, bin_representatives: dict[Any, list[float]] | None = None, class_: str | None = None, module_: str | None = None)[source]
Bases:
IntervalBinningBaseGaussian Mixture Model clustering-based binning implementation using clean architecture.
Creates bins based on Gaussian Mixture Model (GMM) clustering of each feature. The bin edges are determined by the decision boundaries between mixture components, creating bins that represent natural probabilistic groupings in the data based on underlying Gaussian distributions.
The GMM algorithm assumes the data can be modeled as a mixture of Gaussian distributions and finds the optimal parameters (means, covariances, weights) for each component. Bin boundaries are placed at the midpoints between adjacent component means, creating intervals that correspond to regions where different Gaussian components are most likely.
This approach is particularly effective for data with multiple modes or natural clustering, as it can identify and separate these distributions automatically. Unlike k-means clustering, GMM provides probabilistic cluster assignments and can handle clusters of different shapes and densities.
When GMM fitting fails (e.g., due to numerical issues or insufficient data), the algorithm automatically falls back to equal-width binning to ensure robust operation.
This implementation follows the clean binlearn architecture with straight inheritance, dynamic column resolution, and parameter reconstruction capabilities.
- Parameters:
n_components – Number of Gaussian components (mixture components) to fit. Controls the number of bins created. Can be an integer or a string expression like ‘sqrt’, ‘log2’, etc. for dynamic calculation based on data size. If None, uses configuration default.
random_state – Random seed for reproducible GMM fitting. Controls the random initialization of component parameters. If None, results may vary between runs due to random initialization.
allow_fallback – Whether to fall back to equal-width binning when GMM fitting fails. If True (default), uses equal-width binning as fallback with a warning. If False, raises an error when GMM fails. If None, uses configuration default.
clip – Whether to clip values outside the fitted range to the nearest bin edge. If None, uses configuration default.
preserve_dataframe – Whether to preserve pandas DataFrame structure in transform operations. If None, uses configuration default.
fit_jointly – Whether to fit all columns together (False for GMM - always fits columns independently). If None, uses configuration default.
bin_edges – Pre-computed bin edges for reconstruction. Should not be provided during normal usage.
bin_representatives – Pre-computed bin representatives for reconstruction. Should not be provided during normal usage.
class – Class name for reconstruction compatibility. Internal use only.
module – Module name for reconstruction compatibility. Internal use only.
- n_components
Number of mixture components to fit
- random_state
Random seed for reproducible results
- allow_fallback
Whether to fall back to equal-width binning when needed
- allow_fallback
Whether to fall back to equal-width binning on failure
Example
>>> import numpy as np >>> from binlearn.methods import GaussianMixtureBinning >>> >>> # Create sample data with multiple modes >>> np.random.seed(42) >>> data = np.concatenate([ ... np.random.normal(-2, 0.5, 200), # First mode ... np.random.normal(1, 0.8, 300), # Second mode ... np.random.normal(4, 0.3, 150) # Third mode ... ]) >>> >>> # Initialize GMM binning with 3 components >>> binner = GaussianMixtureBinning(n_components=3, random_state=42) >>> >>> # Fit and transform >>> X = data.reshape(-1, 1) >>> binner.fit(X) >>> X_binned = binner.transform(X) >>> >>> # Check identified components >>> print(f"Number of bins: {len(binner.bin_edges_[0]) - 1}") >>> print(f"Bin representatives: {binner.bin_representatives_[0]}")
Note
GMM is particularly effective for data with natural multimodal distributions
Component means become the bin representatives (centers of identified modes)
Bin boundaries are placed at midpoints between adjacent component means
Requires sufficient data points (at least n_components) per column
Falls back to equal-width binning if GMM fitting fails
Each column is processed independently (unsupervised approach)
Uses full covariance type for maximum flexibility in component shapes
See also
KMeansBinning: Alternative clustering-based binning with hard cluster assignments DBSCANBinning: Density-based clustering for irregularly shaped clusters EqualWidthBinning: Simple equal-width interval binning
- __init__(n_components: int | str | None = None, random_state: int | None = None, allow_fallback: bool | None = None, clip: bool | None = None, preserve_dataframe: bool | None = None, fit_jointly: bool | None = None, *, bin_edges: dict[Any, list[float]] | None = None, bin_representatives: dict[Any, list[float]] | None = None, class_: str | None = None, module_: str | None = None)[source]
Initialize Gaussian Mixture binning with clustering parameters.
Sets up GMM-based binning with specified parameters. Applies configuration defaults for any unspecified parameters and validates the resulting configuration.
- Parameters:
n_components – Number of Gaussian components (mixture components) to fit. Controls the number of bins created. Can be: - Integer: Exact number of components - String: Dynamic calculation expression (‘sqrt’, ‘log2’, etc.) Must be positive. If None, uses configuration default.
random_state – Random seed for reproducible GMM fitting. Controls the random initialization of component parameters. Should be a non-negative integer. If None, results may vary between runs.
allow_fallback – Whether to fall back to equal-width binning when GMM fitting fails. If True (default), uses equal-width binning as fallback with a warning. If False, raises an error when GMM fails. If None, uses configuration default.
clip – Whether to clip transformed values outside the fitted range to the nearest bin edge. If None, uses configuration default.
preserve_dataframe – Whether to preserve pandas DataFrame structure in transform operations. If None, uses configuration default.
fit_jointly – Whether to fit all columns together. Always False for GMM as it processes columns independently. If None, uses configuration default.
bin_edges – Pre-computed bin edges dictionary for reconstruction. Internal use only - should not be provided during normal initialization.
bin_representatives – Pre-computed representatives dictionary for reconstruction. Internal use only.
class – Class name string for reconstruction compatibility. Internal use only.
module – Module name string for reconstruction compatibility. Internal use only.
Example
>>> # Standard initialization with 5 components >>> binner = GaussianMixtureBinning(n_components=5, random_state=42) >>> >>> # Dynamic component count based on data size >>> binner = GaussianMixtureBinning(n_components='sqrt', random_state=123) >>> >>> # Use configuration defaults >>> binner = GaussianMixtureBinning() >>> >>> # Custom configuration with clipping >>> binner = GaussianMixtureBinning( ... n_components=8, ... random_state=42, ... clip=True, ... preserve_dataframe=True ... )
Note
Parameter validation occurs during initialization
Configuration defaults are applied for None parameters
The random_state parameter ensures reproducible results across runs
n_components can use dynamic expressions for adaptive bin counts
Reconstruction parameters should not be provided during normal usage
- classmethod __init_subclass__(**kwargs)
Set the
set_{method}_requestmethods.This uses PEP-487 [1] to set the
set_{method}_requestmethods. It looks for the information available in the set default values which are set using__metadata_request__*class attributes, or inferred from method signatures.The
__metadata_request__*class attributes are used when a method does not explicitly accept a metadata through its arguments or if the developer would like to specify a request value for those metadata which are different from the defaultNone.References
- static check_data_quality(data: ndarray[Any, Any], name: str = 'data') None
Check data quality and issue warnings if needed.
- fit(X: Any, y: Any | None = None, **fit_params: Any) GeneralBinningBase
Fit the binning transformer with comprehensive orchestration.
This method orchestrates the complete fitting process, handling parameter validation, input preprocessing, column separation, and routing to the appropriate fitting strategy (joint vs independent).
- Parameters:
X – Input data to fit the binning transformer on. Can be: - pandas.DataFrame: Column names are preserved - polars.DataFrame: Column names are preserved - numpy.ndarray: Numeric column indices are used - array-like: Converted to numpy array
y – Target values for supervised binning methods. Ignored by unsupervised methods. Can be array-like or None.
**fit_params – Additional fitting parameters passed to the specific binning algorithm implementation. Common parameters include: - guidance_data: Alternative guidance data (conflicts with fit_jointly=True)
- Returns:
The fitted binning transformer instance.
- Return type:
self
- Raises:
ValueError – If parameter validation fails, inputs are invalid, or conflicting parameters are provided (e.g., fit_jointly=True with guidance_data).
BinningError – If the binning algorithm fails to fit the data.
RuntimeError – If an unexpected error occurs during fitting.
Example
>>> from binlearn import EqualWidthBinning >>> import pandas as pd >>> X = pd.DataFrame({'feature1': [1, 2, 3, 4, 5], 'feature2': [10, 20, 30, 40, 50]}) >>> binner = EqualWidthBinning(n_bins=3) >>> binner.fit(X) EqualWidthBinning(...)
Note
The method automatically handles column separation when guidance_columns is specified, routing guidance columns separately from binning columns. The fitting strategy (joint vs independent) is determined by the fit_jointly parameter.
- fit_transform(X, y=None, **fit_params)
Fit to data, then transform it.
Fits transformer to X and y with optional parameters fit_params and returns a transformed version of X.
- Parameters:
X (array-like of shape (n_samples, n_features)) – Input samples.
y (array-like of shape (n_samples,) or (n_samples, n_outputs), default=None) – Target values (None for unsupervised transformations).
**fit_params (dict) – Additional fit parameters.
- Returns:
X_new – Transformed array.
- Return type:
ndarray array of shape (n_samples, n_features_new)
- get_input_columns() list[Any] | None
Get input columns for data preparation.
This method should be overridden by derived classes to provide appropriate column information without exposing binning-specific concepts.
- Returns:
Column information or None if not available
- get_metadata_routing()
Get metadata routing of this object.
Please check User Guide on how the routing mechanism works.
- Returns:
routing – A
MetadataRequestencapsulating routing information.- Return type:
MetadataRequest
- get_params(deep: bool = True) dict[str, Any]
Get parameters for this estimator, including fitted parameters.
This method extends sklearn’s standard get_params to include fitted parameters when the estimator is fitted, enabling complete object reconstruction through the get_params/set_params interface. This is essential for pipeline persistence and model serialization.
- Parameters:
deep – If True, returns parameters for sub-estimators (not applicable here but maintained for sklearn compatibility).
- Returns:
- Return type:
Dictionary of parameter names mapped to their values, including
Example
>>> binner = EqualWidthBinning(n_bins=5) >>> params = binner.get_params() >>> print(params) {'n_bins': 5, 'clip': None, ..., 'class_': 'EqualWidthBinning', 'module_': '...'} >>> >>> binner.fit(X) >>> fitted_params = binner.get_params() >>> # Now includes: {'bin_edges': {...}, 'bin_representatives': {...}, ...}
Note
Automatically extracts constructor parameters from __init__ signature
Includes fitted parameters only when estimator is fitted
Adds class metadata for reconstruction workflows
Excludes internal sklearn attributes like n_features_in_
class_ and module_ parameters are handled specially during set_params
- inverse_transform(X: Any) Any
Inverse transform from bin indices back to representative values.
Converts discrete bin indices back to their representative values, effectively reversing the binning transformation. This is useful for interpreting results or reconstructing approximate original values.
- Parameters:
X – Input data containing bin indices to inverse transform. Should contain only binning columns (no guidance columns). Can be: - pandas.DataFrame: Column names should match binning columns - polars.DataFrame: Column names should match binning columns - numpy.ndarray: Must have same number of binning columns - array-like: Converted to numpy array
- Returns:
Inverse transformed data where bin indices are replaced with their representative values (typically bin centers). Output format matches the preserve_dataframe setting.
- Raises:
RuntimeError – If the transformer has not been fitted yet.
ValueError – If input data has wrong number of columns or invalid format.
BinningError – If inverse transformation fails.
Example
>>> # After fitting and transforming >>> X_binned = [[0, 1], [1, 0], [2, 2]] # Bin indices >>> X_reconstructed = binner.inverse_transform(X_binned) >>> print(X_reconstructed) [[0.5, 1.5], [1.5, 0.5], [2.5, 2.5]] # Representative values
Note
For guided binning (when guidance_columns is specified), the input should only contain the binning columns, not the guidance columns. The number of input columns must match the number of binning columns.
- set_output(*, transform=None)
Set output container.
See Introducing the set_output API for an example on how to use the API.
- Parameters:
transform ({"default", "pandas", "polars"}, default=None) –
Configure output of transform and fit_transform.
”default”: Default output format of a transformer
”pandas”: DataFrame output
”polars”: Polars output
None: Transform configuration is unchanged
Added in version 1.4: “polars” option was added.
- Returns:
self – Estimator instance.
- Return type:
estimator instance
- set_params(**params: Any) SklearnIntegrationBase
Set the parameters of this estimator.
This method supports reconstruction workflows by handling fitted parameters that come from get_params() output (without underscores) and setting them as fitted attributes (with underscores).
- Parameters:
**params – Parameters to set. Can include: - Regular constructor parameters (n_bins, clip, etc.) - Fitted parameters from get_params (bin_edges, bin_representatives) - Class metadata (ignored during reconstruction)
- Returns:
Returns the instance itself.
- Return type:
self
- transform(X: Any) Any
Transform input data using fitted binning parameters.
Applies the fitted binning transformation to new data, converting continuous values to discrete bin indices or representatives. Handles column separation when guidance columns are present.
- Parameters:
X – Input data to transform. Must have the same structure as the data used during fitting (same number of columns). Can be: - pandas.DataFrame: Column names should match training data - polars.DataFrame: Column names should match training data - numpy.ndarray: Must have same number of columns as training - array-like: Converted to numpy array
- Returns:
Transformed data where continuous values are replaced with bin indices or representative values. The output format depends on: - preserve_dataframe setting: DataFrame vs array format - binning method: indices vs representatives - guidance_columns: only binning columns are transformed
- Raises:
RuntimeError – If the transformer has not been fitted yet.
ValueError – If the input data has incompatible structure or format.
BinningError – If transformation fails due to data issues.
Example
>>> # After fitting >>> X_new = pd.DataFrame({'feature1': [1.5, 2.5], 'feature2': [15, 25]}) >>> X_binned = binner.transform(X_new) >>> print(X_binned) [[0, 0], [1, 1]] # Bin indices
Note
When guidance_columns is specified, only the binning columns are transformed. Guidance columns are filtered out from the output. The method preserves the original data format when preserve_dataframe=True.
- static validate_array_like(data: Any, name: str = 'data', allow_none: bool = False) ndarray[Any, Any] | None
Validate and convert array-like input to numpy array.
This method provides robust validation and conversion of various input formats to numpy arrays, with comprehensive error handling and helpful suggestions for common issues.
- Parameters:
data – Input data to validate and convert. Can be: - numpy.ndarray: Used directly - pandas.DataFrame/Series: Converted to numpy array - polars.DataFrame: Converted to numpy array - list, tuple: Converted to numpy array - None: Allowed only if allow_none=True
name – Name of the data parameter for error messages. Used to provide context in error messages (e.g., “X”, “y”, “guidance_data”).
allow_none – Whether to allow None as a valid input. If True, None is returned unchanged; if False, None raises InvalidDataError.
- Returns:
Validated numpy array, or None if data is None and allow_none=True. The returned array maintains the same data content but is guaranteed to be a numpy array.
- Raises:
InvalidDataError – If validation fails: - data is None when allow_none=False - data cannot be converted to numpy array - Conversion process encounters errors
Example
>>> # Valid inputs >>> arr = ValidationMixin.validate_array_like([1, 2, 3], "X") >>> print(type(arr)) <class 'numpy.ndarray'> >>> >>> # Allow None >>> result = ValidationMixin.validate_array_like(None, "y", allow_none=True) >>> print(result) None >>> >>> # Invalid input >>> ValidationMixin.validate_array_like(None, "X", allow_none=False) InvalidDataError: X cannot be None
Note
This method focuses on format validation and conversion. Content validation (like checking for NaN values) should be done separately using other validation methods.
Overview
GaussianMixtureBinning creates bins based on Gaussian Mixture Model (GMM) clustering of each feature.
The bin edges are determined by finding the decision boundaries between adjacent mixture components, which
naturally groups similar values together based on probabilistic clustering.
This approach is particularly useful when:
Your data has natural Gaussian-like clusters
You want bins that adapt to the probabilistic structure of the data distribution
You need clustering that captures overlapping distributions
You want to model uncertainty in cluster assignments
Key Features
Probabilistic Clustering: Uses Gaussian mixture models for sophisticated clustering
Decision Boundaries: Creates bin edges at optimal decision boundaries between components
Overlap Handling: Naturally handles overlapping distributions
Reproducible Results: Supports random state for consistent clustering
Sklearn Compatibility: Full transformer interface with fit/transform methods
DataFrame Support: Preserves pandas/polars column names and structure
Basic Usage
import numpy as np
import pandas as pd
from binlearn.methods import GaussianMixtureBinning
# Create sample data with natural clusters
np.random.seed(42)
cluster1 = np.random.normal(10, 2, 300)
cluster2 = np.random.normal(25, 3, 200)
cluster3 = np.random.normal(40, 1.5, 100)
data = np.concatenate([cluster1, cluster2, cluster3])
# Apply Gaussian mixture binning
binner = GaussianMixtureBinning(n_components=3, random_state=42)
data_binned = binner.fit_transform(data.reshape(-1, 1))
print(f"Bin edges: {binner.bin_edges_[0]}")
print(f"Original data shape: {data.shape}")
print(f"Binned data shape: {data_binned.shape}")
DataFrame Example
# DataFrame usage with multiple features
df = pd.DataFrame({
'feature1': np.concatenate([
np.random.normal(10, 2, 200),
np.random.normal(30, 3, 200)
]),
'feature2': np.concatenate([
np.random.normal(5, 1, 200),
np.random.normal(15, 2, 200)
])
})
binner = GaussianMixtureBinning(
n_components=2,
random_state=42,
preserve_dataframe=True
)
df_binned = binner.fit_transform(df)
print(f"Bin edges for feature1: {binner.bin_edges_['feature1']}")
print(f"Bin edges for feature2: {binner.bin_edges_['feature2']}")
Advanced Configuration
# Advanced configuration with GMM parameters
binner = GaussianMixtureBinning(
n_components=4,
covariance_type='full', # Full covariance matrices
max_iter=200, # Maximum EM iterations
random_state=42,
tol=1e-3, # Convergence tolerance
clip=True # Clip out-of-range values
)
data_binned = binner.fit_transform(data)
Scikit-learn Pipeline Integration
from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
# Create a pipeline with Gaussian mixture binning
pipeline = Pipeline([
('binning', GaussianMixtureBinning(n_components=3, random_state=42)),
('classifier', RandomForestClassifier(random_state=42))
])
# Use in ML workflow
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
pipeline.fit(X_train, y_train)
accuracy = pipeline.score(X_test, y_test)
Parameter Guide
- n_components (int, default=5)
Number of mixture components (bins) to create. Higher values create more granular bins.
- covariance_type (str, default=’full’)
Type of covariance parameters: * ‘full’: Each component has its own general covariance matrix * ‘tied’: All components share the same general covariance matrix * ‘diag’: Each component has its own diagonal covariance matrix * ‘spherical’: Each component has its own single variance
- random_state (int, optional)
Random seed for reproducible clustering results.
- max_iter (int, default=100)
Maximum number of EM algorithm iterations.
- tol (float, default=1e-3)
Tolerance for convergence of the EM algorithm.
See Also
KMeansBinning- K-means clustering-based binningDBSCANBinning- Density-based clustering binningEqualFrequencyBinning- Quantile-based binningTreeBinning- Decision tree-based supervised binning