Subamostragem aleatória e ClusterCentroids
Os alunos farão a subamostragem da classe majoritária aleatoriamente e com ClusterCentroids, comparando a perda de informação e o desempenho resultante do modelo.
Subamostragem aleatória e ClusterCentroids é uma aula grátis de Machine Learning Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Machine Learning Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Machine Learning Academy inclui 4 aulas no total.
Partes desta aula ainda não foram traduzidas e aparecem em inglês.
Undersampling: Reducing the Majority Class
While oversampling grows the minority class, undersampling shrinks the majority class to balance the dataset. The key advantage: training is faster because there is less data overall. The key risk: you discard real majority-class information, potentially causing the model to make more false positives. Undersampling is most useful when the majority class is so large that oversampling would make training prohibitively slow.
Random Undersampling: Delete Majority Examples at Random
RandomUnderSampler randomly selects and removes majority-class samples until the desired ratio is achieved. It is the fastest undersampling method but throws away potentially useful information. With small datasets, random undersampling can make the model significantly worse by discarding majority samples near the decision boundary.
from imblearn.under_sampling import RandomUnderSampler
from sklearn.datasets import make_classification
import numpy as np
X, y = make_classification(n_samples=1000, weights=[0.95, 0.05],
n_features=10, random_state=42)
print('Before undersampling:', np.bincount(y))
rus = RandomUnderSampler(sampling_strategy=1.0, random_state=42)
X_res, y_res = rus.fit_resample(X, y)
print('After undersampling:', np.bincount(y_res))
print('New total samples:', len(y_res))Controlling the Sampling Strategy
The sampling_strategy parameter controls the final ratio of minority to majority. 1.0 makes them equal; 0.5 keeps 2:1 majority advantage. For very large datasets you might set 0.1 to create a 10:1 ratio — still better than the original 100:1 while keeping training fast. Choose based on the business cost of false positives vs false negatives.
from imblearn.under_sampling import RandomUnderSampler
from sklearn.datasets import make_classification
import numpy as np
X, y = make_classification(n_samples=10000, weights=[0.99, 0.01], random_state=42)
print('Original:', np.bincount(y))
for ratio in [1.0, 0.5, 0.2]:
rus = RandomUnderSampler(sampling_strategy=ratio, random_state=0)
_, y_r = rus.fit_resample(X, y)
counts = np.bincount(y_r)
print(f'ratio={ratio}: {counts} ({counts[1]/counts[0]:.2f} min:maj)')Cluster Centroids: Intelligent Undersampling
ClusterCentroids applies K-Means clustering to the majority class, replacing each cluster with its centroid. Instead of keeping random majority samples, it retains a compressed, representative set. This preserves the overall structure of the majority class better than random deletion, but is slower and requires tuning the number of clusters (which equals the target majority count after resampling).
from imblearn.under_sampling import ClusterCentroids
from sklearn.datasets import make_classification
import numpy as np
X, y = make_classification(n_samples=1000, weights=[0.9, 0.1],
n_features=5, random_state=42)
print('Before:', np.bincount(y))
cc = ClusterCentroids(sampling_strategy=1.0, random_state=42)
X_cc, y_cc = cc.fit_resample(X, y)
print('After ClusterCentroids:', np.bincount(y_cc))
print('Note: synthetic centroids replace real majority samples')Comparing Undersampling Methods
Let us benchmark random undersampling vs cluster centroids vs no resampling on the same imbalanced dataset, using F1-score on the minority class as the evaluation metric.
from imblearn.under_sampling import RandomUnderSampler, ClusterCentroids
from imblearn.pipeline import Pipeline as ImbPipeline
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import f1_score
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
import numpy as np
X, y = make_classification(n_samples=1000, weights=[0.95, 0.05], random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=42)
sc = StandardScaler()
X_tr = sc.fit_transform(X_train)
X_te = sc.transform(X_test)
for name, sampler in [('None', None),
('RUS', RandomUnderSampler(random_state=0)),
('ClusterCentroids', ClusterCentroids(random_state=0))]:
if sampler:
Xr, yr = sampler.fit_resample(X_tr, y_train)
else:
Xr, yr = X_tr, y_train
lr = LogisticRegression().fit(Xr, yr)
f1 = f1_score(y_test, lr.predict(X_te))
print(f'{name:20s}: F1={f1:.4f} n_train={len(yr)}')Information Loss in Undersampling
The critical downside of undersampling is information loss. When 95 out of every 100 majority-class samples are discarded, the model sees a training distribution very different from reality. This can inflate false-positive rates in production. For this reason, undersampling is often combined with oversampling (e.g., using SMOTEENN or SMOTETomek) to balance the dataset while minimising information loss.
Combining Oversampling and Undersampling
SMOTETomek combines SMOTE (oversample minority) with Tomek Links removal (clean ambiguous boundary majority samples). The result balances both classes and removes borderline majority samples that confuse the classifier. This combined approach often outperforms either oversampling or undersampling alone.
from imblearn.combine import SMOTETomek
from sklearn.datasets import make_classification
import numpy as np
X, y = make_classification(n_samples=1000, weights=[0.95, 0.05], random_state=42)
print('Before:', np.bincount(y))
st = SMOTETomek(random_state=42)
X_res, y_res = st.fit_resample(X, y)
print('After SMOTETomek:', np.bincount(y_res))Near Miss: Informed Undersampling by Distance
NearMiss selects majority-class samples based on their distance to minority samples — choosing either the closest (NearMiss-1) or the farthest (NearMiss-3). Unlike random undersampling, NearMiss keeps majority samples that are most relevant for defining the decision boundary. NearMiss-3 keeps majority samples farthest from all minority samples, creating a cleaner boundary region.
from imblearn.under_sampling import NearMiss
from sklearn.datasets import make_classification
import numpy as np
X, y = make_classification(n_samples=1000, weights=[0.9, 0.1], random_state=42)
print('Before:', np.bincount(y))
for version in [1, 2, 3]:
nm = NearMiss(version=version)
_, y_nm = nm.fit_resample(X, y)
print(f'NearMiss-{version}:', np.bincount(y_nm))Undersampling Inside an imblearn Pipeline
Like oversampling, undersampling must happen inside a pipeline to prevent leakage during cross-validation. Use imblearn.pipeline.Pipeline with the undersampler as a step before the classifier. The sampler's fit_resample is called on each training fold, and test folds are never modified.
from imblearn.pipeline import Pipeline as ImbPipeline
from imblearn.under_sampling import RandomUnderSampler
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
from sklearn.datasets import make_classification
import numpy as np
X, y = make_classification(n_samples=1000, weights=[0.95, 0.05], random_state=42)
pipe = ImbPipeline([
('sc', StandardScaler()),
('rus', RandomUnderSampler(random_state=42)),
('lr', LogisticRegression())
])
scores = cross_val_score(pipe, X, y, cv=5, scoring='f1')
print(f'CV F1 (RUS): {np.mean(scores):.4f} +/- {np.std(scores):.4f}')When to Choose Undersampling Over Oversampling
Prefer undersampling when: the majority class is enormous (millions of samples), training time is a bottleneck, or computational resources are constrained. Prefer oversampling (SMOTE) when: the minority class is very small (fewer than a few hundred samples), discarding majority data would make the training set too small, or the minority class has complex, non-convex structure that SMOTE can fill in. In practice, try both and compare on validation metrics.
Evaluating After Undersampling
After resampling, always evaluate on the original imbalanced test set — never on a resampled test set. Resampling the test data would give an unrealistic view of production performance. The goal is to improve the model's behaviour on the true data distribution, not to optimise for an artificial balanced distribution.
from sklearn.metrics import classification_report
from imblearn.under_sampling import RandomUnderSampler
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
X, y = make_classification(n_samples=1000, weights=[0.95, 0.05], random_state=42)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, stratify=y, random_state=42)
sc = StandardScaler()
X_train_s = sc.fit_transform(X_train)
X_test_s = sc.transform(X_test)
rus = RandomUnderSampler(random_state=0)
X_r, y_r = rus.fit_resample(X_train_s, y_train)
lr = LogisticRegression().fit(X_r, y_r)
# Evaluate on ORIGINAL imbalanced test set
print(classification_report(y_test, lr.predict(X_test_s)))Quick Check
Test your understanding of undersampling and Cluster Centroids from this lesson.
Lesson Recap
In this lesson you learned: RandomUnderSampler randomly deletes majority samples — fast but risks losing important boundary information, ClusterCentroids replaces majority clusters with their centroids to preserve the class distribution more faithfully, and always evaluate on the original imbalanced test set to measure real-world model behaviour. Next up we explore class weighting and threshold moving as alternatives to resampling.
Perguntas Frequentes
A aula “Subamostragem aleatória e ClusterCentroids” é grátis?
Sim — o texto completo de “Subamostragem aleatória e ClusterCentroids” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Machine Learning Academy, atualize para CoddyKit PRO. O curso de Machine Learning Academy inclui 4 aulas no total.
O que vou aprender em “Subamostragem aleatória e ClusterCentroids”?
Os alunos farão a subamostragem da classe majoritária aleatoriamente e com ClusterCentroids, comparando a perda de informação e o desempenho resultante do modelo. Você pratica Machine Learning Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Machine Learning Academy?
Nenhuma experiência prévia é necessária. Machine Learning Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Subamostragem aleatória e ClusterCentroids”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Machine Learning Academy?
Sim. Cada aula de Machine Learning Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Detecção de desequilíbrio: distribuição de classes e armadilhas da linha de base
- Sobreamostragem aleatória e SMOTE
- Subamostragem aleatória e ClusterCentroids
- Pesos das classes e ajuste do limiar