จัดการข้อมูลไม่สมดุล (Imbalanced Data) ด้วย SMOTE และ imbalanced-learn ใน Python 2026

คู่มือ SMOTE และ imbalanced-learn 0.13 บน Python 2026 พร้อมโค้ดตัวอย่างครบวงจร ตั้งแต่ SMOTE พื้นฐาน, ADASYN, BorderlineSMOTE, SMOTENC ไปจนถึงการรวมกับ scikit-learn Pipeline, การประเมินผลอย่างถูกวิธี และข้อผิดพลาดที่พบบ่อย

SMOTE ใน Python 2026: คู่มือ imbalanced-learn

อัปเดตล่าสุด: 19 กรกฎาคม 2026

SMOTE (Synthetic Minority Over-sampling Technique) คือเทคนิคสร้างตัวอย่างสังเคราะห์ของคลาสส่วนน้อยด้วยการสุ่มจุดใหม่ระหว่างจุดที่มีอยู่กับเพื่อนบ้านที่ใกล้ที่สุดในพื้นที่ฟีเจอร์ ซึ่งช่วยลดปัญหาโมเดลจำแนกประเภทเอนเอียงไปทางคลาสส่วนใหญ่ ในไลบรารี imbalanced-learn เวอร์ชัน 0.13 (มิถุนายน 2026) SMOTE ทำงานร่วมกับ scikit-learn 1.5+ ได้อย่างสมบูรณ์ ในบทความนี้ผมจะพาคุณดูทั้งวิธีเรียกใช้ SMOTE, ตัวแปรที่มีประโยชน์อย่าง ADASYN และ BorderlineSMOTE, การรวมเข้ากับ Pipeline, และข้อผิดพลาดที่วิศวกรข้อมูลส่วนใหญ่มองข้าม

  • SMOTE สร้างตัวอย่างสังเคราะห์ด้วยการ interpolate ระหว่างจุดคลาสส่วนน้อยกับเพื่อนบ้าน k-NN ไม่ใช่แค่การทำสำเนาซ้ำแบบ RandomOverSampler
  • ต้องใช้ SMOTE เฉพาะบนชุดฝึก (train set) หลังการแบ่งข้อมูล ห้ามใช้กับชุดทดสอบเด็ดขาด เพราะจะทำให้ metric สูงเกินจริง (data leakage)
  • imbalanced-learn มี Pipeline คลาสของตัวเอง (imblearn.pipeline.Pipeline) เพราะ Pipeline ของ scikit-learn ไม่รองรับขั้นตอน resampling
  • SMOTENC จัดการฟีเจอร์ประเภทแบบ categorical ได้โดยตรง ส่วน SMOTEN สำหรับข้อมูล categorical ล้วน
  • สำหรับข้อมูลที่ไม่สมดุลไม่มาก (น้อยกว่า 1:10) การใช้ class_weight='balanced' ในโมเดลมักได้ผลดีกว่าและรวดเร็วกว่า SMOTE
  • วัดผลด้วย PR-AUC (Average Precision) และ F1 ของคลาสส่วนน้อย ไม่ใช่ accuracy ซึ่งหลอกลวงในข้อมูลไม่สมดุล

SMOTE คืออะไร และทำงานอย่างไร?

เอาล่ะ ก่อนจะไปดูโค้ด มาปูพื้นให้ชัดก่อน SMOTE ย่อมาจาก Synthetic Minority Over-sampling Technique ถูกนำเสนอครั้งแรกโดย Chawla และคณะในปี 2002 อัลกอริทึมทำงานตามขั้นตอนดังนี้: (1) เลือกจุดหนึ่งจากคลาสส่วนน้อยแบบสุ่ม (2) หาเพื่อนบ้านที่ใกล้ที่สุด k จุด (ค่าดีฟอลต์ k=5) ในคลาสเดียวกัน (3) สุ่มเลือกหนึ่งในเพื่อนบ้านนั้น (4) สร้างจุดสังเคราะห์ใหม่บนเส้นตรงระหว่างสองจุดโดยใช้ค่าสุ่ม α ∈ [0, 1] เป็นตัวถ่วงน้ำหนัก คือ x_new = x + α · (x_neighbor − x)

