Skip to content

Sampling Strategies: SMOTE, ADASYN, Borderline-SMOTE, SMOTE-NC — The Art of Synthesizing Positive Samples

Generating synthetic positive samples for imbalanced data: random over/undersampling, SMOTE, ADASYN, Borderline-SMOTE, SMOTE-NC (numeric + categorical), SMOTE-Tomek hybrid; imblearn pipeline and common pitfalls.

Şükrü Yusuf KAYA
28 min read
Intermediate
Sampling Stratejileri: SMOTE, ADASYN, Borderline-SMOTE, SMOTE-NC — Sentetik Pozitif Üretmenin Sanatı
🧬 Yapay pozitif üretme
Imbalanced veride en doğal çözüm: 'pozitif örnekleri çoğalt'. Ama nasıl? Aynı örneği 100 kez kopyalamak overfit'e sokar. SMOTE (2002, Chawla et al.) bu sorunu zekice çözdü: pozitif örneklerin yakın komşuları arasında sentetik yeni örnekler üretti. Bu fikir 22 yıldır AD'nin standart araç kutusunda. Bu derste SMOTE ve 5 modern varyantını işleyeceğiz.

Önce Naif Yaklaşımlar#

1. Random Oversampling#

Pozitif örnekleri rastgele kopyala. Sınıflar dengelendiğinde dur.
from imblearn.over_sampling import RandomOverSampler ros = RandomOverSampler(random_state=42) X_res, y_res = ros.fit_resample(X, y)
Avantaj: Hızlı, basit. Dezavantaj: Aynı örnekleri tekrarlar → overfit riski yüksek. Karar sınırı kopyalanmış noktalara aşırı uyar.

2. Random Undersampling#

Negatif örnekleri rastgele azalt. Sınıflar dengelendiğinde dur.
from imblearn.under_sampling import RandomUnderSampler rus = RandomUnderSampler(random_state=42) X_res, y_res = rus.fit_resample(X, y)
Avantaj: Hızlı, hesaplama maliyeti düşük. Dezavantaj: Bilgi kaybı; sadece birkaç bin satıra düşersin. Büyük veri kümelerinde değerli bilgi atılır.
Pratik kural: Sadece prototype için kullan. Production için SMOTE ailesi.

SMOTE: Synthetic Minority Oversampling Technique#

Chawla, Bowyer, Hall, Kegelmeyer (2002). Bugün hâlâ en yaygın oversampling yöntemi.

Algoritma#

INPUT: pozitif örnekler P, k komşu sayısı (genelde 5), N (kaç kat çoğalt) FOR i = 1 to len(P): 1. p_i için k en yakın komşusunu bul (sadece pozitiflerden) 2. N tane sentetik örnek üret: a. Rastgele bir komşu p_j seç b. Rastgele alpha ∈ [0, 1] seç c. p_new = p_i + alpha * (p_j - p_i) 3. p_new'leri sentetik kümeye ekle

Sezgi#

İki gerçek pozitif örnek arasındaki çizgi üzerinde rastgele bir nokta yarat. Bu, "iki bilinen fraud arasında, benzeri bir fraud olabilir" varsayımı.

Görsel#

SMOTE — iki gerçek pozitif arasında sentetik nokta üretimi.
SMOTE algoritması: kırmızı = orijinal pozitif, yeşil = sentetik pozitif. Mavi = negatif sınıf.
python
from imblearn.over_sampling import SMOTE
from sklearn.datasets import make_classification
import numpy as np
 
# Sentetik imbalanced veri
X, y = make_classification(
n_samples=10000, n_features=20,
weights=[0.99, 0.01], # 1:100 imbalance
random_state=42
)
print(f"Önce: y=0: {(y==0).sum()}, y=1: {(y==1).sum()}")
 
# SMOTE
smote = SMOTE(k_neighbors=5, sampling_strategy='auto', random_state=42)
X_res, y_res = smote.fit_resample(X, y)
print(f"Sonra: y=0: {(y_res==0).sum()}, y=1: {(y_res==1).sum()}")
 
# sampling_strategy alternatifleri:
# 'auto' veya 'not majority' — pozitif sınıfı negatife eşitle (1:1)
# 'minority' — sadece pozitifi oversample et
# 0.5 — pozitif/negatif = 0.5 oranını hedefle
# {1: 1000} — pozitif sayısını 1000'e çıkar
SMOTE temel kullanım

SMOTE'un Tuzakları#

Tuzak 1: Outlier komşusunu sentetik kabul etmek#

Pozitif sınıfta bir outlier (yanlış etiket veya gerçek uç olay) varsa, SMOTE o outlier'ı komşu olarak kullanıp outlier yumağı üretir. Çözüm: SMOTE öncesi pozitif sınıfta outlier temizliği (örn. iForest ile).

Tuzak 2: Categorical feature'lar#

