Machine Learning Academy · पाठ

ट्री बनाना: विभाजन, नोड और लीफ़

शिक्षार्थी देखेंगे कि निर्णय ट्री प्रत्येक नोड पर डेटा को जड़ से लीफ़ तक पुनरावर्ती रूप से कैसे बाँटता है और शाखाओं का अनुसरण करके पूर्वानुमान कैसे करता है।

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

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

निर्णय वृक्ष क्या है

निर्णय वृक्ष फ़्लोचार्ट जैसी संरचना है, जिसमें प्रत्येक आंतरिक नोड किसी एक विशेषता के बारे में हाँ/नहीं का प्रश्न पूछता है, प्रत्येक शाखा एक उत्तर दर्शाती है और प्रत्येक पत्ती नोड में एक पूर्वानुमान होता है। किसी नए नमूने का वर्गीकरण करने के लिए आप मूल नोड से शुरू करते हैं, विशेषता मानों के अनुसार शाखाओं का अनुसरण करते हैं और उस पत्ती तक पहुँचते हैं जिसका लेबल पूर्वानुमान होता है। निर्णय वृक्ष डिज़ाइन के अनुसार व्याख्येय होते हैं — उत्तर दिए गए प्रश्नों के क्रम को पढ़कर आप ठीक-ठीक पता लगा सकते हैं कि कोई पूर्वानुमान क्यों किया गया, इसलिए वित्त और स्वास्थ्य सेवा जैसे विनियमित उद्योगों में इनका व्यापक उपयोग होता है।

# Conceptual tree for predicting loan default:
#
# Is income > 50000?
# |--- Yes: Is credit_score > 700?
# |         |--- Yes: APPROVE (leaf)
# |         |--- No:  Is debt_ratio < 0.4?
# |                   |--- Yes: APPROVE (leaf)
# |                   |--- No:  REJECT (leaf)
# |--- No: REJECT (leaf)

print('Decision tree makes predictions by asking questions')
print('Each path from root to leaf = one decision rule')

नोड, शाखाएँ और पत्तियाँ

निर्णय वृक्ष में तीन प्रकार के घटक होते हैं: रूट नोड (पूछा जाने वाला पहला प्रश्न — पूरे डेटासेट का सबसे अधिक जानकारी देने वाला विभाजन), आंतरिक नोड (मध्यवर्ती प्रश्न, जो डेटा के उपसमुच्चयों को आगे विभाजित करते हैं), और लीफ़ नोड (अंतिम नोड, जहाँ predictions संग्रहीत होते हैं)। प्रत्येक आंतरिक नोड किसी फ़ीचर की सीमा के आधार पर डेटा को दो या अधिक उपसमुच्चयों में विभाजित करता है। वृक्ष की गहराई रूट से किसी भी लीफ़ तक के सबसे लंबे पथ की लंबाई होती है। अधिक गहरे वृक्ष अधिक जटिल पैटर्न दर्शा सकते हैं, लेकिन उनमें अति-अनुरूपण की संभावना अधिक होती है।

# Tree anatomy example
print('Root node: first split on most informative feature')
print('Internal nodes: further splits on subsets')
print('Leaf nodes: final predictions')
print()
print('Depth=1 tree (stump): one question, two leaves')
print('Depth=2 tree: up to three questions, four leaves')
print('Depth=d tree: up to 2^d leaves')
print()
print('More depth = more flexible but higher overfitting risk')

पुनरावर्ती विभाजन: एल्गोरिदम कैसे विभाजित करता है

निर्णय वृक्ष का निर्माण एक लोभी, पुनरावर्ती एल्गोरिदम है। प्रत्येक नोड पर यह हर फ़ीचर और हर सीमा पर संभव विभाजन का मूल्यांकन करता है, वर्गों को सबसे अच्छी तरह अलग करने वाले विभाजन को चुनता है (जिसे Gini अशुद्धता या information_gain से मापा जाता है), उस विभाजन को लागू करता है और फिर बनने वाले प्रत्येक उपसमुच्चय पर यही प्रक्रिया पुनरावर्ती रूप से दोहराता है। यह तब तक चलता है, जब तक रुकने की कोई शर्त पूरी न हो जाए: अधिकतम गहराई पहुँच जाना, प्रति नोड न्यूनतम नमूने पूरे होना, या कोई और उपयोगी विभाजन न बचना। लोभी का अर्थ है कि हर चरण पर स्थानीय रूप से सबसे अच्छा विभाजन चुना जाता है, पीछे लौटकर विकल्पों की जाँच नहीं की जाती — इससे वैश्विक रूप से सर्वोत्तम विभाजन छूट सकते हैं, लेकिन एल्गोरिदम व्यावहारिक बना रहता है।