ในการทำงานจริงกับปัญหาการตรวจจับการทุจริตของธนาคารที่ผมช่วยสร้างระบบให้ (อัตราส่วนคลาสประมาณ 1:850) ผมพบว่าความเข้าใจกลไกนี้สำคัญมาก เพราะ SMOTE ไม่ใช่ของวิเศษ มันสร้างจุดในบริเวณที่มีคลาสส่วนน้อยอยู่แล้วเท่านั้น หากคลาสส่วนน้อยของคุณเป็น outlier กระจัดกระจาย SMOTE จะสร้าง noise มากกว่าสัญญาณ ดูรายละเอียดใน SMOTE original paper (Chawla et al., 2002) และ เอกสาร imbalanced-learn ทางการ ที่อธิบายพารามิเตอร์ครบถ้วน

ข้อแตกต่างสำคัญระหว่าง SMOTE กับ RandomOverSampler คือ RandomOverSampler ทำสำเนาจุดที่มีอยู่ซ้ำ ๆ (over-fit เสี่ยงสูง) ส่วน SMOTE จะสร้างจุดใหม่ที่ไม่เคยมีอยู่ ทำให้ decision boundary ของโมเดลนุ่มนวลกว่า แต่ก็แลกกับความเสี่ยงในการสร้างจุดในบริเวณที่ทับซ้อนกับคลาสส่วนใหญ่

การติดตั้งและตั้งค่า imbalanced-learn 0.13

เวอร์ชันล่าสุด (0.13.x, มิถุนายน 2026) รองรับ Python 3.10+ และ scikit-learn 1.5+ ติดตั้งได้ผ่าน pip หรือ conda:

# ผ่าน pip
pip install imbalanced-learn==0.13.0

# ผ่าน conda (channel: conda-forge)
conda install -c conda-forge imbalanced-learn=0.13.0

# ตรวจสอบเวอร์ชัน
python -c "import imblearn; print(imblearn.__version__)"
# 0.13.0

ถ้าคุณใช้ scikit-learn เวอร์ชันเก่า (< 1.3) ควรอัปเกรดก่อน เพราะ imbalanced-learn 0.13 ใช้ estimator tags แบบใหม่ที่ต้องการ sklearn 1.3+ และหลาย metadata routing feature (เช่น set_config(enable_metadata_routing="enabled")) จะทำงานได้ก็ต่อเมื่อคู่กับ sklearn 1.5+ เท่านั้น

import numpy as np
import pandas as pd
from sklearn.datasets import make_classification
from imblearn.over_sampling import SMOTE
from collections import Counter

# สร้างชุดข้อมูลไม่สมดุลตัวอย่าง (อัตราส่วนคลาส 1:19)
X, y = make_classification(
    n_samples=10000,
    n_features=20,
    n_informative=10,
    n_redundant=5,
    n_classes=2,
    weights=[0.95, 0.05],
    random_state=42,
)
print("การกระจายคลาสเดิม:", Counter(y))
# การกระจายคลาสเดิม: Counter({0: 9500, 1: 500})

โค้ดข้างต้นจำลองสถานการณ์ที่พบบ่อยในระบบตรวจจับความผิดปกติ ตัวเลข weights=[0.95, 0.05] คือสัดส่วนที่ตั้งใจให้เกิดความไม่สมดุล 95:5 ซึ่งเป็นระดับที่ SMOTE เริ่มมีผลชัดเจน

ใช้งาน SMOTE พื้นฐานพร้อมโค้ดตัวอย่าง

