Machine Learning Academy · पाठ

वर्ग भार और सीमा स्थानांतरण

शिक्षार्थी sklearn वर्गीकारकों में class_weight='balanced' सेट करेंगे और दुर्लभ घटनाओं के लिए recall को और बेहतर बनाने हेतु प्रायिकता आउटपुट पर निर्णय सीमा बदलेंगे।

पाठ 4, कुल 4 में से13 चरण

वर्ग भार और सीमा स्थानांतरण, CoddyKit पर Machine Learning Academy का एक निःशुल्क पाठ है। यह 4 में से 4वाँ पाठ है। आप नीचे पूरा पाठ निःशुल्क पढ़ सकते हैं—फिर अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर के साथ ब्राउज़र में इसका व्यावहारिक अभ्यास कर सकते हैं। यह Machine Learning Academy सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। Machine Learning Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

रीसैंपलिंग के दो विकल्प

रीसैंपलिंग (SMOTE, अंडरसैंपलिंग) प्रशिक्षण डेटा को भौतिक रूप से बदलता है। दो वैकल्पिक तरीके मूल डेटा पर सीधे काम करते हैं: वर्ग भार प्रशिक्षण के दौरान अल्पसंख्यक नमूनों के गलत वर्गीकरण को अधिक दंडित करता है और थ्रेशहोल्ड स्थानांतरण प्रशिक्षण के बाद निर्णय सीमा को समायोजित करता है। दोनों तरीके सरल, तेज़ हैं और रीसैंपलिंग से होने वाली सूचना-हानि या कृत्रिम शोर के जोखिम से बचते हैं।

वर्ग भार: अल्पसंख्यक त्रुटियों को अधिक दंडित करें

अधिकांश sklearn वर्गीकारक class_weight पैरामीटर स्वीकार करते हैं। class_weight='balanced' सेट करने पर वर्ग आवृत्तियों के व्युत्क्रमानुपाती भार स्वतः निकाले जाते हैं: weight[c] = n_samples / (n_classes * count[c])। इसके बाद किसी दुर्लभ सकारात्मक नमूने का गलत वर्गीकरण, किसी सामान्य नकारात्मक नमूने के गलत वर्गीकरण की तुलना में कहीं अधिक दंडित होता है, जिससे मॉडल अल्पसंख्यक वर्ग को बेहतर ढंग से सीखता है।

from sklearn.linear_model import LogisticRegression
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, stratify=y, random_state=42)

sc = StandardScaler()
X_tr = sc.fit_transform(X_train)
X_te = sc.transform(X_test)

# With balanced class weights
lr = LogisticRegression(class_weight='balanced').fit(X_tr, y_train)
print('--- class_weight=balanced ---')
print(classification_report(y_test, lr.predict(X_te)))

संतुलित भारों की मैन्युअल गणना

यदि आप 'balanced' से अधिक सूक्ष्म नियंत्रण चाहते हैं, तो कस्टम भारों का शब्दकोश भी दे सकते हैं। उदाहरण के लिए, यदि आपके व्यवसाय के अनुसार छूटे हुए धोखाधड़ी के मामले की लागत गलत अलार्म से 20 गुना अधिक है, तो class_weight={0: 1, 1: 20} सेट करें। इससे गलत वर्गीकरण की लागत का अनुपात सीधे प्रशिक्षण में शामिल हो जाता है।

from sklearn.linear_model import LogisticRegression
from sklearn.utils.class_weight import compute_class_weight
import numpy as np

# Compute balanced weights automatically
y_train = np.array([0] * 475 + [1] * 25)
classes = np.unique(y_train)
weights = compute_class_weight('balanced', classes=classes, y=y_train)
weight_dict = dict(zip(classes, weights))
print('Auto-balanced weights:', weight_dict)

# Custom: penalty 10x higher for missing positive
custom_weights = {0: 1, 1: 10}
print('Custom weights:', custom_weights)

lr = LogisticRegression(class_weight=custom_weights)
# lr.fit(X_train, y_train)

कौन-से एल्गोरिदम class_weight का समर्थन करते हैं?

