Skip to content

Conversation

bdpedigo
Copy link

Reference Issues/PRs

What does this implement/fix? Explain your changes.

Any other comments?

Comment on lines 29 to 31
Different combinations of initialization, GMM,
and cluster numbers are used and the clustering
with the best selection criterion (BIC or AIC) is chosen.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggest making this match LassoLarsIC a bit closer, eg "Such criteria are useful to select the value of the regularization parameter by making a trade-off between the goodness of fit and the complexity of the model." could basically replace "regularization parameter" with "gaussian mixture parameters"

n_init : int, optional (default = 1)
If ``n_init`` is larger than 1, additional
``n_init``-1 runs of :class:`sklearn.mixture.GaussianMixture`
initialized with k-means will be performed
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not necessarily initialized with k-means, right?

initialized with k-means will be performed
for all covariance parameters in ``covariance_type``.

init_params : {‘kmeans’ (default), ‘k-means++’, ‘random’, ‘random_from_data’}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps worth explaining the options, mainly i dont know what random_from_data is from this description

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, is kmeans ++ not the default? if not, why not? i think it is in sklearn if i remember correctly

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, not sure, apparently kmeans is the default in GaussianMixture


Attributes
----------
best_criterion_ : float
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lasso lars IC calls this "criterion_"

covariance_type_ : str
Covariance type for the model with the best bic/aic.

best_model_ : :class:`sklearn.mixture.GaussianMixture`
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in lassolarsIC, there is no "sub-object" with the best model; rather the whole class just operates as if it is that model. does that make sense? while i cant speak for them, my guess is this is closer to what they'd be expecting

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I add the attributes like weights_, means_ from GaussianMixture into GaussianMixtureIC, but I found that I still need to save the best model (I call best_estimator_ in the newest version) in order to all predict. Did I understand you correctly?

best_model_ : :class:`sklearn.mixture.GaussianMixture`
Object with the best bic/aic.

labels_ : array-like, shape (n_samples,)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a property of GaussianMixture, recommend not storing

self.criterion = criterion
self.n_jobs = n_jobs

def _check_multi_comp_inputs(self, input, name, default):
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i usually make any methods that dont access self into functions

name="min_components",
target_type=int,
)
check_scalar(
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

min value could be "min_components"?

else:
criterion_value = model.aic(X)

# change the precision of "criterion_value" based on sample size
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you explain this?

)
best_criter = [result.criterion for result in results]

if sum(best_criter == np.min(best_criter)) == 1:
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this all seems fine but just a suggestion - https://numpy.org/doc/stable/reference/generated/numpy.argmin.html
docs imply that for ties, argmin gives the first. so in other words if results are sorted in order of complexity, just using argmin would do what you want. (can even leave a comment to this effect, if you go this route).

note that i think having the results sorted by complexity anyway is probably desireable?




class _CollectResults:
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is effectively a dictionary - recommend just using one, or a named tuple? i am just anti classes that only store data and dont have any methods, but that is just my style :)

Comment on lines 306 to 323
param_grid = dict(
covariance_type=covariance_type,
n_components=range(self.min_components, self.max_components + 1),
)
param_grid = list(ParameterGrid(param_grid))

seeds = random_state.randint(np.iinfo(np.int32).max, size=len(param_grid))

if parse_version(joblib.__version__) < parse_version("0.12"):
parallel_kwargs = {"backend": "threading"}
else:
parallel_kwargs = {"prefer": "threads"}

results = Parallel(n_jobs=self.n_jobs, verbose=self.verbose, **parallel_kwargs)(
delayed(self._fit_cluster)(X, gm_params, seed)
for gm_params, seed in zip(param_grid, seeds)
)
best_criter = [result.criterion for result in results]
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just use GridSearchCV as in their example? https://scikit-learn.org/stable/auto_examples/mixture/plot_gmm_selection.html#sphx-glr-auto-examples-mixture-plot-gmm-selection-py

it would abstract away some of the stuff you have to do to make parallel work, for instance

@github-actions
Copy link

github-actions bot commented Jun 21, 2023

❌ Linting issues

This PR is introducing linting issues. Here's a summary of the issues. Note that you can avoid having linting issues by enabling pre-commit hooks. Instructions to enable them can be found here.

You can see the details of the linting issues under the lint job here


ruff check

ruff detected issues. Please run ruff check --fix --output-format=full locally, fix the remaining issues, and push the changes. Here you can see the detected issues. Note that the installed ruff version is ruff=0.11.7.


sklearn/mixture/_gaussian_mixture_ic.py:1:1: CPY001 Missing copyright notice at top of file
sklearn/mixture/_gaussian_mixture_ic.py:10:1: TID252 Prefer absolute imports over relative imports
   |
 8 | import numpy as np
 9 |