ก่อนใช้ SMOTE ต้องแบ่งข้อมูล train/test ก่อนเสมอ กฎเหล็กคือ SMOTE ใช้กับชุดฝึกเท่านั้น ห้ามใช้กับชุดทดสอบเด็ดขาด มิฉะนั้นจะเกิด data leakage และตัวชี้วัดจะสวยเกินจริง (ผมเคยเจอเคสที่ทีมส่งโมเดลขึ้นโปรดักชันโดยทำ SMOTE ก่อน split ผลคือ ROC-AUC 0.98 ตอนทดสอบ แต่บนข้อมูลจริงเหลือ 0.72)

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, average_precision_score

# 1) แบ่งข้อมูลด้วย stratify เพื่อรักษาสัดส่วนคลาสในทั้งสองชุด
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, stratify=y, random_state=42
)
print("ก่อน SMOTE (train):", Counter(y_train))

# 2) ใช้ SMOTE บนชุดฝึกเท่านั้น
smote = SMOTE(
    sampling_strategy="auto",   # oversample คลาสส่วนน้อยให้เท่าคลาสส่วนใหญ่
    k_neighbors=5,
    random_state=42,
)
X_train_res, y_train_res = smote.fit_resample(X_train, y_train)
print("หลัง SMOTE (train):", Counter(y_train_res))

# 3) ฝึกโมเดลบนข้อมูลที่ resample แล้ว
model = LogisticRegression(max_iter=1000, random_state=42)
model.fit(X_train_res, y_train_res)

# 4) ประเมินบนชุดทดสอบเดิม (ไม่ถูก resample)
y_pred = model.predict(X_test)
y_proba = model.predict_proba(X_test)[:, 1]
print(classification_report(y_test, y_pred, digits=3))
print("PR-AUC:", round(average_precision_score(y_test, y_proba), 3))

พารามิเตอร์ที่สำคัญที่สุดคือ sampling_strategy ค่า "auto" จะ oversample คลาสส่วนน้อยให้เท่ากับคลาสส่วนใหญ่ แต่ในทางปฏิบัติมักไม่เหมาะที่สุด ส่วนตัวผมมักตั้งเป็นค่า float เช่น 0.5 ซึ่งหมายถึงต้องการอัตราส่วน 1:2 หลัง resample ตัวอย่าง: SMOTE(sampling_strategy=0.5) จะให้ผลที่นุ่มนวลกว่า และลดความเสี่ยงในการ over-generate จุดสังเคราะห์

SMOTE variants: ADASYN, BorderlineSMOTE, SMOTENC และ SMOTEN

SMOTE พื้นฐานอาจไม่เหมาะกับทุกสถานการณ์ imbalanced-learn จึงมี variant หลายตัวที่ควรรู้จัก:

ADASYN: Adaptive Synthetic Sampling

ADASYN คล้าย SMOTE แต่ให้ความสำคัญกับจุดที่ "ยาก" ก่อน โดยดูจากอัตราส่วนของคลาสส่วนใหญ่ในบริเวณเพื่อนบ้าน ยิ่งพื้นที่หนาแน่นด้วยคลาสส่วนใหญ่ ADASYN ก็จะสร้างจุดใหม่ที่บริเวณนั้นมากกว่า เหมาะกับปัญหาที่มี decision boundary ซับซ้อน

from imblearn.over_sampling import ADASYN

adasyn = ADASYN(sampling_strategy=0.5, n_neighbors=5, random_state=42)
X_res, y_res = adasyn.fit_resample(X_train, y_train)

BorderlineSMOTE: สร้างจุดใกล้ boundary

BorderlineSMOTE จะจำแนกจุดคลาสส่วนน้อยเป็น "safe", "danger", และ "noise" แล้วสร้างจุดสังเคราะห์เฉพาะจุดในกลุ่ม "danger" (จุดที่มีเพื่อนบ้านครึ่งหนึ่งเป็นคลาสส่วนใหญ่) ตัวเลือกนี้ทำงานดีกับ dataset ที่คลาสส่วนน้อยมีทั้งจุดที่ชัดเจนและจุดคลุมเครือ

from imblearn.over_sampling import BorderlineSMOTE

