การสุ่มลดตัวอย่างและ ClusterCentroids
ผู้เรียนจะลดตัวอย่างของคลาสส่วนใหญ่แบบสุ่มและด้วย ClusterCentroids พร้อมเปรียบเทียบการสูญเสียข้อมูลกับประสิทธิภาพของแบบจำลองที่ได้
การสุ่มลดตัวอย่างและ ClusterCentroids เป็นบทเรียน Machine Learning Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Machine Learning Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Machine Learning Academy มีบทเรียนทั้งหมด 4 บทเรียน
การลดตัวอย่าง: ลดคลาสส่วนใหญ่
ขณะที่การเพิ่มตัวอย่างขยายคลาสส่วนน้อย การลดตัวอย่าง จะลดขนาดคลาสส่วนใหญ่เพื่อปรับสมดุลชุดข้อมูล ข้อได้เปรียบสำคัญคือการฝึกทำได้เร็วขึ้น เพราะมีข้อมูลโดยรวมน้อยลง ความเสี่ยงสำคัญคือคุณทิ้งข้อมูลจริงของคลาสส่วนใหญ่ไป ซึ่งอาจทำให้โมเดลสร้างผลบวกลวงมากขึ้น การลดตัวอย่างมีประโยชน์ที่สุดเมื่อคลาสส่วนใหญ่มีขนาดใหญ่มากจนการเพิ่มตัวอย่างทำให้การฝึกช้าจนไม่เหมาะสม
การลดตัวอย่างแบบสุ่ม: ลบตัวอย่างของคลาสส่วนใหญ่แบบสุ่ม
RandomUnderSampler จะเลือกและลบตัวอย่างของคลาสส่วนใหญ่แบบสุ่มจนได้อัตราส่วนตามต้องการ วิธีนี้เป็นวิธีลดตัวอย่างที่เร็วที่สุด แต่ต้องทิ้งข้อมูลที่อาจมีประโยชน์ สำหรับชุดข้อมูลขนาดเล็ก การลดตัวอย่างแบบสุ่มอาจทำให้โมเดลแย่ลงอย่างมาก เพราะลบตัวอย่างของคลาสส่วนใหญ่ที่อยู่ใกล้เส้นแบ่งการตัดสินใจ
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))การควบคุมกลยุทธ์การสุ่มตัวอย่าง
พารามิเตอร์ sampling_strategy ใช้ควบคุมอัตราส่วนสุดท้ายระหว่างคลาสส่วนน้อยกับคลาสส่วนใหญ่ ค่า 1.0 ทำให้ทั้งสองคลาสมีจำนวนเท่ากัน ส่วนค่า 0.5 ทำให้คลาสส่วนใหญ่มีจำนวนมากกว่า 2:1 สำหรับชุดข้อมูลขนาดใหญ่มาก คุณอาจตั้งค่า 0.1 เพื่อสร้างอัตราส่วน 10:1 ซึ่งยังดีกว่าอัตราส่วนเดิม 100:1 และช่วยให้การฝึกยังรวดเร็ว เลือกค่าตามต้นทุนทางธุรกิจของผลบวกลวงเทียบกับผลลบลวง
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: การลดตัวอย่างอย่างชาญฉลาด
ClusterCentroids ใช้การจัดกลุ่มแบบ K-Means กับคลาสส่วนใหญ่ แล้วแทนที่แต่ละกลุ่มด้วยเซนทรอยด์ แทนที่จะเก็บตัวอย่างจากคลาสส่วนใหญ่แบบสุ่ม วิธีนี้จะเก็บชุดข้อมูลที่กระชับและเป็นตัวแทนของข้อมูลไว้ ซึ่งรักษาโครงสร้างโดยรวมของคลาสส่วนใหญ่ได้ดีกว่าการลบแบบสุ่ม แต่ทำงานช้ากว่าและต้องปรับจำนวนกลุ่ม (ซึ่งจะเท่ากับจำนวนเป้าหมายของคลาสส่วนใหญ่หลังการสุ่มตัวอย่างใหม่)
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')การเปรียบเทียบวิธีลดจำนวนตัวอย่าง
เราจะทดสอบประสิทธิภาพของการลดจำนวนตัวอย่างแบบสุ่ม การใช้เซนทรอยด์ของกลุ่ม และการไม่สุ่มตัวอย่างใหม่ โดยใช้ชุดข้อมูลที่ไม่สมดุลชุดเดียวกัน และใช้ F1-score ของคลาสส่วนน้อยเป็นเมตริกประเมินผล
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)}')การสูญเสียข้อมูลจากการลดจำนวนตัวอย่าง
ข้อเสียสำคัญของการลดจำนวนตัวอย่างคือ การสูญเสียข้อมูล เมื่อทิ้งตัวอย่างจากคลาสส่วนใหญ่ 95 ตัวจากทุก ๆ 100 ตัว โมเดลจะเห็นการกระจายของข้อมูลฝึกที่แตกต่างจากความเป็นจริงอย่างมาก ซึ่งอาจทำให้อัตราผลบวกลวงในการใช้งานจริงสูงขึ้น ด้วยเหตุนี้ จึงมักใช้การลดจำนวนตัวอย่างร่วมกับการเพิ่มจำนวนตัวอย่าง (เช่น ใช้ SMOTEENN หรือ SMOTETomek) เพื่อสร้างสมดุลให้ชุดข้อมูลพร้อมลดการสูญเสียข้อมูลให้น้อยที่สุด
การผสานการเพิ่มและลดจำนวนตัวอย่าง
SMOTETomek ผสาน SMOTE (เพิ่มจำนวนตัวอย่างของคลาสส่วนน้อย) กับการลบ Tomek Links (ทำความสะอาดตัวอย่างของคลาสส่วนใหญ่ที่อยู่บริเวณขอบเขตและมีความกำกวม) ผลลัพธ์คือคลาสทั้งสองมีความสมดุล และตัวอย่างของคลาสส่วนใหญ่ที่อยู่ใกล้เส้นแบ่งซึ่งทำให้ตัวจำแนกสับสนจะถูกลบออก วิธีผสานนี้มักให้ผลดีกว่าการเพิ่มหรือลดจำนวนตัวอย่างเพียงอย่างเดียว
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: การลดจำนวนตัวอย่างตามระยะห่างอย่างมีข้อมูลประกอบ
NearMiss เลือกตัวอย่างจากคลาสส่วนใหญ่โดยพิจารณาระยะห่างจากตัวอย่างของคลาสส่วนน้อย โดยเลือกตัวอย่างที่ใกล้ที่สุด (NearMiss-1) หรือไกลที่สุด (NearMiss-3) ต่างจากการลดจำนวนตัวอย่างแบบสุ่ม NearMiss จะเก็บตัวอย่างของคลาสส่วนใหญ่ที่เกี่ยวข้องกับการกำหนดเส้นแบ่งการตัดสินใจมากที่สุด NearMiss-3 จะเก็บตัวอย่างของคลาสส่วนใหญ่ที่อยู่ไกลจากตัวอย่างของคลาสส่วนน้อยทั้งหมดมากที่สุด ทำให้บริเวณเส้นแบ่งสะอาดขึ้น
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))การลดจำนวนตัวอย่างภายในไปป์ไลน์ imblearn
เช่นเดียวกับการเพิ่มจำนวนตัวอย่าง การลดจำนวนตัวอย่างต้องทำภายในไปป์ไลน์เพื่อป้องกันข้อมูลรั่วไหลระหว่างการตรวจสอบไขว้ ให้ใช้ imblearn.pipeline.Pipeline โดยวางตัวลดจำนวนตัวอย่างเป็นขั้นตอนก่อนตัวจำแนก ระบบจะเรียกใช้ fit_resample ของตัวสุ่มตัวอย่างใหม่กับชุดฝึกในแต่ละส่วน และจะไม่มีการแก้ไขชุดทดสอบ
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}')เมื่อใดควรเลือกการลดจำนวนตัวอย่างแทนการเพิ่มจำนวนตัวอย่าง
ควรเลือกการลดจำนวนตัวอย่างเมื่อ: คลาสส่วนใหญ่มีขนาดใหญ่มาก (มีตัวอย่างหลายล้านรายการ) เวลาในการฝึกเป็นคอขวด หรือทรัพยากรการคำนวณมีจำกัด ควรเลือกการเพิ่มจำนวนตัวอย่าง (SMOTE) เมื่อ: คลาสส่วนน้อยมีขนาดเล็กมาก (มีตัวอย่างไม่ถึงไม่กี่ร้อยรายการ) การทิ้งข้อมูลของคลาสส่วนใหญ่จะทำให้ชุดฝึกเล็กเกินไป หรือคลาสส่วนน้อยมีโครงสร้างซับซ้อนและไม่ใช่รูปนูน ซึ่ง SMOTE สามารถเติมตัวอย่างได้ ในทางปฏิบัติ ให้ลองทั้งสองวิธีแล้วเปรียบเทียบด้วยเมตริกจากชุดตรวจสอบ
การประเมินผลหลังลดจำนวนตัวอย่าง
หลังการสุ่มตัวอย่างใหม่ ให้ประเมินผลด้วย ชุดทดสอบเดิมที่ไม่สมดุล เสมอ — ห้ามใช้ชุดทดสอบที่สุ่มตัวอย่างใหม่ การสุ่มตัวอย่างข้อมูลทดสอบใหม่จะทำให้เห็นประสิทธิภาพในการใช้งานจริงอย่างไม่สมจริง เป้าหมายคือการปรับปรุงพฤติกรรมของโมเดลบนการกระจายข้อมูลจริง ไม่ใช่การปรับให้เหมาะกับการกระจายข้อมูลที่สร้างสมดุลขึ้นมาเทียม
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)))ตรวจสอบความเข้าใจอย่างรวดเร็ว
ทดสอบความเข้าใจเกี่ยวกับการลดจำนวนตัวอย่างและ Cluster Centroids จากบทเรียนนี้
สรุปบทเรียน
ในบทเรียนนี้ คุณได้เรียนรู้ว่า RandomUnderSampler ลบตัวอย่างของคลาสส่วนใหญ่ออกแบบสุ่ม ซึ่งทำงานได้รวดเร็วแต่เสี่ยงสูญเสียข้อมูลสำคัญบริเวณเส้นแบ่ง ClusterCentroids แทนที่กลุ่มของคลาสส่วนใหญ่ด้วยเซนทรอยด์ เพื่อรักษาการกระจายของคลาสให้ใกล้เคียงความเป็นจริงมากขึ้น และ ควรประเมินผลด้วยชุดทดสอบเดิมที่ไม่สมดุลเสมอ เพื่อวัดพฤติกรรมของโมเดลในโลกจริง บทถัดไปเราจะสำรวจการให้น้ำหนักคลาสและการเลื่อนค่าเกณฑ์เพื่อใช้เป็นทางเลือกแทนการสุ่มตัวอย่างใหม่
เรียนรู้ Python ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 30
- บทเรียน
- 120
คำถามที่พบบ่อย
บทเรียน “การสุ่มลดตัวอย่างและ ClusterCentroids” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การสุ่มลดตัวอย่างและ ClusterCentroids” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Machine Learning Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Machine Learning Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การสุ่มลดตัวอย่างและ ClusterCentroids”
ผู้เรียนจะลดตัวอย่างของคลาสส่วนใหญ่แบบสุ่มและด้วย ClusterCentroids พร้อมเปรียบเทียบการสูญเสียข้อมูลกับประสิทธิภาพของแบบจำลองที่ได้ คุณปฏิบัติ Machine Learning Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Machine Learning Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Machine Learning Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การสุ่มลดตัวอย่างและ ClusterCentroids” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Machine Learning Academy นี้ได้ไหม
ได้ บทเรียน Machine Learning Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การตรวจจับความไม่สมดุล: การกระจายของคลาสและข้อผิดพลาดของค่าพื้นฐาน
- การสุ่มเพิ่มตัวอย่างและ SMOTE
- การสุ่มลดตัวอย่างและ ClusterCentroids
- น้ำหนักคลาสและการเลื่อนเกณฑ์ตัดสินใจ