class imbalance
pandas
data preprocessing
machine learning
data augmentation

Duplicating training examples to handle class imbalance in a pandas data frame

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

Duplicating minority-class examples is one of the simplest ways to handle class imbalance before training a model. It is not always the best method, but it is a strong baseline because it is easy to implement, easy to explain, and quick to compare against alternatives such as class weights or synthetic oversampling.

Check the Imbalance First

Before duplicating anything, inspect the class distribution so you know what problem you are solving.

python
1import pandas as pd
2
3counts = df["label"].value_counts()
4print(counts)
5print(counts / counts.sum())

If one class is rare, a classifier may learn to predict the majority class most of the time and still achieve deceptively high accuracy. That is why imbalance-aware metrics matter more than raw accuracy in these problems.

Oversample Only the Training Split

The most important rule is to split the data before duplicating rows. If you oversample first and then split, copies of the same minority example can leak into both train and test sets, which makes evaluation overly optimistic.

python
1from sklearn.model_selection import train_test_split
2
3X = df.drop(columns=["label"])
4y = df["label"]
5
6X_train, X_test, y_train, y_test = train_test_split(
7    X,
8    y,
9    test_size=0.2,
10    random_state=42,
11    stratify=y
12)
13
14train_df = pd.concat([X_train, y_train], axis=1)

That split preserves the original label distribution in the test set so you can evaluate the model under realistic conditions.

Duplicate the Minority Class with Replacement

Once you have the training split, you can duplicate minority rows until the classes are balanced.

python
1import pandas as pd
2from sklearn.utils import resample
3
4majority = train_df[train_df["label"] == 0]
5minority = train_df[train_df["label"] == 1]
6
7minority_upsampled = resample(
8    minority,
9    replace=True,
10    n_samples=len(majority),
11    random_state=42
12)
13
14balanced_train_df = pd.concat([majority, minority_upsampled], ignore_index=True)
15balanced_train_df = balanced_train_df.sample(frac=1.0, random_state=42).reset_index(drop=True)
16
17print(balanced_train_df["label"].value_counts())

This is simple random oversampling. The minority class is represented more often during training, which can improve recall and make the learner pay more attention to that class.

Train and Evaluate with the Right Metrics

After oversampling, train on the balanced training frame and evaluate on the untouched test set.

python
1from sklearn.ensemble import RandomForestClassifier
2from sklearn.metrics import classification_report
3
4X_train_bal = balanced_train_df.drop(columns=["label"])
5y_train_bal = balanced_train_df["label"]
6
7model = RandomForestClassifier(random_state=42)
8model.fit(X_train_bal, y_train_bal)
9
10predictions = model.predict(X_test)
11print(classification_report(y_test, predictions))

Pay attention to precision, recall, and F1 score for the minority class. That gives a much better picture than overall accuracy.

Know the Tradeoffs of Duplication

Random duplication is easy, but it can also make the model memorize rare examples instead of learning a broader pattern, especially when the minority class is extremely small.

That does not mean the method is useless. It just means you should treat it as a baseline and compare it against other options:

  • 'class_weight="balanced" in supported models'
  • synthetic methods such as SMOTE
  • collecting more minority-class data if possible

If duplication improves recall significantly without unacceptable precision loss, it may already be good enough for the problem at hand.

Compare Against Class Weights

Some models support class weighting directly, which can avoid literal row duplication.

python
1from sklearn.linear_model import LogisticRegression
2
3weighted_model = LogisticRegression(
4    class_weight="balanced",
5    max_iter=1000
6)
7
8weighted_model.fit(X_train, y_train)
9print(weighted_model.score(X_test, y_test))

For linear models in particular, class weighting is often a strong competitor to oversampling. It is worth measuring both instead of assuming one is always better.

Common Pitfalls

The biggest mistake is oversampling before the train-test split. That leaks duplicated samples into evaluation and makes the results look better than they really are.

Another mistake is measuring success only with accuracy. In imbalanced problems, accuracy often tells you almost nothing about minority-class behavior.

Developers also sometimes oversample a tiny minority class until it dominates the training set. That can create heavy overfitting and unstable calibration.

Finally, remember to shuffle the balanced training frame after concatenation. If all majority rows come first and all duplicated minority rows come last, some training pipelines can behave oddly.

Summary

  • Duplicate minority examples only after splitting the data.
  • Use resample(..., replace=True) for a simple oversampling baseline.
  • Train on the balanced training set and evaluate on the untouched test set.
  • Focus on recall, precision, and F1 instead of accuracy alone.
  • Compare duplication with class weights and synthetic oversampling methods.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.