ml/ library Learn by doing
ALGORITHM 52 · PYTHON / JAVASCRIPT

Random Forest

รวมต้นไม้ที่เห็นข้อมูลและ feature ต่างกัน

LEARNING LEVEL3
ผสานหลายแนวคิดควรรู้มาก่อน · Decision Tree และ Bagging
ลองใน Playground

01Overall Concept

OVERALL CONCEPT

ไอเดียหลัก — Random Forest คือป่าที่มี Decision Tree จำนวนมาก แต่ละต้นได้เห็นข้อมูลและ feature ต่างกันเล็กน้อย แล้วรวมคำตอบด้วยการโหวตหรือเฉลี่ย ความแตกต่างของต้นไม้ช่วยให้ป่าทั้งป่าทำนายได้มั่นคงกว่าต้นไม้ต้นเดียว

ลองนึกภาพว่า — เหมือนคณะกรรมการที่แต่ละคนได้อ่านเอกสารคนละส่วนและตั้งคำถามคนละแบบ ถ้าคนหนึ่งเข้าใจผิด คนอื่นยังช่วยแก้ด้วยเสียงส่วนใหญ่ได้

ตัวอย่างการนำไปใช้ — ตรวจจับธุรกรรมผิดปกติ ประเมินความเสี่ยงจากข้อมูลตาราง พยากรณ์ยอดขาย หรือใช้เป็นโมเดลตั้งต้นที่แข็งแรง

02อธิบายภาษาคนเข้าใจง่ายๆ

เล่าแบบไม่ใช้ศัพท์ยาก

Random Forest คือหนึ่งในเทคนิค Machine Learning คลาสสิกที่ใช้งานจริงได้ดีมาก

มันเอาแนวคิด Bagging มาใช้กับ Decision Tree

สมมติเราสร้างต้นไม้ 500 ต้น

แต่ละต้นไม่ได้เห็นข้อมูลเหมือนกันทั้งหมด และตอนเลือกคำถามที่จะแตกกิ่งก็ไม่ได้เห็นตัวแปรทั้งหมด

ต้นหนึ่งอาจสนใจ

รายได้ + อายุ + จำนวนการซื้อ

อีกต้นอาจสนใจ

พื้นที่ + จำนวนการเข้าเว็บ + ประเภทสมาชิก

ผลคือเราจะได้ต้นไม้ที่ “มีความเห็นแตกต่างกัน”

จากนั้นให้ทั้งหมดโหวต

นี่สำคัญ เพราะถ้าต้นไม้ 500 ต้นเหมือนกันหมด การมี 500 ต้นก็ไม่ได้ช่วยอะไร

Random Forest จึงตั้งใจสร้าง ความหลากหลาย

ข้อดีคือมักทำงานดีโดยไม่ต้องปรับอะไรมาก รับมือกับข้อมูลหลายรูปแบบได้ และไม่ Overfit ง่ายเท่า Decision Tree เดี่ยว

ยังสามารถดู Feature Importance คร่าวๆ ได้ด้วยว่าอะไรมีบทบาทกับการตัดสินใจ

ข้อเสียคืออธิบายยากกว่า Tree ตัวเดียว เพราะแทนที่จะอ่าน Flowchart ต้นเดียว เรามีต้นไม้หลายร้อยต้น

ภาพจำ: ป่าที่มีต้นไม้หลายต้น แต่ละต้นคิดต่างกัน แล้วเสียงส่วนใหญ่เป็นคำตอบสุดท้าย

03How it works

ค่อยๆ ทำไปด้วยกัน ตั้งแต่ข้อมูลแถวแรกจนถึงการตรวจคำตอบ

  1. เริ่มจากตารางซื้อซ้ำ

    X เป็นประวัติการซื้อและพฤติกรรมที่รู้ก่อนช่วงเป้าหมาย y เป็นซื้อซ้ำ/ไม่ซื้อซ้ำ แบ่ง train/test ก่อนและแปลงหมวดหมู่ให้เหมาะสม ต้นไม้โดยทั่วไปไม่ต้องปรับสเกลตัวเลขแบบ kNN แต่ต้องใช้คอลัมน์และวิธีแปลงเดียวกันตอนรับลูกค้าใหม่

  2. สุ่มสองชั้นเพื่อให้ต้นไม้คิดต่าง

    ชั้นแรกสุ่มแถวจาก train แบบ bootstrap ให้แต่ละต้น ชั้นที่สองคือทุกครั้งที่จะแตกกิ่ง จะสุ่ม feature บางส่วนมาเป็นผู้สมัคร แล้วหาคำถามที่ดีที่สุดในชุดนั้น ต้นหนึ่งจึงอาจถามเรื่องความถี่ อีกต้นถามยอดใช้จ่าย แม้เรียนเรื่องซื้อซ้ำเหมือนกัน

  3. แต่ละต้นส่งความเห็นกลับมารวม

    หลังฝึก ลูกค้าใหม่เดินผ่านต้นไม้ทุกต้น แต่ละต้นให้สัดส่วนคลาสจากใบที่ไปถึง RandomForestClassifier เฉลี่ย probability เหล่านี้แล้วเลือกคลาสสูงสุด จึงไม่ควรตีความ probability=0.76 ว่า “76 จาก 100 ต้นโหวต” เสมอไป ส่วน RandomForestRegressor ใช้ค่าเฉลี่ยตัวเลขจากต้นไม้

  4. เริ่มจากป่าขนาดพอดี

    ใช้ RandomForestClassifier(n_estimators=100, max_depth=6, min_samples_leaf=3, max_features='sqrt', random_state=42) แล้ว fit(X_train, y_train) จำนวนต้นช่วยให้ผลรวมเสถียร max_depth และ min_samples_leaf คุมความละเอียดของแต่ละต้น ส่วน max_features คุมตัวเลือกคำถามที่สุ่มในแต่ละจุด ไม่ใช่เลือกคอลัมน์ครั้งเดียวทั้งป่า

  5. ทดสอบและดูสิ่งที่โมเดลพึ่งพา

    วัด confusion matrix หรือ precision/recall บน test ลองปรับ max_depth กับ min_samples_leaf จาก validation ก่อนเพิ่มต้นไม้เรื่อยๆ ค่า feature_importances_ ช่วยดูภาพรวมได้แต่มีอคติได้ จึงลอง permutation importance บนข้อมูลกันไว้ประกอบ อย่าอ่านความสำคัญว่าเป็นเหตุและผล และเทียบคะแนนกับต้นไม้เดี่ยวเพื่อดูว่าความซับซ้อนที่เพิ่มมาคุ้มไหม