scikit-learn में ये आकलक class_weight स्वीकार करते हैं: LogisticRegression, LinearSVC, SVC, SGDClassifier, DecisionTreeClassifier, RandomForestClassifier। ग्रेडिएंट बूस्टिंग मॉडल (XGBoost, LightGBM) समान भूमिका निभाने वाले scale_pos_weight पैरामीटर का उपयोग करते हैं। न्यूरल नेटवर्क हानि फलन में sample_weight के माध्यम से इसे संभालते हैं।

from sklearn.ensemble import RandomForestClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.linear_model import LogisticRegression

# All support class_weight='balanced'
models = [
    LogisticRegression(class_weight='balanced'),
    DecisionTreeClassifier(class_weight='balanced'),
    RandomForestClassifier(class_weight='balanced'),
    SVC(class_weight='balanced', probability=True)
]

print('All these models support class_weight:')
for m in models:
    print(' ', m.__class__.__name__)

थ्रेशहोल्ड स्थानांतरण: निर्णय सीमा को समायोजित करना

वर्गीकारक प्रायिकता स्कोर देते हैं; डिफ़ॉल्ट निर्णय थ्रेशहोल्ड 0.5 है — यदि proba >= 0.5 हो तो सकारात्मक का अनुमान लगाया जाता है। असंतुलित समस्याओं में थ्रेशहोल्ड घटाने (जैसे 0.3 करने) से अधिक सकारात्मक मामले पकड़े जाते हैं और रिकॉल बढ़ता है, लेकिन गलत-सकारात्मक परिणाम भी बढ़ते हैं। इसे बढ़ाने से प्रिसीजन बढ़ता है, लेकिन अधिक सकारात्मक मामले छूट जाते हैं। थ्रेशहोल्ड स्थानांतरण प्रशिक्षण के बाद लागू किया जाता है और इसके लिए मॉडल को दोबारा प्रशिक्षित करने की आवश्यकता नहीं होती।

from sklearn.linear_model import LogisticRegression
from sklearn.metrics import precision_score, recall_score, f1_score
from sklearn.preprocessing import StandardScaler
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_tr, X_te, y_tr, y_te = train_test_split(X, y, stratify=y, random_state=42)
sc = StandardScaler()
X_tr_s = sc.fit_transform(X_tr)
X_te_s = sc.transform(X_te)

lr = LogisticRegression(class_weight='balanced').fit(X_tr_s, y_tr)
proba = lr.predict_proba(X_te_s)[:, 1]

print(f'{'Threshold':>10}  {'Precision':>10}  {'Recall':>8}  {'F1':>6}')
for t in [0.2, 0.3, 0.4, 0.5, 0.6]:
    preds = (proba >= t).astype(int)
    p = precision_score(y_te, preds, zero_division=0)
    r = recall_score(y_te, preds)
    f = f1_score(y_te, preds, zero_division=0)
    print(f'{t:>10.1f}  {p:>10.4f}  {r:>8.4f}  {f:>6.4f}')

इष्टतम थ्रेशहोल्ड खोजना

सभी संभावित थ्रेशहोल्ड पर जाँच करके संबंधित प्रिसीजन और रिकॉल निकालने के लिए precision_recall_curve और roc_curve फलनों का उपयोग करें। फिर वह थ्रेशहोल्ड चुनें जो F1 (या किसी अन्य व्यावसायिक मापदंड) को अधिकतम करता हो। यह थ्रेशहोल्ड मान का अनुमान लगाने से अधिक व्यवस्थित तरीका है।

from sklearn.metrics import precision_recall_curve, f1_score
import numpy as np

# proba and y_te from previous step
precisions, recalls, thresholds = precision_recall_curve(y_te, proba)

# F1 at each threshold
f1_scores = 2 * (precisions * recalls) / (precisions + recalls + 1e-8)
best_idx = np.argmax(f1_scores)
best_threshold = thresholds[best_idx]
best_f1 = f1_scores[best_idx]

print(f'Optimal threshold: {best_threshold:.4f}')
print(f'Best F1 at that threshold: {best_f1:.4f}')

# Apply the optimal threshold
y_pred_opt = (proba >= best_threshold).astype(int)
print('Minority class recall:', recall_score(y_te, y_pred_opt).round(4))

class_weight बनाम रीसैंपलिंग: समझौते

