xbe.at

Machine learning / Feature engineering and preprocessing

Data Augmentation Techniques in Machine Learning with Python

8 min read, 14 sections

Contents
  1. Data Augmentation in Machine Learning
  2. Image Rotation
  3. Image Flipping
  4. Color Jittering
  5. Random Cropping
  6. Gaussian Noise Addition
  7. Text Data Augmentation: Synonym Replacement
  8. Time Series Data Augmentation: Time Warping
  9. Audio Data Augmentation: Time Stretching
  10. Balancing Class Distribution
  11. Real-life Example: Plant Disease Detection
  12. Real-life Example: Hand Gesture Recognition
  13. Conclusion and Best Practices
  14. Additional Resources

Data Augmentation in Machine Learning

Data augmentation is a technique used to artificially increase the size and diversity of training datasets. It involves creating new, synthetic data points from existing ones through various transformations. This process helps improve model generalization, reduce overfitting, and enhance performance on unseen data.

import numpy as np
import matplotlib.pyplot as plt

# Original data
x = np.array([1, 2, 3, 4, 5])
y = np.array([2, 4, 5, 4, 5])

# Augmented data (adding noise)
x_aug = np.concatenate([x, x + np.random.normal(0, 0.1, len(x))])
y_aug = np.concatenate([y, y + np.random.normal(0, 0.1, len(y))])

plt.scatter(x, y, label='Original')
plt.scatter(x_aug[len(x):], y_aug[len(y):], label='Augmented')
plt.legend()
plt.title('Data Augmentation Example')
plt.show()

Image Rotation

One common data augmentation technique for images is rotation. By applying small rotations to existing images, we can create new, valid training samples. This helps the model become invariant to slight rotations in input data.

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

# Load an image
img = Image.open('sample_image.jpg')

# Rotate the image
rotated_img = img.rotate(30)

# Display original and rotated images
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
ax1.imshow(img)
ax1.set_title('Original Image')
ax2.imshow(rotated_img)
ax2.set_title('Rotated Image (30 degrees)')
plt.show()

Image Flipping

Horizontal flipping is another effective augmentation technique, especially useful for tasks where the orientation of objects doesn't matter. It doubles the dataset size and helps the model learn orientation-invariant features.

import cv2
import matplotlib.pyplot as plt

# Read an image
img = cv2.imread('sample_image.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# Flip the image horizontally
flipped_img = cv2.flip(img, 1)

# Display original and flipped images
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
ax1.imshow(img)
ax1.set_title('Original Image')
ax2.imshow(flipped_img)
ax2.set_title('Flipped Image')
plt.show()

Color Jittering

Color jittering involves randomly changing the brightness, contrast, saturation, and hue of images. This technique helps models become robust to variations in lighting conditions and color distributions.

import torch
import torchvision.transforms as transforms
from PIL import Image
import matplotlib.pyplot as plt

# Load an image
img = Image.open('sample_image.jpg')

# Define color jitter transformation
color_jitter = transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.1)

# Apply color jittering
jittered_img = color_jitter(img)

# Display original and jittered images
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
ax1.imshow(img)
ax1.set_title('Original Image')
ax2.imshow(jittered_img)
ax2.set_title('Color Jittered Image')
plt.show()

Random Cropping

Random cropping involves selecting random portions of the image for training. This technique helps the model focus on different parts of the image and become more robust to object positioning and partial occlusions.

import torchvision.transforms as transforms
from PIL import Image
import matplotlib.pyplot as plt

# Load an image
img = Image.open('sample_image.jpg')

# Define random crop transformation
random_crop = transforms.RandomCrop((200, 200))

# Apply random cropping
cropped_img = random_crop(img)

# Display original and cropped images
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
ax1.imshow(img)
ax1.set_title('Original Image')
ax2.imshow(cropped_img)
ax2.set_title('Randomly Cropped Image')
plt.show()

Gaussian Noise Addition

Adding Gaussian noise to images simulates real-world sensor noise and helps models become more robust to noisy inputs. This technique is particularly useful for improving model performance in low-light or high-ISO conditions.

import numpy as np
import cv2
import matplotlib.pyplot as plt