# kind="borderline-1" (ดีฟอลต์) หรือ "borderline-2"
bsm = BorderlineSMOTE(sampling_strategy=0.5, kind="borderline-1", random_state=42)
X_res, y_res = bsm.fit_resample(X_train, y_train)

SMOTENC และ SMOTEN สำหรับข้อมูล categorical

SMOTE ใช้กับฟีเจอร์เชิงตัวเลขเท่านั้น ถ้าข้อมูลของคุณมีฟีเจอร์ประเภทแบบ (categorical) ต้องใช้ SMOTENC (Nominal + Continuous) หรือ SMOTEN (Nominal only) ซึ่งเป็นเรื่องปกติมากในข้อมูลของแวร์เฮาส์การวิเคราะห์ (analytics warehouse) ที่มีทั้ง numeric metric และมิติ dimensional หากคุณต้องเตรียมข้อมูลก่อน อ่าน คู่มือจัดการ Missing Data ใน pandas 3.0 ก่อนน่าจะช่วยได้เยอะ

from imblearn.over_sampling import SMOTENC

# ระบุ index ของคอลัมน์ categorical
cat_features = [3, 5, 7]  # คอลัมน์ 3, 5, 7 เป็น categorical
smotenc = SMOTENC(
    categorical_features=cat_features,
    sampling_strategy=0.5,
    random_state=42,
)
X_res, y_res = smotenc.fit_resample(X_train_df, y_train)

ในเวอร์ชัน 0.13 SMOTENC รองรับการรับ boolean mask หรือชื่อคอลัมน์ (เมื่อ input เป็น DataFrame) แทน index ตัวเลขได้แล้ว ซึ่งช่วยลดข้อผิดพลาดในโปรเจกต์ที่คอลัมน์เปลี่ยนแปลงบ่อย

รวม SMOTE เข้ากับ scikit-learn Pipeline อย่างถูกวิธี

เหตุผลที่ Pipeline ของ scikit-learn ธรรมดารวม SMOTE ไม่ได้คือ SMOTE เป็น resampler ไม่ใช่ transformer มันเปลี่ยนทั้ง X และ y ในขณะที่ transformer ของ sklearn เปลี่ยนเฉพาะ X ทางแก้คือใช้ imblearn.pipeline.Pipeline ซึ่งมี API เหมือน sklearn ทุกประการแต่รองรับ resampler เพิ่มเติม หากคุณเคยอ่านบทความ คู่มือ scikit-learn Pipeline ฉบับสมบูรณ์ มาก่อน แนวคิดจะเหมือนเดิม เพียงเปลี่ยน import

from imblearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier

pipeline = Pipeline([
    ("scaler", StandardScaler()),
    ("smote", SMOTE(sampling_strategy=0.5, random_state=42)),
    ("clf", RandomForestClassifier(n_estimators=200, random_state=42)),
])

pipeline.fit(X_train, y_train)
y_pred = pipeline.predict(X_test)

จุดสำคัญ: SMOTE จะทำงานเฉพาะเมื่อเรียก fit เท่านั้น เมื่อเรียก predict หรือ transform ขั้นตอน SMOTE จะถูกข้ามอัตโนมัติ นี่คือพฤติกรรมที่ต้องการ เพราะเราไม่อยาก resample ข้อมูลทดสอบหรือข้อมูลโปรดักชัน

เมื่อจับคู่ Pipeline นี้กับ Cross-Validation, GridSearchCV จะ resample ในแต่ละ fold แยกกันโดยอัตโนมัติ ซึ่งเป็นวิธีที่ถูกต้อง ป้องกัน leakage อีกชั้น (ผมเคยเสียเวลาไปสองวันไล่แก้ metric ที่ดูดีเกินจริง สุดท้ายเจอว่าลืมย้ายจาก sklearn.pipeline ไป imblearn.pipeline นั่นเอง) หากต้องการเจาะลึกเรื่องการปรับพารามิเตอร์ ผมแนะนำอ่านต่อที่ คู่มือ Hyperparameter Tuning ด้วย GridSearchCV, RandomizedSearchCV และ Optuna

from sklearn.model_selection import GridSearchCV

