diff --git a/sklearn/datasets/_samples_generator.py b/sklearn/datasets/_samples_generator.py index 9a972ba031bd3..a3495b358354f 100644 --- a/sklearn/datasets/_samples_generator.py +++ b/sklearn/datasets/_samples_generator.py @@ -672,6 +672,15 @@ def make_regression( return X, y +@validate_params( + { + "n_samples": [Interval(Integral, 0, None, closed="left"), tuple], + "shuffle": ["boolean"], + "noise": [Interval(Real, 0, None, closed="left"), None], + "random_state": ["random_state"], + "factor": [Interval(Real, 0, 1, closed="left")], + } +) def make_circles( n_samples=100, *, shuffle=True, noise=None, random_state=None, factor=0.8 ): @@ -706,7 +715,7 @@ def make_circles( See :term:`Glossary `. factor : float, default=.8 - Scale factor between inner and outer circle in the range `(0, 1)`. + Scale factor between inner and outer circle in the range `[0, 1)`. Returns ------- @@ -716,20 +725,13 @@ def make_circles( y : ndarray of shape (n_samples,) The integer labels (0 or 1) for class membership of each sample. """ - - if factor >= 1 or factor < 0: - raise ValueError("'factor' has to be between 0 and 1.") - if isinstance(n_samples, numbers.Integral): n_samples_out = n_samples // 2 n_samples_in = n_samples - n_samples_out - else: - try: - n_samples_out, n_samples_in = n_samples - except ValueError as e: - raise ValueError( - "`n_samples` can be either an int or a two-element tuple." - ) from e + else: # n_samples is a tuple + if len(n_samples) != 2: + raise ValueError("When a tuple, n_samples must have exactly two elements.") + n_samples_out, n_samples_in = n_samples generator = check_random_state(random_state) # so as not to have the first point = last point, we set endpoint=False diff --git a/sklearn/datasets/tests/test_samples_generator.py b/sklearn/datasets/tests/test_samples_generator.py index 09c245667c0a3..13df2bc796a55 100644 --- a/sklearn/datasets/tests/test_samples_generator.py +++ b/sklearn/datasets/tests/test_samples_generator.py @@ -688,11 +688,6 @@ def test_make_circles(): 2, ), "Samples not correctly distributed across circles." - with pytest.raises(ValueError): - make_circles(factor=-0.01) - with pytest.raises(ValueError): - make_circles(factor=1.0) - def test_make_circles_unbalanced(): X, y = make_circles(n_samples=(2, 8)) @@ -704,12 +699,6 @@ def test_make_circles_unbalanced(): with pytest.raises( ValueError, - match=r"`n_samples` can be either an int " r"or a two-element tuple.", - ): - make_circles(n_samples=[1, 2, 3]) - - with pytest.raises( - ValueError, - match=r"`n_samples` can be either an int " r"or a two-element tuple.", + match="When a tuple, n_samples must have exactly two elements.", ): make_circles(n_samples=(10,)) diff --git a/sklearn/tests/test_public_functions.py b/sklearn/tests/test_public_functions.py index 31aeb37c5e536..c89ce2481bd61 100644 --- a/sklearn/tests/test_public_functions.py +++ b/sklearn/tests/test_public_functions.py @@ -111,6 +111,7 @@ def _check_function_param_validation( "sklearn.datasets.fetch_olivetti_faces", "sklearn.datasets.load_svmlight_file", "sklearn.datasets.load_svmlight_files", + "sklearn.datasets.make_circles", "sklearn.datasets.make_classification", "sklearn.datasets.make_friedman1", "sklearn.datasets.make_sparse_coded_signal",