ในหน่วยนี้ คุณจะใช้คลัง YDF (Yggdrasil Decision Forest) เพื่อฝึกและตีความแผนผังการตัดสินใจ
หน่วยการเรียนรู้นี้ได้รับแรงบันดาลใจจากบทแนะนำ🧭การเริ่มต้นใช้งาน YDF
รอบคัดเลือก
ก่อนศึกษาชุดข้อมูล ให้ทําดังนี้
- สร้าง Colab Notebook ใหม่
- ติดตั้งไลบรารี YDF โดยวางและเรียกใช้บรรทัดโค้ดต่อไปนี้ในสมุดบันทึก Colab ใหม่
!pip install ydf -U
- นําเข้าไลบรารีต่อไปนี้
import ydf import numpy as np import pandas as pd
ชุดข้อมูลเพนกวินพาล์มเมอร์
Colab นี้ใช้ชุดข้อมูล Penguins ของ Palmer ซึ่งมีข้อมูลการวัดขนาดของนกเพนกวิน 3 สายพันธุ์ ดังนี้
- สายรัดคาง
- Gentoo
- Adelie
นี่เป็นปัญหาการจัดประเภท โดยมีเป้าหมายเพื่อคาดการณ์สายพันธุ์นกเพนกวินตามข้อมูลในชุดข้อมูลนกเพนกวินของ Palmer เพนกวินมีดังนี้
รูปที่ 16 นกเพนกวิน 3 สายพันธุ์ รูปภาพโดย @allisonhorst
โค้ดต่อไปนี้จะเรียกใช้ฟังก์ชัน pandas เพื่อโหลดชุดข้อมูล Palmer Penguins ลงในหน่วยความจํา
path = "https://storage.googleapis.com/download.tensorflow.org/data/palmer_penguins/penguins.csv"
dataset = pd.read_csv(path)
label = "species"
# Display the first 3 examples.
dataset.head(3)
ตารางต่อไปนี้จัดรูปแบบตัวอย่าง 3 รายการแรกในชุดข้อมูล Palmer Penguins
ตารางที่ 3 ตัวอย่าง 3 รายการแรกใน Palmer Penguins
ชนิดพันธุ์ | เกาะ | bill_length_mm | bill_depth_mm | flipper_length_mm | body_mass_g | เพศ | ปี | |
---|---|---|---|---|---|---|---|---|
0 | Adelie | Torgersen | 39.1 | 18.7 | 181.0 | 3750.0 | ชาย | 2007 |
1 | Adelie | Torgersen | 39.5 | 17.4 | 186.0 | 3800.0 | เป็นเพศหญิง | 2007 |
2 | Adelie | Torgersen | 40.3 | 18.0 | 195.0 | 3250.0 | เป็นเพศหญิง | 2007 |
ชุดข้อมูลแบบสมบูรณ์มีทั้งตัวเลข (เช่น bill_depth_mm
) หมวดหมู่ (เช่น island
) และฟีเจอร์ที่ขาดหายไป ต่างจากเครือข่ายประสาท Decision Forest รองรับประเภทฟีเจอร์เหล่านี้ทั้งหมดโดยกำเนิด คุณจึงไม่ต้องทำการเข้ารหัสแบบฮอตเวิร์ก การปรับให้เป็นมาตรฐาน หรือฟีเจอร์ is_present เพิ่มเติม
เซลล์โค้ดต่อไปนี้จะแยกชุดข้อมูลออกเป็นชุดการฝึกและชุดการทดสอบ
# Use the ~20% of the examples as the testing set
# and the remaining ~80% of the examples as the training set.
np.random.seed(1)
is_test = np.random.rand(len(dataset)) < 0.2
train_dataset = dataset[~is_test]
test_dataset = dataset[is_test]
print("Training examples: ", len(train_dataset))
# >> Training examples: 272
print("Testing examples: ", len(test_dataset))
# >> Testing examples: 72
การฝึกต้นไม้การตัดสินใจด้วยไฮเปอร์พารามิเตอร์เริ่มต้น
คุณสามารถฝึกต้นไม้การตัดสินใจต้นแรกด้วยอัลกอริทึมการเรียนรู้ CART (Classification and Regression Trees) (หรือที่เรียกว่าตัวเรียนรู้) โดยไม่ต้องระบุไฮเปอร์พารามิเตอร์ใดๆ
นั่นเป็นเพราะ ydf.CartLearner
learner ให้ค่าไฮเปอร์พารามิเตอร์เริ่มต้นที่ดี คุณจะได้ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีการทํางานของรูปแบบนี้ในภายหลัง
model = ydf.CartLearner(label=label).train(train_dataset)
การเรียกก่อนหน้านี้ไม่ได้ระบุคอลัมน์ที่จะใช้เป็นฟีเจอร์อินพุต ดังนั้น ระบบจะใช้ทุกคอลัมน์ในชุดการฝึก นอกจากนี้ การเรียกใช้ดังกล่าวไม่ได้ระบุความหมาย (เช่น ตัวเลข หมวดหมู่ ข้อความ) ของฟีเจอร์อินพุต ระบบจึงจะอนุมานความหมายขององค์ประกอบโดยอัตโนมัติ
เรียกใช้ model.plot_tree()
เพื่อแสดงแผนผังการตัดสินใจที่ได้
model.plot_tree()
ใน Colab คุณสามารถใช้เมาส์เพื่อแสดงรายละเอียดเกี่ยวกับองค์ประกอบที่เฉพาะเจาะจง เช่น การแจกแจงคลาสในแต่ละโหนด
รูปที่ 17 แผนผังการตัดสินใจที่ผ่านการฝึกด้วยไฮเปอร์พารามิเตอร์เริ่มต้น
Colab แสดงว่าเงื่อนไขรูทมีตัวอย่าง 243 รายการ อย่างไรก็ตาม คุณอาจจำได้ว่าชุดข้อมูลการฝึกอบรมมีตัวอย่าง 272 รายการ ระบบได้จองตัวอย่างที่เหลือ 29 รายการไว้โดยอัตโนมัติเพื่อใช้ตรวจสอบและตัดต้นไม้
เงื่อนไขแรกจะทดสอบค่าของ bill_depth_mm
ตารางที่ 4 และ 5 แสดงความเป็นไปได้ของสายพันธุ์ต่างๆ โดยขึ้นอยู่กับผลลัพธ์ของเงื่อนไขแรก
ตารางที่ 4 ความน่าจะเป็นที่จะมีสายพันธุ์อื่นหาก bill_depth_mm ≥
42.3
สายพันธุ์ | ความเป็นไปได้ |
---|---|
Adelie (สีแดง) | 8% |
Gentoo (สีน้ำเงิน) | 58% |
สายรัดคาง (สีเขียว) | 36% |
ตาราง 5 ความเป็นไปได้ที่จะมีสายพันธุ์อื่นหาก
bill_depth_mm < 42.3
สายพันธุ์ | ความเป็นไปได้ |
---|---|
Adelie (สีแดง) | 97% |
Gentoo (สีน้ำเงิน) | 2% |
สายรัดคาง (สีเขียว) | 0% |
bill_depth_mm
เป็นองค์ประกอบตัวเลข ดังนั้น ระบบจึงพบค่า 42.3 โดยใช้อัลกอริทึมการแยกที่แน่นอนสำหรับการแยกประเภทแบบ 2 กลุ่มด้วยฟีเจอร์ที่เป็นตัวเลข
หาก bill_depth_mm ≥ 42.3
เป็น True ให้ทดสอบเพิ่มเติมว่า flipper_length_mm ≥ 207.5
แยก Gentoos ออกจาก Gentoos+Adelie ได้เกือบสมบูรณ์แบบหรือไม่
โค้ดต่อไปนี้แสดงความแม่นยำของการฝึกอบรมและทดสอบของโมเดล
train_evaluation = model.evaluate(train_dataset)
print("train accuracy:", train_evaluation.accuracy)
# >> train accuracy: 0.9338
test_evaluation = model.evaluate(test_dataset)
print("test accuracy:", test_evaluation.accuracy)
# >> test accuracy: 0.9167
ความแม่นยำในการทดสอบสูงกว่าความแม่นยำในการฝึกนั้นเกิดขึ้นได้น้อย แต่ก็เป็นไปได้ ในกรณีนี้ ชุดทดสอบอาจแตกต่างจากชุดการฝึก แต่ในกรณีนี้ ไม่ได้เป็นเช่นนั้น เนื่องจากมีการแบ่งกลุ่มทดสอบและกลุ่มควบคุมแบบสุ่ม คำอธิบายที่เป็นไปได้มากกว่าคือชุดข้อมูลทดสอบมีขนาดเล็กมาก (มีเพียง 72 ตัวอย่าง) การประมาณความแม่นยำจึงมีความคลาดเคลื่อน
ในทางปฏิบัติแล้ว สําหรับชุดข้อมูลขนาดเล็กเช่นนี้ เราขอแนะนําให้ใช้การทดสอบไขว้ เนื่องจากจะคํานวณค่าเมตริกการประเมินที่แม่นยํากว่า อย่างไรก็ตาม ในตัวอย่างนี้ เราจะฝึกและทดสอบต่อเพื่อความเรียบง่าย
การปรับปรุงไฮเปอร์พารามิเตอร์ของโมเดล
โมเดลนี้เป็นต้นไม้การตัดสินใจเดียวที่ผ่านการฝึกด้วยค่าไฮเปอร์พารามิเตอร์เริ่มต้น หากต้องการการคาดการณ์ที่ดีขึ้น คุณสามารถทำสิ่งต่อไปนี้
ใช้เครื่องมือเรียนรู้ที่มีประสิทธิภาพมากขึ้น เช่น Random Forest หรือGradient Boosted Trees เราจะอธิบายอัลกอริทึมการเรียนรู้เหล่านั้นในหน้าถัดไป
เพิ่มประสิทธิภาพไฮเปอร์พารามิเตอร์โดยใช้การสังเกตและการคาดคะเน คู่มือการปรับปรุงโมเดลอาจมีประโยชน์
ใช้การปรับแต่งไฮเปอร์พารามิเตอร์เพื่อทดสอบไฮเปอร์พารามิเตอร์ที่เป็นไปได้จํานวนมากโดยอัตโนมัติ
เนื่องจากเรายังไม่เห็นอัลกอริทึมของ Random Forest และ Gradient Boosted Trees และเนื่องจากจำนวนตัวอย่างมีน้อยเกินไปที่จะทำการปรับแต่งไฮเปอร์พารามิเตอร์โดยอัตโนมัติ คุณจึงต้องปรับปรุงโมเดลด้วยตนเอง
แผนภูมิการตัดสินใจที่แสดงด้านบนมีขนาดเล็ก และใบที่มีตัวอย่าง 61 รายการมีป้ายกำกับ Adelie และ Chinstrap ผสมกัน เหตุใดอัลกอริทึมจึงไม่แบ่งกลุ่มใบไม้นี้ย่อยลงไปอีก มีสาเหตุที่เป็นไปได้สองข้อ:
- อาจมีจำนวนตัวอย่างขั้นต่ำต่อใบ (
min_examples=5
โดยค่าเริ่มต้น) แล้ว - ระบบอาจแยกและตัดต้นไม้ออกเพื่อป้องกันการพอดีมากเกินไป
ลดจำนวนตัวอย่างขั้นต่ำเป็น 1 และดูผลลัพธ์
model = ydf.CartLearner(label=label, min_examples=1).train(train_dataset)
model.plot_tree()
รูปที่ 18 แผนผังการตัดสินใจที่ผ่านการฝึกด้วย min_examples=1
โหนดใบที่มี 61 ตัวอย่างได้รับการแบ่งย่อยเพิ่มเติมหลายครั้ง
หากต้องการดูว่าการแยกโหนดเพิ่มเติมมีประโยชน์หรือไม่ เราจะประเมินคุณภาพของรูปแบบใหม่นี้ในชุดข้อมูลทดสอบ ดังนี้
print(model.evaluate(test_dataset).accuracy)
# >> 0.97222
คุณภาพของโมเดลเพิ่มขึ้นเมื่อความแม่นยำในการทดสอบเพิ่มขึ้นจาก 0.9167 เป็น 0.97222 การเปลี่ยนแปลงไฮเปอร์พารามิเตอร์นี้ถือเป็นแนวคิดที่ดี
ก่อนหน้านี้ของป่าการตัดสินใจ
การปรับปรุงไฮเปอร์พารามิเตอร์อย่างต่อเนื่องอาจช่วยให้เราบรรลุความแม่นยำที่สมบูรณ์แบบ อย่างไรก็ตาม เราฝึกโมเดลที่มีประสิทธิภาพมากขึ้น เช่น Random Forest และดูว่าได้ผลลัพธ์ที่ดีกว่าไหมแทนที่จะทำด้วยตนเอง
model = ydf.RandomForestLearner(label=label).train(train_dataset)
print("Test accuracy: ", model.evaluate(test_dataset).accuracy)
# >> Test accuracy: 0.986111
ความแม่นยำของ Random Forest ดีกว่าต้นไม้แบบง่าย คุณจะได้ทราบเหตุผลในหน้าถัดไป
การใช้งานและข้อจํากัด
ดังที่ได้กล่าวไว้ก่อนหน้านี้ ต้นไม้การตัดสินใจเดี่ยวมักมีคุณภาพต่ำกว่าวิธีการแมชชีนเลิร์นนิงสมัยใหม่ เช่น Random Forest, Gradient Boosted Tree และโครงข่ายประสาท อย่างไรก็ตาม แผนผังการตัดสินใจยังคงมีประโยชน์ในกรณีต่อไปนี้
- เป็นฐานข้อมูลที่ง่ายและไม่แพงสําหรับประเมินแนวทางที่ซับซ้อนมากขึ้น
- เมื่อมีการเลือกระหว่างคุณภาพของโมเดลกับความสามารถในการตีความ
- เพื่อเป็นตัวแทนในการตีความโมเดลป่าการตัดสินใจ ซึ่งหลักสูตรจะกล่าวถึงในภายหลัง