# Pseudocode for recursive tree building
def build_tree(X, y, depth=0, max_depth=3):
    # Stopping conditions
    if len(set(y)) == 1:      # All same class
        return {'leaf': True, 'prediction': y[0]}
    if depth >= max_depth:    # Max depth reached
        from collections import Counter
        return {'leaf': True, 'prediction': Counter(y).most_common(1)[0][0]}
    
    # Find best split
    best_feature, best_threshold = find_best_split(X, y)
    
    # Partition data
    left_mask  = X[:, best_feature] <= best_threshold
    right_mask = ~left_mask
    
    return {
        'leaf': False,
        'feature': best_feature,
        'threshold': best_threshold,
        'left':  build_tree(X[left_mask],  y[left_mask],  depth+1, max_depth),
        'right': build_tree(X[right_mask], y[right_mask], depth+1, max_depth)
    }

अक्ष-संरेखित विभाजन: एकल फ़ीचर पर सीमाएँ

स्किकिट-लर्न के निर्णय वृक्ष हमेशा अक्ष-संरेखित (लंबवत) विभाजन इस्तेमाल करते हैं: प्रत्येक प्रश्न यह पूछता है कि कोई एक फ़ीचर किसी सीमा से ऊपर है या नीचे (जैसे, आय <= 35?)। इससे द्वि-आयामी फ़ीचर स्थान में आयताकार निर्णय क्षेत्र बनते हैं। यह तरीका सरल और आसानी से समझने योग्य है, लेकिन यह तिरछी निर्णय सीमाओं को कुशलतापूर्वक प्रदर्शित नहीं कर सकता — उदाहरण के लिए, 45 डिग्री की रेखा के साथ दो वर्गों को अलग करने के लिए कई विभाजनों की आवश्यकता होती है। वृक्ष-समूह (रैंडम फ़ॉरेस्ट) कई वृक्षों को मिलाकर इस समस्या को दूर करते हैं; प्रत्येक वृक्ष में अलग अक्ष-संरेखित विभाजन होते हैं, जो मिलकर लगभग किसी भी सीमा-आकार को दर्शा सकते हैं।

import numpy as np

# Simulate finding a split on one feature
feature_values = np.array([10, 20, 30, 40, 50])
labels = np.array([0, 0, 0, 1, 1])

# For each possible threshold between consecutive values:
for threshold in [15, 25, 35, 45]:
    left_labels  = labels[feature_values <= threshold]
    right_labels = labels[feature_values > threshold]
    print(f'Threshold {threshold}: left={list(left_labels)}, right={list(right_labels)}')
# Threshold 35 gives perfect separation [0,0,0] vs [1,1]

स्किकिट-लर्न के साथ निर्णय वृक्ष को प्रशिक्षित करना

स्किकिट-लर्न का DecisionTreeClassifier एक ही बार fit() चलाने पर प्रशिक्षित हो जाता है। प्रमुख पैरामीटर में max_depth (वृक्ष की अधिकतम गहराई — अति-अनुरूपण को नियंत्रित करने के लिए अत्यंत महत्वपूर्ण), criterion (विभाजन की गुणवत्ता मापने का तरीका: 'gini' या 'entropy'), और min_samples_split (किसी नोड को विभाजित करने के लिए आवश्यक न्यूनतम नमूने — बहुत छोटे समूहों को विभाजित होने से रोकता है) शामिल हैं। फिट करने के तुरंत बाद वृक्ष predictions देने के लिए तैयार हो जाता है। KNN के विपरीत, prediction की जटिलता O(log N) होती है — केवल सीखी हुई शाखाओं का अनुसरण करना होता है — इसलिए prediction के समय निर्णय वृक्ष तेज़ होते हैं।

from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

tree = DecisionTreeClassifier(
    max_depth=3,
    criterion='gini',
    random_state=42
)
tree.fit(X_train, y_train)

print('Train accuracy:', tree.score(X_train, y_train).round(3))
print('Test  accuracy:', tree.score(X_test, y_test).round(3))
print('Tree depth:', tree.get_depth())
print('Number of leaves:', tree.get_n_leaves())

Prediction के पथ का अनुसरण करना

निर्णय वृक्षों की शक्ति यह है कि आप हर prediction को चरण-दर-चरण देख सकते हैं। decision_path() method एक विरल मैट्रिक्स लौटाता है, जो बताता है कि प्रत्येक नमूना किन नोड से होकर गुज़रा। apply() method प्रत्येक नमूने के लिए लीफ़ नोड का index लौटाता है। इन टूल की मदद से आप उपयोगकर्ता को ठीक-ठीक समझा सकते हैं कि कौन से प्रश्न पूछे गए और किन उत्तरों से prediction निकला — अनुपालन, डीबगिंग और गैर-तकनीकी हितधारकों का विश्वास बनाने के लिए यह आवश्यक है।