param_grid = {
    "smote__sampling_strategy": [0.3, 0.5, 0.7, 1.0],
    "smote__k_neighbors": [3, 5, 7],
    "clf__n_estimators": [100, 200, 400],
}

grid = GridSearchCV(
    pipeline,
    param_grid,
    scoring="average_precision",  # PR-AUC เหมาะกับข้อมูลไม่สมดุล
    cv=5,
    n_jobs=-1,
)
grid.fit(X_train, y_train)
print("พารามิเตอร์ที่ดีที่สุด:", grid.best_params_)

SMOTE กับ class_weight: อันไหนดีกว่ากัน?

คำถามที่พบบ่อยที่สุดในทีมของผมคือควรใช้ SMOTE หรือแค่ตั้ง class_weight='balanced' ในโมเดล? คำตอบขึ้นอยู่กับ (1) ระดับความไม่สมดุล (2) ขนาดข้อมูล (3) ชนิดโมเดล ดูตารางเปรียบเทียบด้านล่าง

ประเด็นSMOTE / ADASYNclass_weight='balanced'
วิธีทำงานสร้างตัวอย่างสังเคราะห์เพิ่มในชุดฝึกเพิ่มน้ำหนัก loss ของคลาสส่วนน้อยขณะฝึก
เวลาฝึกช้า (dataset ใหญ่ขึ้น 2–20 เท่า)เร็ว (dataset เดิม)
ใช้ RAMสูง โดยเฉพาะเมื่อ oversample 1:1ต่ำ ไม่เพิ่มขนาดข้อมูล
ปรับ hyperparameterปรับได้มาก (k_neighbors, sampling_strategy, variant)ปรับได้น้อย (บาลานซ์ vs custom weights)
โมเดลที่รองรับทุกโมเดล (เพราะเปลี่ยนข้อมูล)เฉพาะโมเดลที่รองรับ (LogReg, SVM, RF, XGBoost บางเวอร์ชัน)
ข้อมูล categoricalต้องใช้ SMOTENC / SMOTENไม่มีข้อจำกัด
เหมาะกับไม่สมดุลปานกลาง (1:20 ถึง 1:100), มี pattern ชัดเจนไม่สมดุลไม่มาก (< 1:10), ข้อมูลใหญ่
ความเสี่ยงหลักสร้าง noise หากคลาสส่วนน้อยกระจัดกระจายโมเดลอาจไม่ปรับ decision boundary พอ

ในประสบการณ์ของผมกับ dataset การตรวจจับการทุจริตขนาด 40 ล้านแถว การใช้ class_weight='balanced' ใน XGBoost (ผ่านพารามิเตอร์ scale_pos_weight) ให้ผล PR-AUC สูงกว่า SMOTE อยู่เล็กน้อยและใช้เวลาฝึกน้อยกว่า 8 เท่า แต่ในโปรเจกต์ทางการแพทย์ที่มีข้อมูลเพียง 3,000 แถวและอัตราส่วน 1:50 การใช้ BorderlineSMOTE + LightGBM ให้ผลดีกว่าเห็นได้ชัด ดูรายละเอียดใน เอกสาร scikit-learn เรื่อง class_weight

การประเมินโมเดลข้อมูลไม่สมดุลที่ถูกต้อง

Accuracy เป็นตัวชี้วัดที่ห้ามใช้กับข้อมูลไม่สมดุลอย่างเด็ดขาด ในชุดข้อมูลที่คลาสบวกมีเพียง 1% โมเดลที่ทำนายเป็นคลาสลบเสมอจะได้ accuracy 99% ทันที ซึ่งไร้ความหมายในการนำไปใช้จริง