10 | from ..base import BaseEstimator, ClusterMixin
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TID252
11 | from ..model_selection import GridSearchCV
12 | from ..utils._param_validation import (
   |
   = help: Replace relative imports with absolute imports

sklearn/mixture/_gaussian_mixture_ic.py:10:1: TID252 Prefer absolute imports over relative imports
   |
 8 | import numpy as np
 9 |
10 | from ..base import BaseEstimator, ClusterMixin
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TID252
11 | from ..model_selection import GridSearchCV
12 | from ..utils._param_validation import (
   |
   = help: Replace relative imports with absolute imports

sklearn/mixture/_gaussian_mixture_ic.py:11:1: TID252 Prefer absolute imports over relative imports
   |
10 | from ..base import BaseEstimator, ClusterMixin
11 | from ..model_selection import GridSearchCV
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TID252
12 | from ..utils._param_validation import (
13 |     Integral,
   |
   = help: Replace relative imports with absolute imports

sklearn/mixture/_gaussian_mixture_ic.py:12:1: TID252 Prefer absolute imports over relative imports
   |
10 |   from ..base import BaseEstimator, ClusterMixin
11 |   from ..model_selection import GridSearchCV
12 | / from ..utils._param_validation import (
13 | |     Integral,
14 | |     Interval,
15 | |     InvalidParameterError,
16 | |     StrOptions,
17 | | )
   | |_^ TID252
18 |   from ..utils.validation import check_is_fitted
19 |   from . import GaussianMixture
   |
   = help: Replace relative imports with absolute imports

sklearn/mixture/_gaussian_mixture_ic.py:12:1: TID252 Prefer absolute imports over relative imports
   |
10 |   from ..base import BaseEstimator, ClusterMixin
11 |   from ..model_selection import GridSearchCV
12 | / from ..utils._param_validation import (
13 | |     Integral,
14 | |     Interval,
15 | |     InvalidParameterError,
16 | |     StrOptions,
17 | | )
   | |_^ TID252
18 |   from ..utils.validation import check_is_fitted
19 |   from . import GaussianMixture
   |
   = help: Replace relative imports with absolute imports

sklearn/mixture/_gaussian_mixture_ic.py:12:1: TID252 Prefer absolute imports over relative imports
   |
10 |   from ..base import BaseEstimator, ClusterMixin
11 |   from ..model_selection import GridSearchCV
12 | / from ..utils._param_validation import (
13 | |     Integral,
14 | |     Interval,
15 | |     InvalidParameterError,
16 | |     StrOptions,
17 | | )
   | |_^ TID252
18 |   from ..utils.validation import check_is_fitted
19 |   from . import GaussianMixture
   |
   = help: Replace relative imports with absolute imports

sklearn/mixture/_gaussian_mixture_ic.py:12:1: TID252 Prefer absolute imports over relative imports
   |
10 |   from ..base import BaseEstimator, ClusterMixin
11 |   from ..model_selection import GridSearchCV
12 | / from ..utils._param_validation import (
13 | |     Integral,
14 | |     Interval,
15 | |     InvalidParameterError,
16 | |     StrOptions,
17 | | )
   | |_^ TID252
18 |   from ..utils.validation import check_is_fitted
19 |   from . import GaussianMixture
   |
   = help: Replace relative imports with absolute imports

sklearn/mixture/_gaussian_mixture_ic.py:18:1: TID252 Prefer absolute imports over relative imports
   |
16 |     StrOptions,
17 | )
18 | from ..utils.validation import check_is_fitted
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TID252
19 | from . import GaussianMixture
   |
   = help: Replace relative imports with absolute imports

sklearn/mixture/_gaussian_mixture_ic.py:19:1: TID252 Prefer absolute imports over relative imports
   |
17 | )
18 | from ..utils.validation import check_is_fitted
19 | from . import GaussianMixture
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TID252
   |
   = help: Replace relative imports with absolute imports

Found 10 errors.
No fixes available (9 hidden fixes can be enabled with the `--unsafe-fixes` option).

ruff format

ruff detected issues. Please run ruff format locally and push the changes. Here you can see the detected issues. Note that the installed ruff version is ruff=0.11.7.


--- sklearn/mixture/_gaussian_mixture_ic.py
+++ sklearn/mixture/_gaussian_mixture_ic.py
@@ -4,7 +4,6 @@
 #          Thomas Athey <tathey1@jhmi.edu>
 #          Benjamin Pedigo <bpedigo@jhu.edu>
 
-
 import numpy as np
 
 from ..base import BaseEstimator, ClusterMixin

1 file would be reformatted, 927 files already formatted

Generated for commit: a08d428. Link to the linter CI: here

StefanieSenger and others added 30 commits August 28, 2025 18:24
Co-authored-by: Loïc Estève <loic.esteve@ymail.com>
…learn#32019)

Co-authored-by: ArturoAmorQ <arturo.amor-quiroz@polytechnique.edu>
Co-authored-by: Thomas J. Fan <thomasjpfan@gmail.com>
Co-authored-by: Virgil Chan <virchan.math@gmail.com>
… solver (scikit-learn#32039)

Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org>
…earn#31898)

Co-authored-by: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com>
…cikit-learn#31951)

Co-authored-by: Loïc Estève <loic.esteve@ymail.com>
Co-authored-by: Adrin Jalali <adrin.jalali@gmail.com>
…ely Skewed Data (scikit-learn#29307)

Co-authored-by: rnmourao <robertonunesmourao@yahoo.com.br>
…2035)

Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai>
…display (scikit-learn#31564)

Co-authored-by: Guillaume Lemaitre <guillaume@probabl.ai>
Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.