from sklearn.tree import DecisionTreeClassifier, export_text
from sklearn.datasets import load_iris

X, y = load_iris(return_X_y=True)
tree = DecisionTreeClassifier(max_depth=3, random_state=42)
tree.fit(X, y)

# Print human-readable decision rules
rules = export_text(tree, feature_names=load_iris().feature_names)
print(rules[:500])  # First 500 chars of the rule printout

# Which leaf does sample 0 land in?
leaf = tree.apply(X[[0]])
print('Sample 0 lands in leaf node:', leaf)

लीफ़ नोड पर वृक्ष predictions

प्रत्येक लीफ़ नोड में वहाँ तक पहुँचे प्रशिक्षण नमूनों का वर्ग वितरण संग्रहीत होता है। वर्गीकरण में predicted class, लीफ़ में सबसे अधिक संख्या वाले वर्ग के बराबर होता है। प्रायिकता के अनुमान के लिए predict_proba() लीफ़ में प्रत्येक वर्ग के नमूनों का अनुपात लौटाता है। 10 नमूनों वाली लीफ़ में यदि 9 नमूने वर्ग A और 1 नमूना वर्ग B का हो, तो class A की prediction probability 0.9 होगी। प्रति लीफ़ कम नमूनों वाले वृक्ष कम विश्वसनीय probability estimates देते हैं, इसलिए calibrated probability outputs के लिए min_samples_leaf जैसे regularisation parameters महत्वपूर्ण होते हैं।

from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
import numpy as np

X, y = load_iris(return_X_y=True)
tree = DecisionTreeClassifier(max_depth=3, random_state=42)
tree.fit(X, y)

# Predicted class and probabilities for first three samples
preds = tree.predict(X[:3])
probas = tree.predict_proba(X[:3])

for i in range(3):
    print(f'Sample {i}: class={preds[i]}, probabilities={probas[i].round(3)}')

प्रतिगमन के लिए निर्णय वृक्ष

DecisionTreeRegressor classifier की तरह ही काम करता है, लेकिन प्रत्येक लीफ़ में मौजूद प्रशिक्षण नमूनों का औसत target value predict करता है। विभाजन का criterion बदल जाता है: Gini अशुद्धता के बजाय, यह बनने वाले प्रत्येक child node के भीतर औसत वर्ग त्रुटि (या औसत निरपेक्ष त्रुटि) को न्यूनतम करता है। प्रतिगमन वृक्ष सीढ़ीनुमा predictions देते हैं — आयताकार क्षेत्रों के भीतर स्थिर मान। पर्याप्त गहराई होने पर वे किसी भी training data पर बिल्कुल फिट हो सकते हैं, लेकिन इससे गंभीर अति-अनुरूपण होता है। प्रतिगमन वृक्ष को regularise करने के लिए गहराई और min_samples_leaf नियंत्रित करें।

from sklearn.tree import DecisionTreeRegressor
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(0)
X = np.sort(5 * np.random.rand(80, 1), axis=0)
y = np.sin(X).ravel() + np.random.randn(80) * 0.3

for depth in [1, 3, 10]:
    reg = DecisionTreeRegressor(max_depth=depth)
    reg.fit(X, y)
    mse = np.mean((reg.predict(X) - y)**2)
    print(f'max_depth={depth}: train MSE={mse:.4f}')
# depth=10 nearly zero MSE (memorised training data)

निर्णय वृक्षों से फ़ीचर का महत्व

फिट करने के बाद, tree.feature_importances_ यह माप प्रदान करता है कि प्रत्येक फ़ीचर ने विभाजनों में कितना योगदान दिया। फ़ीचर का महत्व उस फ़ीचर से संबंधित अशुद्धता में हुई कुल कमी के रूप में निकाला जाता है, जिसे प्रत्येक विभाजन तक पहुँचने वाले नमूनों के अंश से भारित किया जाता है। सभी मानों का योग 1.0 होता है। सबसे महत्वपूर्ण फ़ीचर का score सबसे अधिक होता है। इससे यह पहचानने का तेज़ और आसानी से समझ आने वाला तरीका मिलता है कि कौन से inputs predictions को सबसे अधिक प्रभावित करते हैं — फ़ीचर चयन, व्यावसायिक अंतर्दृष्टि और संभावित डेटा समस्याओं का पता लगाने में यह उपयोगी है।

from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
import pandas as pd

X, y = load_iris(return_X_y=True)
feature_names = load_iris().feature_names

tree = DecisionTreeClassifier(max_depth=3, random_state=42)
tree.fit(X, y)

importances = pd.Series(tree.feature_importances_, index=feature_names)
print('Feature Importances:')
print(importances.sort_values(ascending=False))

स्केल से स्वतंत्रता: वृक्षों को स्केलिंग की आवश्यकता नहीं