ตัวชี้วัดที่ควรใช้แทนคือ:

  • Precision-Recall AUC (Average Precision): ทนต่อความไม่สมดุลดีที่สุด สนใจเฉพาะประสิทธิภาพบนคลาสบวก
  • F1-score ของคลาสส่วนน้อย: สมดุลระหว่าง precision และ recall
  • ROC-AUC: ใช้ได้แต่มีข้อจำกัด เพราะไม่ไวต่อการเปลี่ยนแปลงในกลุ่ม false positive ที่มากกว่ามาก
  • Matthews Correlation Coefficient (MCC): ให้ตัวเลขเดียวที่คำนึงถึงทั้ง 4 ช่องของ confusion matrix
from sklearn.metrics import (
    average_precision_score,
    f1_score,
    roc_auc_score,
    matthews_corrcoef,
    precision_recall_curve,
)
import matplotlib.pyplot as plt

y_proba = pipeline.predict_proba(X_test)[:, 1]
y_pred = pipeline.predict(X_test)

print(f"PR-AUC:      {average_precision_score(y_test, y_proba):.3f}")
print(f"F1 (คลาส 1): {f1_score(y_test, y_pred):.3f}")
print(f"ROC-AUC:     {roc_auc_score(y_test, y_proba):.3f}")
print(f"MCC:         {matthews_corrcoef(y_test, y_pred):.3f}")

# วาดกราฟ Precision-Recall
precision, recall, _ = precision_recall_curve(y_test, y_proba)
plt.plot(recall, precision, label="SMOTE + RF")
plt.xlabel("Recall")
plt.ylabel("Precision")
plt.title("Precision-Recall Curve")
plt.legend()
plt.show()

อีกเรื่องที่สำคัญมากคือการปรับ threshold การจำแนก ค่าดีฟอลต์ 0.5 ไม่ใช่ค่าที่ดีเสมอไป ในบางกรณีการเลื่อน threshold ลงเป็น 0.2 อาจให้ recall สูงขึ้นในระดับที่ธุรกิจต้องการ โดยแลกกับ precision ที่ลดลง การตัดสินใจนี้ควรอิงกับต้นทุนของ false positive และ false negative ในบริบทจริง ไม่ใช่ตัวเลข F1 เพียงอย่างเดียว

ข้อผิดพลาดที่ควรหลีกเลี่ยงเมื่อใช้ SMOTE

จากประสบการณ์รีวิวโค้ด ML กว่าร้อยโปรเจกต์ในช่วง 9 ปีที่ผ่านมา นี่คือข้อผิดพลาดที่พบซ้ำที่สุด ซึ่งควรจะหลีกเลี่ยงตั้งแต่เริ่มโปรเจกต์:

  1. ทำ SMOTE ก่อนแบ่ง train/test: ทำให้เกิด leakage อย่างชัดเจน แก้โดยแบ่งข้อมูลก่อนเสมอ หรือใช้ imblearn.pipeline.Pipeline
  2. ใช้ SMOTE บน dataset ขนาดเล็กมาก (< 200 ตัวอย่างของคลาสส่วนน้อย) จุดสังเคราะห์จะซ้ำ pattern ของจุดต้นแบบเดิม ๆ ไม่เพิ่มความหลากหลาย
  3. ลืมทำ scaling ก่อน SMOTE เนื่องจาก SMOTE ใช้ระยะทาง Euclidean การไม่ scale ทำให้ฟีเจอร์ที่มี scale ใหญ่ครองการคำนวณเพื่อนบ้าน
  4. oversample ให้เป็น 1:1 เสมอ โมเดลอาจ over-fit จุดสังเคราะห์ ลองเริ่มที่ 1:3 หรือ 1:2 ก่อน
  5. ใช้ SMOTE กับ time-series data โดยตรง จุดสังเคราะห์จะละเมิดลำดับเวลา ต้องใช้เทคนิคเฉพาะเช่น time-aware oversampling หรือ TimeGAN
  6. ไม่ตรวจสอบ distribution ของจุดสังเคราะห์ ใช้ t-SNE หรือ UMAP วาดจุดใหม่เทียบกับจุดเดิม ถ้าจุดใหม่กระจายไปยังบริเวณคลาสส่วนใหญ่แสดงว่า SMOTE กำลังสร้าง noise

