ValueError: The least populated class in y has only 1 member (stratify)
A class in your labels has fewer examples than a stratified split needs. Count the classes first — a 1-member class is usually a label typo, not a real category.
Updated
The error
ValueError: The least populated class in y has only 1 member, which is too few. The minimum number of groups for any class cannot be less than 2.
Cross-validation raises the sibling:
UserWarning: The least populated class in y has only 3 members, which is less than n_splits=5.
What it means
You asked for a stratified split — one that keeps class proportions equal in train and test. To put a class on both sides, the class needs at least 2 examples. One class has only 1. For k-fold cross-validation, every class needs at least n_splits examples, one per fold.
Why it happens
Look at the class counts before blaming the splitter:
print(y.value_counts())churned 4890 active 5093 churned 1
A class with 1 member is very often a typo or formatting slip — "churned " with a trailing space, "Active" versus "active", an ID that leaked into the label column. Genuine rare classes also happen: a disease with 3 cases, a product bought once.
How to fix it
1. Fix label noise first. If the rare class is a typo, normalise:
y = y.str.strip().str.lower()This usually deletes the phantom class and the error with it.
2. Merge genuinely rare classes into a meaningful bucket.
counts = y.value_counts()
rare = counts[counts < 10].index
y = y.replace(dict.fromkeys(rare, "other"))Do this only when "other" makes sense for your question.
3. Drop classes too rare to learn from — and say so in your write-up.
keep = y.isin(counts[counts >= 10].index)
X, y = X[keep], y[keep]A model cannot learn a class from 2 examples anyway.
4. For cross-validation, reduce the fold count.
cross_val_score(model, X, y, cv=3) # smallest class has 3 members5. Drop stratify only as a last resort. Without it, a rare class can land entirely in the test set — or entirely outside it — and your metrics become a lottery. Prefer fixes 1-4.
How to prevent it
Print y.value_counts() as the first act of any classification project. It surfaces typos, class imbalance and impossible classes in one line, before they become errors deeper in the pipeline. Re-check after every join or filter that touches the label column.
Related errors
- Found input variables with inconsistent numbers of samples — the other train_test_split classic
- ValueError: Unknown label type: 'continuous'
- Classification metrics can't handle a mix