निर्णय वृक्षों का एक प्रमुख व्यावहारिक लाभ यह है कि वे पूरी तरह स्केल-स्वतंत्र होते हैं। आय <= 50000 पर किया गया विभाजन और आय_हज़ार <= 50 पर किया गया विभाजन बिल्कुल समान वृक्ष संरचनाएँ बनाते हैं। किसी फ़ीचर के सभी मानों में 100 जोड़ने या उन्हें 1000 से गुणा करने पर चुने जाने वाले विभाजन नहीं बदलते। निर्णय वृक्ष से पहले आपको कभी भी StandardScaler या MinMaxScaler लागू करने की आवश्यकता नहीं होती। इसका अर्थ यह भी है कि निर्णय वृक्ष बिना किसी पूर्व-प्रसंस्करण के बहुत अलग-अलग स्केल वाले फ़ीचर संभाल लेते हैं, जिससे pipeline सरल हो जाती हैं।

from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
import numpy as np

X, y = load_iris(return_X_y=True)

# Without scaling
tree1 = DecisionTreeClassifier(random_state=42)
tree1.fit(X, y)

# With scaling (same result expected)
X_scaled = StandardScaler().fit_transform(X)
tree2 = DecisionTreeClassifier(random_state=42)
tree2.fit(X_scaled, y)

print('Without scaling accuracy:', tree1.score(X, y).round(3))
print('With scaling accuracy:   ', tree2.score(X_scaled, y).round(3))
# Identical -- scaling has no effect on tree splits

वृक्षों में लुप्त मानों को संभालना

निर्णय वृक्ष कई अन्य एल्गोरिदम की तुलना में लुप्त मानों को अधिक सहजता से संभालते हैं। स्किकिट-लर्न का DecisionTreeClassifier splitter='best' होने पर लुप्त मानों का मूल रूप से समर्थन करता है — विभाजन वाले फ़ीचर में लुप्त मानों वाले नमूने उस child को भेजे जाते हैं जहाँ लुप्त न होने वाले डेटा पर अशुद्धता न्यूनतम होती है। वैकल्पिक रूप से, आप surrogate splits का उपयोग कर सकते हैं: जब किसी नमूने के लिए प्राथमिक विभाजन वाला फ़ीचर लुप्त हो, तो उसके स्थान पर सहसंबंधित फ़ीचर इस्तेमाल किया जाता है। लुप्त डेटा के प्रति यह मजबूती, KNN जैसी दूरी-आधारित विधियों की तुलना में वृक्ष-आधारित मॉडलों का एक व्यावहारिक लाभ है, क्योंकि उन विधियों को पूर्ण फ़ीचर वेक्टर की आवश्यकता होती है।

from sklearn.tree import DecisionTreeClassifier
import numpy as np

# Tree can handle NaN values with missing_values support
# In scikit-learn >= 1.0, DecisionTreeClassifier accepts NaN
X = np.array([
    [1, 2], [np.nan, 3], [3, np.nan], [4, 5]
])
y = np.array([0, 1, 0, 1])

tree = DecisionTreeClassifier(random_state=42)
tree.fit(X, y)
preds = tree.predict(X)
print('Predictions with NaN features:', preds)
# Tree routes NaN samples gracefully

त्वरित जाँच

इस पाठ में बताए गए Python के साथ Machine Learning संबंधी concepts की अपनी समझ जाँचें।

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

इस पाठ में आपने सीखा: निर्णय वृक्ष अक्ष-संरेखित विभाजनों का उपयोग करके डेटा को पुनरावर्ती रूप से विभाजित करते हैं, प्रत्येक लीफ़ बहुमत-मत prediction के लिए वर्ग वितरण संग्रहीत करती है, और निर्णय वृक्ष स्केल से स्वतंत्र होते हैं तथा उन्हें फ़ीचर स्केलिंग की आवश्यकता नहीं होती। आगे हम Gini अशुद्धता और information_gain का अध्ययन करेंगे — ये वे criteria हैं जो प्रत्येक नोड पर चुने जाने वाले विभाजन को निर्धारित करते हैं।

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

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

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

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

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

क्या “ट्री बनाना: विभाजन, नोड और लीफ़” पाठ निःशुल्क है?

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

“ट्री बनाना: विभाजन, नोड और लीफ़” में मैं क्या सीखूँगा?

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

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

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

“ट्री बनाना: विभाजन, नोड और लीफ़” पाठ पूरा करने में कितना समय लगता है?

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

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

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

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

  1. ट्री बनाना: विभाजन, नोड और लीफ़
  2. Gini अशुद्धता और सूचना लाभ
  3. अधिक-फिटिंग रोकने के लिए ट्री की गहराई नियंत्रित करना
  4. निर्णय ट्री का दृश्यांकन और व्याख्या
← Machine Learning Academy पर वापस जाएँ