Mengesan Ketidakseimbangan: Taburan Kelas dan Perangkap Garis Dasar
Pelajar akan mengira kekerapan kelas, mendedahkan perangkap pengelas olok-olok pada set data tidak seimbang, dan mengesahkan bahawa ketepatan ialah metrik yang mengelirukan dalam keadaan ini.
Mengesan Ketidakseimbangan: Taburan Kelas dan Perangkap Garis Dasar ialah pelajaran Machine Learning Academy percuma di CoddyKit. Ini ialah pelajaran 1 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Machine Learning Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Machine Learning Academy merangkumi sejumlah 4 pelajaran.
Apakah Ketidakseimbangan Kelas?
Ketidakseimbangan kelas berlaku apabila satu kelas mendominasi set data. Dalam pengesanan penipuan, transaksi penipuan mungkin hanya merangkumi 0.1% daripada semua rekod; dalam diagnosis perubatan, penyakit yang jarang berlaku mungkin menjejaskan 1 daripada setiap 1000 pesakit. Model yang sentiasa meramalkan kelas majoriti boleh mencapai ketepatan 99.9% sambil mengabaikan sepenuhnya kelas yang jarang tetapi kritikal — menjadikan ketepatan sebagai metrik yang amat mengelirukan dalam senario ini.
Mengukur Taburan Kelas
Sebelum melatih sebarang model, periksa taburan kelas dengan pd.Series(y).value_counts() atau np.bincount(y). Statistik ringkasan yang berguna ialah nisbah ketidakseimbangan — nisbah bilangan kelas majoriti kepada kelas minoriti. Nisbah melebihi 10:1 dianggap tidak seimbang; nisbah melebihi 100:1 sangat tidak seimbang dan memerlukan teknik khusus.
import numpy as np
import pandas as pd
# Simulate imbalanced binary classification dataset
np.random.seed(0)
y = np.array([0] * 950 + [1] * 50) # 95% negative, 5% positive
counts = pd.Series(y).value_counts()
print('Class counts:\n', counts)
print()
print('Class proportions:\n', counts / len(y))
print()
print('Imbalance ratio:', counts[0] / counts[1])Perangkap Ketepatan dengan Data Tidak Seimbang
Pada set data yang mempunyai 95% contoh negatif, model yang sentiasa meramalkan kelas majoriti (negatif) boleh mencapai ketepatan 95% tanpa mempelajari apa-apa yang berguna. Inilah perangkap ketepatan. Model tersebut langsung tidak berupaya mengesan kes positif (kelas yang sebenarnya penting kepada anda), namun ketepatannya kelihatan mengagumkan. Sebab itulah set data tidak seimbang memerlukan metrik selain ketepatan.
from sklearn.dummy import DummyClassifier
from sklearn.metrics import accuracy_score, classification_report
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_classification
X, y = make_classification(n_samples=1000, weights=[0.95, 0.05],
random_state=42, n_features=10)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
# Always predict majority class
dummy = DummyClassifier(strategy='most_frequent')
dummy.fit(X_train, y_train)
y_pred = dummy.predict(X_test)
print('Accuracy:', accuracy_score(y_test, y_pred).round(4))
print()
print(classification_report(y_test, y_pred))Sebab Garis Dasar Dummy Classifier Penting
DummyClassifier dengan strategy='most_frequent' ialah garis dasar minimum yang boleh diterima. Mana-mana model sebenar mesti mengatasinya dengan ketara — bukan dari segi ketepatan sahaja, tetapi juga dari segi metrik yang penting (kejituan, kadar ingatan semula, F1 atau AUC-ROC). Jika model sebenar anda hanya sedikit lebih baik daripada dummy, model itu berkemungkinan juga telah belajar untuk mengabaikan kelas minoriti.
from sklearn.linear_model import LogisticRegression
from sklearn.dummy import DummyClassifier
from sklearn.metrics import classification_report
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, random_state=42)
X_train_s = StandardScaler().fit_transform(X_train)
X_test_s = StandardScaler().fit_transform(X_test)
lr = LogisticRegression().fit(X_train_s, y_train)
print('--- Logistic Regression ---')
print(classification_report(y_test, lr.predict(X_test_s)))Kejituan dan Kadar Ingatan Semula pada Data Tidak Seimbang
Bagi masalah tidak seimbang, dua metrik yang paling bermaklumat ialah: Kejituan = TP / (TP + FP) — daripada semua kes positif yang diramalkan, berapa banyakkah yang benar-benar positif? Kadar ingatan semula = TP / (TP + FN) — daripada semua kes positif sebenar, berapa banyakkah yang berjaya dikesan oleh model? Dalam pengesanan penipuan, kadar ingatan semula amat penting (jangan terlepas penipuan); dalam penapisan spam, kejituan lebih penting (jangan tersalah klasifikasikan e-mel yang sah).
from sklearn.metrics import precision_score, recall_score, f1_score
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, random_state=42)
X_train_s = StandardScaler().fit_transform(X_train)
X_test_s = StandardScaler().fit_transform(X_test)
lr = LogisticRegression().fit(X_train_s, y_train)
y_pred = lr.predict(X_test_s)
print(f'Precision: {precision_score(y_test, y_pred):.4f}')
print(f'Recall: {recall_score(y_test, y_pred):.4f}')
print(f'F1-Score: {f1_score(y_test, y_pred):.4f}')ROC-AUC: Penilaian Tanpa Bergantung pada Ambang
ROC-AUC menilai model pada semua ambang keputusan yang mungkin dan mengukur luas di bawah lengkung yang terhasil. AUC 0.5 bermaksud ramalan rawak; 1.0 bermaksud sempurna; 0.9+ bermaksud cemerlang. Tidak seperti ketepatan, AUC tidak dipengaruhi oleh ketidakseimbangan kelas kerana ia menilai keupayaan menyusun kedudukan model dan bukannya ramalan pada ambang tetap. AUC ialah metrik utama yang disyorkan bagi kebanyakan tugasan pengklasifikasian binari yang tidak seimbang.
from sklearn.metrics import roc_auc_score
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, random_state=42)
sc = StandardScaler()
X_train_s = sc.fit_transform(X_train)
X_test_s = sc.transform(X_test)
lr = LogisticRegression().fit(X_train_s, y_train)
proba = lr.predict_proba(X_test_s)[:, 1]
print('ROC-AUC:', roc_auc_score(y_test, proba).round(4))Memvisualkan Ketidakseimbangan Kelas
Carta bar ringkas bagi kekerapan kelas dapat menyampaikan ketidakseimbangan dengan segera kepada pihak berkepentingan. Sertakannya dalam buku nota analisis data penerokaan anda sebagai amalan standard. Jika anda menggunakan DataFrame Pandas, periksa juga ketidakseimbangan tersembunyi yang berpunca daripada berat sebelah dalam pengumpulan data, bukannya kelangkaan sebenar di dunia nyata.
import matplotlib.pyplot as plt
import numpy as np
y = np.array([0] * 950 + [1] * 50)
classes, counts = np.unique(y, return_counts=True)
plt.bar(['Negative (0)', 'Positive (1)'], counts, color=['#2196F3', '#F44336'])
plt.ylabel('Count')
plt.title('Class Distribution (95:5 imbalance)')
for i, c in enumerate(counts):
plt.text(i, c + 5, str(c), ha='center', fontweight='bold')
plt.show()Pemisahan Berstrata untuk Mengekalkan Nisbah
Apabila memisahkan set data yang tidak seimbang, gunakan stratify=y dalam train_test_split. Tanpa stratifikasi, kebetulan rawak mungkin meletakkan semua sampel kelas minoriti dalam satu bahagian, lalu menjadikan latihan atau penilaian tidak bermakna. Pemisahan berstrata memastikan set latihan dan ujian mempunyai nisbah kelas yang sama seperti set data asal.
from sklearn.model_selection import train_test_split
import numpy as np
y = np.array([0] * 950 + [1] * 50)
X = np.random.randn(1000, 5)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, stratify=y, random_state=42
)
print('Train class ratio:', (y_train == 1).mean().round(4))
print('Test class ratio:', (y_test == 1).mean().round(4))
print('Expected ratio:', (y == 1).mean().round(4))Stratified K-Fold untuk Pengesahan Silang
Begitu juga, gunakan StratifiedKFold (atau hanya hantarkan cv=5 kepada cross_val_score — scikit-learn menggunakan StratifiedKFold secara automatik untuk pengelas) bagi memastikan setiap lipatan mengekalkan nisbah kelas asal. KFold biasa dengan kelas minoriti yang kecil boleh menghasilkan lipatan tanpa sebarang contoh positif, lalu menyebabkan ralat atau metrik yang mengelirukan.
from sklearn.model_selection import StratifiedKFold, cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
import numpy as np
y = np.array([0] * 950 + [1] * 50)
X = np.random.randn(1000, 5)
pipe = Pipeline([('sc', StandardScaler()), ('lr', LogisticRegression())])
skf = StratifiedKFold(n_splits=5)
scores = cross_val_score(pipe, X, y, cv=skf, scoring='roc_auc')
print(f'Stratified CV AUC: {np.mean(scores):.4f} +/- {np.std(scores):.4f}')Lengkung Kejituan-Kadar Ingatan Semula
Bagi data yang sangat tidak seimbang, lengkung kejituan-kadar ingatan semula (PR) selalunya lebih bermaklumat berbanding lengkung ROC. Lengkung PR menunjukkan kejituan pada paksi-y dan kadar ingatan semula pada paksi-x untuk semua ambang. Luas di bawah lengkung PR (skor AP) berjulat dari 0 hingga 1 dan sensitif terhadap prestasi kelas minoriti, dengan cara yang mungkin tidak ditunjukkan oleh ROC-AUC apabila kelas majoriti terlalu dominan.
from sklearn.metrics import precision_recall_curve, average_precision_score
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
import matplotlib.pyplot as plt
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_train_s = sc.fit_transform(X_train)
X_test_s = sc.transform(X_test)
lr = LogisticRegression().fit(X_train_s, y_train)
proba = lr.predict_proba(X_test_s)[:, 1]
precision, recall, _ = precision_recall_curve(y_test, proba)
ap = average_precision_score(y_test, proba)
plt.plot(recall, precision, label=f'AP={ap:.3f}')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.title('Precision-Recall Curve')
plt.legend()
plt.show()Mendokumentasikan Ketidakseimbangan Sebelum Pemodelan
Amalan terbaik: hasilkan laporan ketidakseimbangan pada permulaan setiap projek pengklasifikasian. Rekodkan bilangan kelas, nisbah dan ketepatan garis dasar dummy. Langkah ini menetapkan jangkaan serta memaksa pasukan bersetuju tentang metrik kejayaan yang betul sebelum sebarang model dilatih. Model pengesanan penipuan dengan ketepatan 95% biasanya tidak berguna — pihak berkepentingan anda perlu mengetahui perkara ini sejak awal.
import numpy as np
from sklearn.dummy import DummyClassifier
from sklearn.metrics import accuracy_score, roc_auc_score
y = np.array([0] * 950 + [1] * 50)
X = np.random.randn(1000, 5)
dummy = DummyClassifier(strategy='most_frequent').fit(X, y)
dummy_acc = accuracy_score(y, dummy.predict(X))
dummy_auc = roc_auc_score(y, dummy.predict_proba(X)[:, 1])
print('=== Imbalance Report ===')
print(f'Class 0: {(y==0).sum()} ({(y==0).mean():.1%})')
print(f'Class 1: {(y==1).sum()} ({(y==1).mean():.1%})')
print(f'Imbalance ratio: {(y==0).sum()/(y==1).sum():.0f}:1')
print(f'Dummy accuracy: {dummy_acc:.4f}')
print(f'Dummy AUC: {dummy_auc:.4f}')
print('Recommended metric: ROC-AUC or Precision-Recall AUC')Semakan Pantas
Uji pemahaman anda tentang ketidakseimbangan kelas dan perangkap garis dasar daripada pelajaran ini.
Ringkasan Pelajaran
Dalam pelajaran ini, anda telah mempelajari bahawa ketidakseimbangan kelas menjadikan ketepatan sebagai metrik yang mengelirukan — model yang hanya meramalkan kelas majoriti boleh mencapai ketepatan yang sangat tinggi, sentiasa bandingkan dengan garis dasar DummyClassifier untuk memastikan model anda mempelajari sesuatu yang lebih daripada penyelesaian remeh, dan gunakan ROC-AUC atau AUC kejituan-kadar ingatan semula sebagai metrik utama bagi set data tidak seimbang. Seterusnya, kita akan menggunakan SMOTE dan pensampelan berlebihan rawak untuk menambah sampel kelas minoriti.
Pelajari Python dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 30
- Pelajaran
- 120
Soalan Lazim
Adakah pelajaran “Mengesan Ketidakseimbangan: Taburan Kelas dan Perangkap Garis Dasar” percuma?
Ya — teks penuh “Mengesan Ketidakseimbangan: Taburan Kelas dan Perangkap Garis Dasar” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Machine Learning Academy, tingkat taraf kepada CoddyKit PRO. Kursus Machine Learning Academy merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Mengesan Ketidakseimbangan: Taburan Kelas dan Perangkap Garis Dasar”?
Pelajar akan mengira kekerapan kelas, mendedahkan perangkap pengelas olok-olok pada set data tidak seimbang, dan mengesahkan bahawa ketepatan ialah metrik yang mengelirukan dalam keadaan ini. Anda berlatih Machine Learning Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Machine Learning Academy?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Machine Learning Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 1 daripada 4.
Berapa lamakah pelajaran “Mengesan Ketidakseimbangan: Taburan Kelas dan Perangkap Garis Dasar” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Machine Learning Academy ini?
Ya. Setiap pelajaran Machine Learning Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Mengesan Ketidakseimbangan: Taburan Kelas dan Perangkap Garis Dasar
- Pensampelan Terlebih Rawak dan SMOTE
- Pensampelan Kurang Rawak dan ClusterCentroids
- Pemberat Kelas dan Pengalihan Ambang