SMOTE Euclidean distance kullanır. Categorical (one-hot encoded) feature'lar için aritmetik ortalama anlamsız: "0.7 cinsiyet erkek" diye bir şey yok. Çözüm: SMOTE-NC veya SMOTE-N (aşağıda).

Tuzak 3: Yüksek-boyut#

20+ feature'lı veride k-nearest neighbor patlar (curse of dimensionality). SMOTE komşuları yanlış seçer. Çözüm: Önce PCA/UMAP ile boyut azalt, sonra SMOTE; veya doğrudan boyut-bağımsız varyantlar.

Tuzak 4: Test setine sızdırmak (en büyük tuzak)#

SMOTE sadece training set'e uygulanmalı. Test set'e SMOTE uygulamak veya SMOTE'u train/test split'ten önce koymak veri sızıntısıdır.
# YANLIŞ X_res, y_res = SMOTE().fit_resample(X, y) X_train, X_test, ... = train_test_split(X_res, y_res, ...) # DOĞRU X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, ...) X_train_res, y_train_res = SMOTE().fit_resample(X_train, y_train) # test seti hiç değiştirilmedi
🔧 SMOTE Pipeline'ı
imblearn'in
Pipeline
ı scikit-learn-uyumlu — SMOTE sadece training fold'una uygulanır, cross-validation güvenli.
from imblearn.pipeline import Pipeline
(sklearn değil!). Bu detay her şirket fraud ekibinde unutuluyor.

SMOTE Varyantları#

22 yıl içinde 30+ SMOTE varyantı geliştirildi. Pratikte 5 tanesi yaygın:

1. Borderline-SMOTE (Han et al., 2005)#

Sadece karar sınırına yakın (decision boundary) pozitif örnekleri oversample et. Çünkü iç bölgedeki pozitifler zaten doğru sınıflandırılıyor.
from imblearn.over_sampling import BorderlineSMOTE bsmote = BorderlineSMOTE(kind='borderline-1', random_state=42) X_res, y_res = bsmote.fit_resample(X, y)
Avantaj: Karar sınırını netleştirir, daha az gürültü. Dezavantaj: Borderline tespiti yanlış olursa SMOTE ile aynı sonuç.

2. ADASYN (He et al., 2008)#

Adaptive Synthetic Sampling. Her pozitif örnek için ne kadar sentetik üretileceğini, o örneğin yanlış sınıflandırılma zorluğuna göre ayarla. Daha "zor" örneklerden daha fazla sentetik üret.
from imblearn.over_sampling import ADASYN adasyn = ADASYN(n_neighbors=5, random_state=42) X_res, y_res = adasyn.fit_resample(X, y)
Avantaj: Karar sınırını zorlayan örneklere odaklanır. Dezavantaj: Outlier'ları "zor" zannedip onlardan üretebilir.

3. SMOTE-NC (Numeric + Categorical)#

Categorical feature'ları olduğu gibi (mode-based) kopyala, numeric'leri SMOTE.
from imblearn.over_sampling import SMOTENC # categorical_features: indeksleri smnc = SMOTENC(categorical_features=[1, 5, 9], k_neighbors=5, random_state=42) X_res, y_res = smnc.fit_resample(X, y)
Avantaj: Karışık veriye uygun. Banking fraud ekiplerinde standart. Dezavantaj: Kategorik için mode-based seçim çeşitliliği azaltabilir.

4. SMOTE-N (Tamamen Categorical)#

Sadece kategorik feature'lar varsa.

5. SMOTE-Tomek (Hibrit)#

SMOTE + Tomek links (yakın yanlış-sınıflı çiftleri temizleme). Önce SMOTE, sonra noisy sınır temizliği.
from imblearn.combine import SMOTETomek st = SMOTETomek(random_state=42) X_res, y_res = st.fit_resample(X, y)
Avantaj: Hem oversampling hem cleanup.

Varyant Karşılaştırma Tablosu#

YöntemHızYapıKarar sınırı odağıCategorical
Random OversamplingÇok hızlıKopyaYok (overfit)OK
SMOTEHızlıAritmetik karışımYokHayır
Borderline-SMOTEOrtaSınır-merkezliVarHayır
ADASYNOrtaAdaptif yoğunlukVarHayır
SMOTE-NCOrtaKarışıkYokEvet
SMOTE-TomekYavaşHibritVar (post-cleanup)Hayır

Pratik Seçim Akışı#

[Categorical feature var mı?] ↓ ├── Evet → SMOTE-NC │ └── Hayır → [Karar sınırı odağı gerekli mi?] ↓ ├── Evet → Borderline-SMOTE veya ADASYN │ └── Hayır (baseline) → SMOTE ↓ └── Gürültü temizliği lazımsa → SMOTE-Tomek

Undersampling Aileleri (Bonus)#