สำหรับการรับประกันคุณภาพข้อมูลก่อนเข้าไปยังกระบวนการ resampling ผมแนะนำให้ใช้ Pandera หรือ Great Expectations เพื่อ validate schema และ constraint ก่อน ไม่งั้น SMOTE อาจสร้างจุดสังเคราะห์บน missing value หรือ outlier ที่ควรถูกจัดการก่อน

คำถามที่พบบ่อย

SMOTE ปรับปรุงประสิทธิภาพโมเดลเสมอหรือไม่?

ไม่ SMOTE ช่วยได้เมื่อคลาสส่วนน้อยมี pattern ที่ชัดเจนและกระจุกตัว หากคลาสส่วนน้อยเป็น outlier กระจัดกระจาย SMOTE จะเพิ่ม noise และทำให้ประสิทธิภาพแย่ลง ในหลายกรณี class_weight='balanced' ให้ผลดีกว่าและเร็วกว่า ควรทดสอบทั้งสองวิธีก่อนตัดสินใจ

ควรใช้ SMOTE บนชุดทดสอบด้วยไหม?

ไม่ควรอย่างเด็ดขาด ใช้ SMOTE เฉพาะกับชุดฝึกเท่านั้น การใช้กับชุดทดสอบทำให้เกิด data leakage และ metric สูงเกินจริง ประสิทธิภาพในโปรดักชันจะแตกต่างจากที่วัดได้ทันที การใช้ imblearn.pipeline.Pipeline ร่วมกับ cross-validation จะป้องกันปัญหานี้อัตโนมัติ

SMOTE ใช้กับข้อมูล categorical ได้ไหม?

SMOTE พื้นฐานใช้ไม่ได้ ต้องใช้ SMOTENC สำหรับข้อมูลผสม (numeric + categorical) หรือ SMOTEN สำหรับ categorical ล้วน โดยระบุ index หรือชื่อของคอลัมน์ categorical ผ่านพารามิเตอร์ categorical_features ทั้งสอง variant จัดการการสร้างค่า categorical ให้ถูกต้องโดยไม่สร้างค่าเฉลี่ยที่ไม่มีความหมาย

SMOTE ทำงานกับ deep learning ได้ไหม?

ได้ แต่ในทางปฏิบัติ deep learning มีเทคนิคอื่นที่ดีกว่า เช่น focal loss, weighted BCE loss, หรือการปรับ batch sampling ให้บาลานซ์ SMOTE เหมาะกับ tabular data และโมเดล classic ML มากกว่า สำหรับข้อมูลภาพหรือข้อความ ควรใช้ data augmentation เฉพาะโดเมนแทน

ข้อเสียของ SMOTE คืออะไร?

ข้อเสียหลัก 3 ประการคือ (1) สามารถสร้างจุดในบริเวณที่ทับซ้อนกับคลาสส่วนใหญ่ ทำให้ decision boundary สับสน (2) เพิ่มขนาดข้อมูลอย่างมาก ทำให้ใช้ RAM และเวลาฝึกเพิ่ม (3) ไม่ทำงานกับข้อมูล time-series หรือข้อมูลที่มี dependency ระหว่างแถว จำเป็นต้องเลือก variant ที่เหมาะกับปัญหาและตรวจสอบผลด้วย visualization เสมอ

เกี่ยวกับผู้เขียน Marcus Holloway

Marcus is an analytics engineer with 9 years in the dbt and warehouse-modeling trenches. He spent three years at dbt Labs as a senior solutions architect helping enterprise customers (a large US bank, two telecom carriers) untangle 4000-model projects, and before that ran the analytics platform at HelloFresh's North America org where he rebuilt the supply-chain mart on Snowflake + dbt. His writing focuses on dbt project structure at scale, incremental model patterns that actually survive backfills, and the unglamorous work of column-level lineage and contract testing. He is a regular contributor to the dbt-utils package and co-maintains a small open-source linter for SQL style. Marcus lives in Berlin, holds a master's in statistics from UNC Chapel Hill, and roasts his own coffee badly.