# Read an image
img = cv2.imread('sample_image.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# Add Gaussian noise
mean = 0
std = 25
noise = np.random.normal(mean, std, img.shape).astype(np.uint8)
noisy_img = cv2.add(img, noise)

# Display original and noisy images
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
ax1.imshow(img)
ax1.set_title('Original Image')
ax2.imshow(noisy_img)
ax2.set_title('Noisy Image')
plt.show()

Text Data Augmentation: Synonym Replacement

For text data, synonym replacement is a simple yet effective augmentation technique. It involves replacing words with their synonyms to create new, semantically similar sentences.

import nltk
from nltk.corpus import wordnet

nltk.download('wordnet')

def get_synonyms(word):
    synonyms = set()
    for syn in wordnet.synsets(word):
        for lemma in syn.lemmas():
            synonyms.add(lemma.name())
    return list(synonyms)

def augment_sentence(sentence, num_words_to_replace=2):
    words = sentence.split()
    for _ in range(num_words_to_replace):
        replace_idx = np.random.randint(0, len(words))
        synonyms = get_synonyms(words[replace_idx])
        if synonyms:
            words[replace_idx] = np.random.choice(synonyms)
    return ' '.join(words)

original_sentence = "The quick brown fox jumps over the lazy dog"
augmented_sentence = augment_sentence(original_sentence)

print(f"Original: {original_sentence}")
print(f"Augmented: {augmented_sentence}")

Time Series Data Augmentation: Time Warping

For time series data, time warping is a useful augmentation technique. It involves stretching or compressing segments of the time series to create new, plausible variations.

import numpy as np
import matplotlib.pyplot as plt

def time_warp(x, sigma=0.2, knot=4):
    from scipy.interpolate import CubicSpline
    orig_steps = np.arange(x.shape[1])
    random_warps = np.random.normal(loc=1.0, scale=sigma, size=(x.shape[0], knot+2, x.shape[2]))
    warp_steps = (np.ones((x.shape[2], 1)) * (np.linspace(0, x.shape[1]-1., num=knot+2))).T
    ret = np.zeros_like(x)
    for i, pat in enumerate(x):
        warper = np.array([CubicSpline(warp_steps[:, dim], random_warps[i, :, dim])(orig_steps) for dim in range(x.shape[2])]).T
        ret[i] = pat * warper
    return ret

# Generate sample time series data
t = np.linspace(0, 10, 100)
y = np.sin(t)

# Apply time warping
y_warped = time_warp(y.reshape(1, -1, 1)).squeeze()

# Plot original and warped time series
plt.figure(figsize=(10, 5))
plt.plot(t, y, label='Original')
plt.plot(t, y_warped, label='Time Warped')
plt.legend()
plt.title('Time Warping Augmentation')
plt.show()

Audio Data Augmentation: Time Stretching

For audio data, time stretching is a common augmentation technique. It involves changing the speed of the audio without affecting the pitch, creating new variations of the original sound.

import librosa
import librosa.display
import matplotlib.pyplot as plt

# Load audio file
y, sr = librosa.load('sample_audio.wav')

# Apply time stretching
y_stretched = librosa.effects.time_stretch(y, rate=0.8)

# Plot original and stretched audio waveforms
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8))
librosa.display.waveshow(y, sr=sr, ax=ax1)
ax1.set_title('Original Audio')
librosa.display.waveshow(y_stretched, sr=sr, ax=ax2)
ax2.set_title('Time Stretched Audio')
plt.tight_layout()
plt.show()

Balancing Class Distribution

Data augmentation can help balance class distributions in imbalanced datasets. By generating synthetic samples for underrepresented classes, we can improve model performance on minority classes.

from imblearn.over_sampling import SMOTE
from sklearn.datasets import make_classification
import matplotlib.pyplot as plt

# Generate imbalanced dataset
X, y = make_classification(n_samples=1000, n_classes=2, weights=[0.9, 0.1], n_features=2, n_redundant=0, random_state=42)

# Apply SMOTE
smote = SMOTE(random_state=42)
X_resampled, y_resampled = smote.fit_resample(X, y)

# Plot original and resampled data
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 5))
ax1.scatter(X[:, 0], X[:, 1], c=y, alpha=0.8)
ax1.set_title('Original Imbalanced Dataset')
ax2.scatter(X_resampled[:, 0], X_resampled[:, 1], c=y_resampled, alpha=0.8)
ax2.set_title('Balanced Dataset after SMOTE')
plt.show()

print(f"Original class distribution: {dict(zip(*np.unique(y, return_counts=True)))}")
print(f"Resampled class distribution: {dict(zip(*np.unique(y_resampled, return_counts=True)))}")