class_weight के लाभ: डेटा में कोई बदलाव नहीं, कृत्रिम नमूनों पर अति-अनुकूलन का जोखिम नहीं, मानक sklearn Pipeline के भीतर काम करता है और अधिक तेज़ है। रीसैंपलिंग के लाभ: ऐसे एल्गोरिदम के साथ काम करता है जो class_weight का समर्थन नहीं करते (जैसे कुछ बूस्टिंग प्रकार), और बहुत गंभीर असंतुलन (>100:1) में सहायता कर सकता है, जहाँ केवल वर्ग भार पर्याप्त नहीं होते। व्यवहार में पहले वर्ग भार आज़माएँ — यह सरल और अक्सर पर्याप्त होता है।

ROC वक्र के साथ थ्रेशहोल्ड स्थानांतरण

ROC वक्र प्रत्येक थ्रेशहोल्ड पर वास्तविक-सकारात्मक दर (रिकॉल) और गलत-सकारात्मक दर के बीच समझौता दिखाता है। Youden's J statistic (TPR - FPR) उस इष्टतम थ्रेशहोल्ड पर अधिकतम होता है जहाँ संवेदनशीलता और विशिष्टता का संतुलन हो। जब आप दोनों प्रकार की त्रुटियों को समान महत्व देना चाहते हों, तब इसका उपयोग करें।

from sklearn.metrics import roc_curve
import numpy as np

fpr, tpr, thresholds = roc_curve(y_te, proba)

# Youden's J: maximise TPR - FPR
j_scores = tpr - fpr
best_idx = np.argmax(j_scores)
optimal_threshold = thresholds[best_idx]

print(f'Optimal threshold (Youden J): {optimal_threshold:.4f}')
print(f'TPR: {tpr[best_idx]:.4f}  FPR: {fpr[best_idx]:.4f}')

y_pred_youden = (proba >= optimal_threshold).astype(int)
from sklearn.metrics import classification_report
print(classification_report(y_te, y_pred_youden))

XGBoost और LightGBM में वर्ग भार

XGBoost प्रशिक्षण समूह में नकारात्मक और सकारात्मक नमूनों के अनुपात scale_pos_weight का उपयोग सकारात्मक उदाहरणों का भार बढ़ाने के लिए करता है। 95:5 के असंतुलन के लिए scale_pos_weight=19 (95/5) सेट करें। LightGBM इसी प्रकार is_unbalance=True या scale_pos_weight का उपयोग करता है। दोनों sklearn के class_weight='balanced' के समान हैं, लेकिन पैरामीटर नामकरण की अलग परंपरा अपनाते हैं।

import xgboost as xgb
import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score

X, y = make_classification(n_samples=1000, weights=[0.95, 0.05], random_state=42)
X_tr, X_te, y_tr, y_te = train_test_split(X, y, stratify=y, random_state=42)

neg, pos = np.bincount(y_tr)
scale = neg / pos
print(f'scale_pos_weight = {scale:.1f}')

clf = xgb.XGBClassifier(scale_pos_weight=scale, random_state=42, eval_metric='logloss')
clf.fit(X_tr, y_tr)
print('AUC:', roc_auc_score(y_te, clf.predict_proba(X_te)[:, 1]).round(4))

असंतुलन की सभी रणनीतियों की तुलना

एक ही डेटासेट और परीक्षण समूह पर विभिन्न रणनीतियों की व्यवस्थित तुलना से पता चलता है कि आपकी विशिष्ट समस्या और एल्गोरिदम के लिए कौन-सा तरीका सबसे अच्छा है। यह तुलना चलाएँ और अपने अंतिम रणनीति-चयन को उचित ठहराने के लिए परिणामों को तालिका में प्रस्तुत करें।

from imblearn.over_sampling import SMOTE
from imblearn.under_sampling import RandomUnderSampler
from imblearn.pipeline import Pipeline as ImbPipeline
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import roc_auc_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_tr, X_te, y_tr, y_te = train_test_split(X, y, stratify=y, random_state=0)
sc = StandardScaler()
X_tr_s = sc.fit_transform(X_tr)
X_te_s = sc.transform(X_te)