เปิดตัวอย่างโค้ดเพื่อลองทำตาม →ตัวอย่างตัวเลขในเรื่องใช้ช่วยอธิบาย ส่วนโค้ดและ Playground ใช้ชุดข้อมูลสาธิตของแต่ละหน้าอ่านเอกสารอ้างอิงของเทคนิคนี้ ↗

ข้อมูล พารามิเตอร์ และภาพรวมการคำนวณ

DATA INX · featuresy · targetX = ประวัติลูกค้าก่อนช่วงเป้าหมาย · y = ซื้อซ้ำ / ไม่ซื้อซ้ำ
CALCULATERandom Forest
n_estimatorsmax_depthmax_features
RESULT0.800.150.05class / probabilityเฉลี่ย probability จากใบของทุกต้น → เลือกคลาสสูงสุด
เส้นทางของข้อมูล: จากค่าที่รับเข้า ผ่านการคำนวณด้วยพารามิเตอร์ ไปเป็นผลลัพธ์
INPUT

ข้อมูลที่รับเข้ามา

รับ X เป็นตาราง feature และ y เป็นคลาสหรือค่าต่อเนื่อง รองรับข้อมูลตารางหลายคอลัมน์โดยไม่ต้องสร้างความสัมพันธ์เอง

X = ประวัติลูกค้าก่อนช่วงเป้าหมาย · y = ซื้อซ้ำ / ไม่ซื้อซ้ำ
PARAMETERS

พารามิเตอร์ที่ใช้

n_estimators
จำนวนต้นไม้ในป่า
max_depth
ความลึกสูงสุดของต้นไม้แต่ละต้น
max_features
จำนวน feature สุ่มที่ต้นไม้ลองในแต่ละ split
OUTPUT

ผลลัพธ์ที่ได้

ได้คำทำนายรวม probability และ feature importance โดยประมาณจากการแบ่งของต้นไม้ทั้งหมด

เฉลี่ย probability จากใบของทุกต้น → เลือกคลาสสูงสุด
CALCULATION

คำนวณทีละขั้น

  1. 01

    สร้าง bootstrap sample แยกให้ต้นไม้ทุกต้น

  2. 02

    ในแต่ละ node สุ่ม feature บางส่วน แล้วเลือก threshold ที่ลด impurity ดีที่สุดในชุดนั้น

  3. 03

    RandomForestClassifier เฉลี่ย probability จากทุกต้นและเลือกคลาสสูงสุด ส่วน Regressor เฉลี่ยตัวเลข

ควรรู้อีกนิด — โมเดลใหญ่และอธิบายยากกว่าต้นไม้เดี่ยว การอนุมานนอกช่วงข้อมูลยังไม่ดีสำหรับ regression

04Make it yours

Python · scikit-learn
# ติดตั้ง: pip install numpy scikit-learn matplotlibfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.metrics import accuracy_score from sklearn.datasets import make_classificationfrom sklearn.model_selection import train_test_split X, y = make_classification(    n_samples=150, n_features=2, n_redundant=0,    n_informative=2, n_classes=3, n_clusters_per_class=1,    class_sep=1.4, random_state=42,)X_train, X_test, y_train, y_test = train_test_split(    X, y, test_size=0.2, random_state=42, stratify=y) model = RandomForestClassifier(n_estimators=100, max_depth=4, random_state=42)model.fit(X_train, y_train)pred = model.predict(X_test)print("Accuracy:", accuracy_score(y_test, pred))

โค้ดเปลี่ยนตามค่าที่เลือกใน Playground · แต่ละภาษาใช้ข้อมูลตัวอย่างตามที่ระบุในโค้ด

05Learn by playing

ปรับ max_depth แล้วสังเกตรูปแบบคำทำนายและตัวชี้วัดที่คำนวณใหม่ทันที

Sample dataset / Three classes● คำนวณใหม่เมื่อปรับค่า
ต้นไม้ลึกขึ้นจับรายละเอียดมากขึ้นและอาจ overfit
พื้นที่สีคือคำทำนาย จุดคือคำตอบจริงFeature x → · Feature y ↑ · ขอบเข้ม = ชุดทดสอบ
Test accuracy96.7%
ลักษณะการรวมเสียงข้างมาก
พารามิเตอร์ที่ลอง4

Playground เป็น implementation เพื่อการเรียนรู้ที่คำนวณในเบราว์เซอร์ ส่วนโค้ด Python ใช้ scikit-learn จึงอาจให้ค่าต่างกันเล็กน้อยจากรายละเอียดการ optimize และค่าเริ่มต้นของไลบรารี ผลนี้ไม่ใช่ benchmark บนข้อมูลจริง