Real-life Example: Plant Disease Detection

In agriculture, data augmentation can significantly improve plant disease detection models. By applying various transformations to images of diseased and healthy plants, we can create a more robust dataset for training.

import albumentations as A
import cv2
import matplotlib.pyplot as plt

# Load a sample plant leaf image
image = cv2.imread('plant_leaf.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# Define augmentation pipeline
transform = A.Compose([
    A.RandomRotate90(),
    A.Flip(),
    A.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.2),
    A.GaussNoise(var_limit=(10.0, 50.0))
])

# Apply augmentations
augmented_image = transform(image=image)['image']

# Display original and augmented images
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))
ax1.imshow(image)
ax1.set_title('Original Plant Leaf Image')
ax2.imshow(augmented_image)
ax2.set_title('Augmented Plant Leaf Image')
plt.show()

Real-life Example: Hand Gesture Recognition

In human-computer interaction, data augmentation can enhance hand gesture recognition models. By applying transformations to hand gesture images, we can improve the model's ability to recognize gestures in various orientations and lighting conditions.

import imgaug.augmenters as iaa
import cv2
import matplotlib.pyplot as plt

# Load a sample hand gesture image
image = cv2.imread('hand_gesture.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# Define augmentation sequence
aug_seq = iaa.Sequential([
    iaa.Affine(rotate=(-20, 20)),
    iaa.AdditiveGaussianNoise(scale=(0, 0.05*255)),
    iaa.Multiply((0.8, 1.2)),
    iaa.GammaContrast((0.8, 1.2))
])

# Apply augmentations
augmented_images = [aug_seq(image=image) for _ in range(4)]

# Display original and augmented images
fig, axes = plt.subplots(2, 3, figsize=(15, 10))
axes[0, 0].imshow(image)
axes[0, 0].set_title('Original Hand Gesture')
for i, aug_image in enumerate(augmented_images, 1):
    row, col = divmod(i, 3)
    axes[row, col].imshow(aug_image)
    axes[row, col].set_title(f'Augmented Hand Gesture {i}')
plt.tight_layout()
plt.show()

Conclusion and Best Practices

Data augmentation is a powerful technique for improving model performance and generalization. Key takeaways include:

  1. Choose augmentation techniques relevant to your data type and problem domain.
  2. Ensure augmented data remains valid and realistic.
  3. Use a combination of different augmentation techniques for best results.
  4. Monitor model performance with and without augmentation to assess its impact.
  5. Be mindful of computational costs, especially for large datasets.

By following these best practices, you can effectively leverage data augmentation to enhance your machine learning models' capabilities and robustness.

Additional Resources

For further exploration of data augmentation techniques and their applications in machine learning, consider the following resources:

  1. "A survey on Image Data Augmentation for Deep Learning" by C. Shorten and T. M. Khoshgoftaar (2019) ArXiv link: https://arxiv.org/abs/1904.12433
  2. "Data Augmentation for Deep Learning" by J. Wen et al. (2020) ArXiv link: https://arxiv.org/abs/2009.14119
  3. "Time Series Data Augmentation for Deep Learning: A Survey" by Q. Wen et al. (2020) ArXiv link: https://arxiv.org/abs/2002.12478

These papers provide comprehensive overviews of various data augmentation techniques and their applications in different domains of machine learning.

More in Feature engineering and preprocessing

  1. Data Preprocessing Techniques in Machine Learning9 min

    StandardScaler transforms features by removing the mean and scaling to unit variance, resulting in a distribution with a mean of 0 and standard deviation of...

  2. Advanced Pandas Techniques for Machine Learning10 min

    Data manipulation is a crucial skill in machine learning and data science. This presentation covers advanced techniques using pandas and Python, focusing on...

  3. Data Version Control for Machine Learning with Python7 min

    Data Version Control (DVC) is a powerful tool for managing and versioning datasets and machine learning models. It helps data scientists and ML engineers...

  4. 8 Advanced Feature Engineering for Machine Learning9 min

    Polynomial features capture nonlinear relationships in data. They create new features by combining existing ones, raising them to powers, or multiplying them...

  5. Data Warehousing and Dimensional Modeling for Machine Learning Using Python5 min

    Introduction to Data Warehousing and Dimensional Modeling

  6. 5 Reasons for Feature Selection in Machine Learning14 min

    Feature selection significantly reduces computational complexity and training time by eliminating irrelevant or redundant features. This process becomes...