การสร้างต้นไม้: การแบ่ง โหนด และใบ
ผู้เรียนจะติดตามว่าต้นไม้ตัดสินใจแบ่งพาร์ทิชันข้อมูลแบบเวียนเกิดที่แต่ละโหนดอย่างไรตั้งแต่รากถึงใบ และสร้างการพยากรณ์ด้วยการเดินตามกิ่ง
การสร้างต้นไม้: การแบ่ง โหนด และใบ เป็นบทเรียน Machine Learning Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 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')โหนด กิ่ง และใบ
ต้นไม้ตัดสินใจมีองค์ประกอบสามประเภท: โหนดราก (คำถามแรกที่ถาม — การแบ่งที่ให้ข้อมูลมากที่สุดของชุดข้อมูลทั้งหมด), โหนดภายใน (คำถามระหว่างทางที่แบ่งกลุ่มย่อยของข้อมูลต่อไป) และ โหนดใบ (โหนดปลายทางที่เก็บค่าทำนาย) โหนดภายในแต่ละโหนดจะแบ่งข้อมูลออกเป็นกลุ่มย่อยอย่างน้อยสองกลุ่มตามค่าเกณฑ์ของคุณลักษณะ ความลึกของต้นไม้คือความยาวของเส้นทางที่ยาวที่สุดจากรากไปยังใบใด ๆ ต้นไม้ที่ลึกกว่าสามารถแทนรูปแบบที่ซับซ้อนได้มากขึ้น แต่มีแนวโน้มเกิดการเรียนรู้เกินกว่าข้อมูลจริงมากกว่า
# 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 หรือค่าข้อมูลที่ได้รับ) ใช้การแบ่งนั้น แล้วทำซ้ำกระบวนการแบบวนซ้ำกับกลุ่มย่อยแต่ละกลุ่มที่เกิดขึ้น กระบวนการนี้ดำเนินต่อไปจนกว่าจะเป็นไปตามเกณฑ์หยุด เช่น ถึงความลึกสูงสุด จำนวนตัวอย่างขั้นต่ำต่อโหนด หรือไม่มีการแบ่งที่มีประโยชน์เหลืออยู่ คำว่า “ละโมบ” หมายถึงการเลือกการแบ่งที่ดีที่สุดเฉพาะหน้าในแต่ละขั้นตอน โดยไม่ย้อนกลับไปแก้ไข การทำเช่นนี้อาจพลาดการแบ่งที่ดีที่สุดในภาพรวม แต่ทำให้อัลกอริทึมสามารถคำนวณได้จริง
# 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)
}การแบ่งตามแกน: ค่าเกณฑ์บนคุณลักษณะเดียว
ต้นไม้ตัดสินใจใน scikit-learn ใช้ การแบ่งตามแกน (ตั้งฉากกับแกน) เสมอ กล่าวคือ แต่ละคำถามจะตรวจสอบว่าคุณลักษณะหนึ่งมีค่าสูงกว่าหรือต่ำกว่าเกณฑ์หรือไม่ (เช่น อายุ <= 35?) วิธีนี้สร้างขอบเขตการตัดสินใจเป็นรูปสี่เหลี่ยมในปริภูมิคุณลักษณะ 2 มิติ แม้แนวทางนี้จะเรียบง่ายและตีความได้ แต่ ไม่สามารถแทนขอบเขตการตัดสินใจแนวทแยงได้อย่างมีประสิทธิภาพ ตัวอย่างเช่น การแยกสองคลาสตามเส้นมุม 45 องศาต้องใช้การแบ่งหลายครั้ง กลุ่มต้นไม้ (Random Forests) แก้ปัญหานี้ด้วยการรวมต้นไม้จำนวนมาก โดยแต่ละต้นใช้การแบ่งตามแกนที่แตกต่างกัน ซึ่งเมื่อรวมกันแล้วสามารถประมาณรูปร่างของขอบเขตได้แทบทุกแบบ
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]การฝึกต้นไม้ตัดสินใจด้วย scikit-learn
DecisionTreeClassifier ของ scikit-learn ฝึกได้ด้วยการเรียก fit() เพียงครั้งเดียว พารามิเตอร์สำคัญได้แก่ max_depth (ความลึกสูงสุดของต้นไม้ ซึ่งสำคัญต่อการควบคุมการฟิตเกิน), criterion (เกณฑ์วัดคุณภาพการแบ่ง: 'gini' หรือ 'entropy') และ min_samples_split (จำนวนตัวอย่างขั้นต่ำสำหรับการแบ่งโหนด ซึ่งช่วยป้องกันการแบ่งกลุ่มขนาดเล็กเกินไป) ต้นไม้พร้อมสำหรับการทำนายทันทีหลังการฝึก ต่างจาก KNN การทำนายมีความซับซ้อน O(log N) เพียงเดินตามกิ่งที่เรียนรู้ไว้ จึงทำให้ต้นไม้ตัดสินใจทำนายได้รวดเร็ว
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())การติดตามเส้นทางการทำนาย
จุดเด่นของต้นไม้ตัดสินใจคือ คุณสามารถ ติดตามทุกขั้นตอนของการทำนายได้ทีละขั้น เมธอด decision_path() จะคืนเมทริกซ์แบบเบาบางที่ระบุว่าแต่ละตัวอย่างผ่านโหนดใดบ้าง เมธอด apply() จะคืนดัชนีโหนดใบสำหรับแต่ละตัวอย่าง เครื่องมือเหล่านี้ช่วยให้คุณอธิบายแก่ผู้ใช้ได้อย่างชัดเจนว่าระบบถามคำถามใดบ้าง และคำตอบใดนำไปสู่การทำนาย ซึ่งจำเป็นต่อการปฏิบัติตามข้อกำหนด การแก้ไขข้อบกพร่อง และการสร้างความไว้วางใจกับผู้มีส่วนได้ส่วนเสียที่ไม่ใช่ผู้เชี่ยวชาญด้านเทคนิค
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)การทำนายของต้นไม้ที่โหนดใบ
โหนดใบแต่ละโหนดเก็บ การกระจายของคลาส จากตัวอย่างฝึกที่มาถึงโหนดนั้น สำหรับการจำแนกคลาสที่ทำนายคือคลาสส่วนใหญ่ในโหนดใบ สำหรับการประมาณความน่าจะเป็น predict_proba() จะคืนสัดส่วนของแต่ละคลาสในโหนดใบ หากโหนดใบมีตัวอย่าง 10 รายการ โดยเป็นคลาส A 9 รายการและคลาส B 1 รายการ ระบบจะทำนายเป็นคลาส A ด้วยความน่าจะเป็น 0.9 ต้นไม้ที่มีตัวอย่างต่อโหนดใบน้อยกว่าจะให้ค่าประมาณความน่าจะเป็นที่ไม่น่าเชื่อถือนัก นี่คือเหตุผลที่พารามิเตอร์การทำให้เป็นระเบียบ เช่น min_samples_leaf มีความสำคัญต่อผลลัพธ์ความน่าจะเป็นที่ปรับเทียบแล้ว
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 ทำงานเช่นเดียวกับตัวจำแนก แต่ทำนาย ค่าเป้าหมายเฉลี่ย ของตัวอย่างฝึกในแต่ละโหนดใบ เกณฑ์การแบ่งจะเปลี่ยนไป โดยแทนที่จะใช้ความไม่บริสุทธิ์แบบ Gini จะลด ค่าคลาดเคลื่อนกำลังสองเฉลี่ย (หรือค่าคลาดเคลื่อนสัมบูรณ์เฉลี่ย) ภายในโหนดลูกแต่ละโหนดที่เกิดขึ้น ต้นไม้ถดถอยให้ผลการทำนายเป็นฟังก์ชันขั้นบันได กล่าวคือมีค่าคงที่ภายในบริเวณรูปสี่เหลี่ยม หากมีความลึกเพียงพอ ต้นไม้จะฟิตข้อมูลฝึกได้พอดีทุกจุด แต่จะทำให้เกิดการฟิตเกินอย่างรุนแรง ควบคุมความลึกและ 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_ จะให้ค่าที่วัดว่าคุณลักษณะแต่ละรายการมีส่วนต่อการแบ่งมากเพียงใด ความสำคัญของคุณลักษณะคำนวณจากการลดความไม่บริสุทธิ์ทั้งหมด (Gini หรือ entropy) ที่เป็นผลจากคุณลักษณะแต่ละรายการ โดยถ่วงน้ำหนักตามสัดส่วนของตัวอย่างที่มาถึงการแบ่งแต่ละครั้ง ค่าทั้งหมดรวมกันได้ 1.0 คุณลักษณะที่สำคัญที่สุดจะได้คะแนนสูงสุด วิธีนี้เป็นวิธีที่รวดเร็วและตีความได้ในการระบุว่าข้อมูลนำเข้าใดมีอิทธิพลต่อการทำนายมากที่สุด เหมาะสำหรับการคัดเลือกคุณลักษณะ การทำความเข้าใจธุรกิจ และการตรวจหาปัญหาที่อาจเกิดขึ้นกับข้อมูล
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 ก่อนสร้างต้นไม้ตัดสินใจ นอกจากนี้ ต้นไม้ตัดสินใจยังรองรับคุณลักษณะที่มีมาตราส่วนแตกต่างกันอย่างมากได้โดยไม่ต้องประมวลผลล่วงหน้า ทำให้กระบวนการทำงานซับซ้อนน้อยลง
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 ของ scikit-learn รองรับค่าที่หายไปโดยตรงเมื่อ splitter='best' โดยตัวอย่างที่มีค่าหายไปในคุณลักษณะที่ใช้แบ่งจะถูกส่งไปยังโหนดลูกที่ทำให้ความไม่บริสุทธิ์ของข้อมูลที่ไม่หายไปต่ำที่สุด อีกทางเลือกหนึ่งคือใช้การแบ่งทดแทน เมื่อคุณลักษณะที่ใช้แบ่งหลักมีค่าหายไปสำหรับตัวอย่างหนึ่ง ระบบจะใช้คุณลักษณะที่มีความสัมพันธ์กันแทน ความทนทานต่อข้อมูลที่หายไปนี้เป็นข้อได้เปรียบเชิงปฏิบัติประการหนึ่งของแบบจำลองที่ใช้ต้นไม้ เมื่อเทียบกับวิธีที่อาศัยระยะทาง เช่น 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 จากบทเรียนนี้
สรุปบทเรียน
ในบทเรียนนี้ คุณได้เรียนรู้ วิธีที่ต้นไม้ตัดสินใจแบ่งข้อมูลซ้ำตามลำดับโดยใช้การแบ่งตามแกน โหนดใบแต่ละโหนดจะเก็บการกระจายของคลาสเพื่อใช้ทำนายด้วยเสียงข้างมาก และ ต้นไม้ตัดสินใจไม่ขึ้นกับมาตราส่วน จึงไม่จำเป็นต้องปรับมาตราส่วนของคุณลักษณะ ต่อไปเราจะศึกษาเรื่องความไม่บริสุทธิ์แบบ Gini และ information gain ซึ่งเป็นเกณฑ์ที่ใช้กำหนดว่าจะเลือกการแบ่งใดในแต่ละโหนด
เรียนรู้ Python ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 30
- บทเรียน
- 120
คำถามที่พบบ่อย
บทเรียน “การสร้างต้นไม้: การแบ่ง โหนด และใบ” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การสร้างต้นไม้: การแบ่ง โหนด และใบ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Machine Learning Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Machine Learning Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การสร้างต้นไม้: การแบ่ง โหนด และใบ”
ผู้เรียนจะติดตามว่าต้นไม้ตัดสินใจแบ่งพาร์ทิชันข้อมูลแบบเวียนเกิดที่แต่ละโหนดอย่างไรตั้งแต่รากถึงใบ และสร้างการพยากรณ์ด้วยการเดินตามกิ่ง คุณปฏิบัติ Machine Learning Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Machine Learning Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Machine Learning Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “การสร้างต้นไม้: การแบ่ง โหนด และใบ” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Machine Learning Academy นี้ได้ไหม
ได้ บทเรียน Machine Learning Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การสร้างต้นไม้: การแบ่ง โหนด และใบ
- ความไม่บริสุทธิ์แบบ Gini และกำไรสารสนเทศ
- การควบคุมความลึกของต้นไม้เพื่อป้องกันการปรับมากเกินไป
- การแสดงภาพและแปลความหมายต้นไม้ตัดสินใจ