Bazen veri çok büyükse (10M+ satır), oversampling pratik değil. O zaman akıllı undersampling:
Bir pozitif ile bir negatif çiftinin birbirine en yakın komşu olduğu çiftleri kaldır. Sınırı temizler.

2. Edited Nearest Neighbors (ENN)#

Her örneğin k komşusunun çoğunluğu farklı sınıftaysa, o örneği kaldır. Gürültüyü süpürür.

3. NearMiss#

Pozitiflere en yakın negatifleri tut, uzak olanları at. Üç versiyonu var (NearMiss-1, 2, 3).

4. Random Undersampling Boosted (RUSBoost)#

Boosting + undersampling hibrit — production'da bazı şirketler XGBoost'a alternatif olarak kullanır.
python
from imblearn.under_sampling import TomekLinks, EditedNearestNeighbours, NearMiss
 
# Tomek Links — sınır temizleme
tomek = TomekLinks()
X_res, y_res = tomek.fit_resample(X, y)
 
# ENN — gürültü temizleme
enn = EditedNearestNeighbours(n_neighbors=3)
X_res, y_res = enn.fit_resample(X, y)
 
# NearMiss — pozitif-odaklı seçim
nm = NearMiss(version=1, n_neighbors=3)
X_res, y_res = nm.fit_resample(X, y)
Undersampling örnekleri

Production-Ready Pipeline#

Tüm bunları birleştiren standart pipeline:
python
from imblearn.pipeline import Pipeline
from imblearn.over_sampling import SMOTE
from imblearn.under_sampling import TomekLinks
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score, StratifiedKFold
 
# Imbalance-aware pipeline
pipeline = Pipeline([
('scaler', StandardScaler()), # 1. ölçeklendir
('smote', SMOTE(k_neighbors=5, random_state=42)), # 2. oversample
('tomek', TomekLinks()), # 3. sınır temizliği
('clf', RandomForestClassifier(n_estimators=200, random_state=42)),
])
 
# Stratified K-fold — imbalanced için şart
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
 
# PR-AUC ile değerlendirme (accuracy değil!)
scores = cross_val_score(pipeline, X, y,
cv=skf, scoring='average_precision', n_jobs=-1)
print(f"PR-AUC: {scores.mean():.3f} ± {scores.std():.3f}")
Imbalance-aware tam pipeline
📊 SMOTE'un gerçek etkisi
Recent benchmark (2023, Brown vd.): 50+ imbalanced dataset üzerinde SMOTE PR-AUC'u baseline'a göre ortalama %8 artırıyor; en güçlü etkisi 1:100-1:1000 oranlarında. 1:10.000+ ekstrem imbalanced'da SMOTE etkisini kaybediyor — orada cost-sensitive learning (Modül 3.3) veya semi-supervised (Modül 1.3) daha güçlü.

SMOTE Anti-Pattern'leri#

Production'da görülen 5 yaygın hata:

1. Test set'e SMOTE uygulamak#

Yukarıda söylendi — veri sızıntısı.

2. Cross-validation'dan önce SMOTE#

# YANLIŞ X_res, y_res = SMOTE().fit_resample(X, y) scores = cross_val_score(clf, X_res, y_res, cv=5) # Her fold sentetik dolu — bias var
Doğru yaklaşım: imblearn.Pipeline ile sarmala (yukarıdaki örnek).

3. Categorical-aware olmadan tabular fraud verisi#

Çoğu finansal fraud verisi 1/3 categorical. Saf SMOTE bu feature'ları saçma değerlere taşır. SMOTE-NC kullan.

4. SMOTE + sonra StandardScaler#

Sırasız uygula → SMOTE öncesi scaler fit'i sızıntı yaratır.

5. "Sınıflar dengelendi, demek ki başardık" yanılgısı#

1:1 dengelemek tek başına yetmez. Gerçek imbalanced'da PR-AUC ölçmen şart. Train set'i dengelemek, test set'inde kalibrasyonu bozar (model beklenenden çok sık pozitif tahmin eder). Modül 4'te kalibrasyon konusunu işleyeceğiz.
👉 Bir sonraki ders
Ders 3.3 — Cost-Sensitive Learning + Focal Loss. Veriyi değiştirmenin alternatifi: loss function'ı değiştirmek. Class weight, sample weight, asymmetric loss, focal loss (Lin et al., 2017). Anomaly Transformer ve modern AD modellerinin çoğunda görürsün.

Frequently Asked Questions

Yarar ama klasik ML kadar dramatik değil. Neural net'lerin focal loss / weighted loss'u doğal olarak destekler, bu yüzden sampling alternatif yerine ek yaklaşım. Imbalanced classification'da modern NN pratik: focal loss + hafif oversampling.

Yorumlar & Soru-Cevap

(0)
Yorum yazmak için giriş yap.
Yorumlar yükleniyor...

Related Content