strategies = [
    ('Baseline', None, {}),
    ('class_weight', None, {'class_weight': 'balanced'}),
    ('RUS', RandomUnderSampler(random_state=0), {}),
    ('SMOTE', SMOTE(random_state=0), {})
]

for name, sampler, kwargs in strategies:
    Xr, yr = (sampler.fit_resample(X_tr_s, y_tr) if sampler else (X_tr_s, y_tr))
    lr = LogisticRegression(**kwargs).fit(Xr, yr)
    auc = roc_auc_score(y_te, lr.predict_proba(X_te_s)[:, 1])
    print(f'{name:15s}: AUC={auc:.4f}')

प्रायिकता आउटपुट का कैलिब्रेशन

वर्ग भार और थ्रेशहोल्ड स्थानांतरण दोनों मॉडल के प्रायिकता स्कोर पर निर्भर करते हैं। यदि वर्गीकारक का कैलिब्रेशन खराब है (जैसे Platt scaling का उपयोग करने वाला probability=True वाला SVM), तो थ्रेशहोल्ड समायोजन अच्छी तरह काम नहीं कर सकता। थ्रेशहोल्ड अनुकूलित करने से पहले प्रायिकताओं की विश्वसनीयता सुनिश्चित करने के लिए sklearn.calibration.CalibratedClassifierCV का उपयोग करें या कैलिब्रेशन वक्रों की तुलना calibration_curve से करें।

त्वरित जाँच

इस पाठ से वर्ग भार और थ्रेशहोल्ड स्थानांतरण की अपनी समझ जाँचें।

पाठ का पुनरावलोकन

इस पाठ में आपने सीखा: class_weight='balanced' अल्पसंख्यक-वर्ग के गलत वर्गीकरण को अनुपातिक रूप से दंडित करता है और प्रशिक्षण डेटा में बदलाव किए बिना काम करता है; थ्रेशहोल्ड स्थानांतरण प्रशिक्षण के बाद निर्णय सीमा को समायोजित करता है और रिकॉल-प्रिसीजन के बीच संतुलन बदलता है; तथा इष्टतम थ्रेशहोल्ड खोजा जा सकता है — प्रिसीजन-रिकॉल वक्र पर F1 या ROC वक्र पर Youden's J को अधिकतम करके। आगे हम प्रोडक्शन परिनियोजन के लिए प्रशिक्षित मॉडलों को joblib और pickle से सहेजेंगे।

शुरुआत निःशुल्क

एआई शिक्षक के साथ Python सीखें — निःशुल्क

अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।

पाठ्यक्रम
30
पाठ
120

अक्सर पूछे जाने वाले प्रश्न

क्या “वर्ग भार और सीमा स्थानांतरण” पाठ निःशुल्क है?

हाँ—“वर्ग भार और सीमा स्थानांतरण” का पूरा पाठ यहाँ वेब पर निःशुल्क पढ़ा जा सकता है। इंटरैक्टिव अभ्यास (अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर) करने और Machine Learning Academy पाठ्यक्रम का बाकी हिस्सा अनलॉक करने के लिए CoddyKit PRO लें। Machine Learning Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

“वर्ग भार और सीमा स्थानांतरण” में मैं क्या सीखूँगा?

शिक्षार्थी sklearn वर्गीकारकों में class_weight='balanced' सेट करेंगे और दुर्लभ घटनाओं के लिए recall को और बेहतर बनाने हेतु प्रायिकता आउटपुट पर निर्णय सीमा बदलेंगे। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ Machine Learning Academy का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।

क्या Machine Learning Academy शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?

पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर Machine Learning Academy शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 4वाँ पाठ है।

“वर्ग भार और सीमा स्थानांतरण” पाठ पूरा करने में कितना समय लगता है?

CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।

क्या मैं इस Machine Learning Academy पाठ में कोड लिख और चला सकता हूँ?

हाँ। हर Machine Learning Academy पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।

इस पाठ्यक्रम के सभी पाठ

  1. असंतुलन का पता लगाना: वर्ग वितरण और आधाररेखा की समस्याएँ
  2. रैंडम ओवरसैंपलिंग और SMOTE
  3. रैंडम अंडरसैंपलिंग और ClusterCentroids
  4. वर्ग भार और सीमा स्थानांतरण
← Machine Learning Academy पर वापस जाएँ