การสร้างแผนผังการตัดสินใจ

ในหน่วยนี้ คุณจะใช้การฝึกไลบรารี YDF (Yggdrasil Decision Forest) และตีความแผนผังการตัดสินใจ

หน่วยนี้ได้รับแรงบันดาลใจจากบทแนะนำ🧭 YDF เริ่มต้นใช้งาน

รอบคัดเลือก

ก่อนศึกษาชุดข้อมูล ให้ทำดังนี้

  1. สร้างสมุดบันทึก Colab ใหม่
  2. ติดตั้งไลบรารี YDF โดยการวางและเรียกใช้โค้ดบรรทัดต่อไปนี้ใน Colab Notebook เครื่องใหม่
    !pip install ydf -U
    
  3. นำเข้าไลบรารีต่อไปนี้
    import ydf
    import numpy as np
    import pandas as pd
    

ชุดข้อมูลของเพนกวินพาลเมอร์

Colab นี้ใช้ชุดข้อมูล Palmer Penguins ซึ่งมีหน่วยวัดขนาดสำหรับเพนกวิน 3 สายพันธุ์ ดังนี้

  • ชินสแตรป
  • เจนทู
  • อดิลี

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

เพนกวิน 3 สายพันธุ์

รูปที่ 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 ตัวอย่างแรกในเพนกวินพาลเมอร์

ชนิดพันธุ์ เกาะ bill_length_mm bill_depth_mm flipper_length_mm body_mass_g เพศ ปี
0 อดิลี ทอร์เกอร์เซิน 39.1 18.7 181.0 3,750.0 ชาย 2007
1 อดิลี ทอร์เกอร์เซิน 39.5 17.4 186.0 3,800.0 เป็นเพศหญิง 2007
2 อดิลี ทอร์เกอร์เซิน 40.3 18.0 195.0 3,250.0 เป็นเพศหญิง 2007

ชุดข้อมูลทั้งชุดประกอบด้วยข้อมูลตัวเลขผสมกัน (เช่น bill_depth_mm) เชิงหมวดหมู่ (เช่น island) และฟีเจอร์ที่ขาดหายไป ฟอเรสต์การตัดสินใจรองรับฟีเจอร์ทุกประเภทเหล่านี้โดยค่าเริ่มต้น ซึ่งต่างจากโครงข่ายประสาท คุณจึงไม่ต้องทำการเข้ารหัสแบบใช้ครั้งเดียว การปรับให้เป็นรูปแบบมาตรฐาน หรือใช้ฟีเจอร์ 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 (การแยกประเภทและต้นไม้ถดถอย) (หรือที่เรียกว่าผู้เรียน) โดยไม่ต้องระบุไฮเปอร์พารามิเตอร์ใดๆ เนื่องจากผู้เรียน ydf.CartLearner ให้ค่า hyperparameter เริ่มต้นที่ดี คุณจะได้ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีการทำงานของโมเดลประเภทนี้ ภายหลังในหลักสูตรนี้

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%
Chinstrap (สีเขียว) 36%

 

ตารางที่ 5. ความเป็นไปได้ของสปีชีส์ต่างๆ หาก bill_depth_mm < 42.3

สายพันธุ์ ความเป็นไปได้
Adelie (สีแดง) 97%
Gentoo (สีน้ำเงิน) 2%
Chinstrap (สีเขียว) 0%

bill_depth_mm เป็นฟีเจอร์ตัวเลข ดังนั้นจึงพบค่า 42.3 โดยใช้อัลกอริทึมการแยกที่ตรงกับการจัดประเภทแบบไบนารีด้วยฟีเจอร์ตัวเลข

หาก bill_depth_mm ≥ 42.3 เป็นจริง ให้ทดสอบเพิ่มเติมว่า 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 ตัวอย่าง) การประมาณความแม่นยำจึงไม่ค่อยชัด

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

การปรับปรุงไฮเปอร์พารามิเตอร์ของโมเดล

โมเดลนี้เป็นต้นไม้การตัดสินใจเดียวได้รับการฝึกด้วยค่าไฮเปอร์พารามิเตอร์ที่เป็นค่าเริ่มต้น หากต้องการรับการคาดการณ์ที่ดียิ่งขึ้น คุณดำเนินการต่อไปนี้ได้

  1. ใช้ตัวเรียนรู้ที่มีประสิทธิภาพมากขึ้น เช่น ป่าแบบสุ่มหรือโมเดลต้นไม้ที่เร่งระดับแบบไล่ระดับ เราจะอธิบายอัลกอริทึมการเรียนรู้ดังกล่าวในหน้าถัดไป

  2. เพิ่มประสิทธิภาพไฮเปอร์พารามิเตอร์โดยใช้การสังเกตการณ์และการสังเกต คู่มือการปรับปรุงโมเดลอาจเป็นประโยชน์

  3. ใช้การปรับแต่งไฮเปอร์พารามิเตอร์ เพื่อทดสอบไฮเปอร์พารามิเตอร์ที่เป็นไปได้จำนวนมากโดยอัตโนมัติ

เนื่องจากเรายังยังไม่เห็นฟอเรสต์แบบสุ่มและต้นไม้ที่เพิ่มระดับไล่ระดับสี และเนื่องจากจำนวนตัวอย่างน้อยเกินกว่าที่จะปรับแต่งไฮเปอร์พารามิเตอร์อัตโนมัติ คุณจึงปรับปรุงโมเดลด้วยตนเอง

แผนผังการตัดสินใจที่แสดงด้านบนมีขนาดเล็ก และใบไม้ที่มีตัวอย่าง 61 รายการมีป้ายกำกับของ Adelie และ Chinstrap รวมกัน ทำไมอัลกอริทึมจึงไม่แยกใบไม้นี้ ออกไปก่อน มีสาเหตุที่เป็นไปได้สองข้อ:

  • อาจมีจำนวนตัวอย่างต่อใบไม้ถึงจำนวนขั้นต่ำแล้ว (min_examples=5 โดยค่าเริ่มต้น)
  • ต้นไม้อาจถูกแบ่งออกและตัดแต่งกิ่งไม้เพื่อไม่ให้มากเกินไป

ลดจำนวนตัวอย่างขั้นต่ำให้เหลือ 1 รายการและดูผลลัพธ์ดังนี้

model = ydf.CartLearner(label=label, min_examples=1).train(train_dataset)
model.plot_tree()

แผนผังการตัดสินใจที่ได้รับการฝึกด้วย
min_examples=1

รูปที่ 18 แผนผังการตัดสินใจที่ได้รับการฝึกด้วย min_examples=1

 

ระบบจะแบ่งโหนด Leaf ที่มีตัวอย่าง 61 รายการต่อไปอีกหลายครั้ง

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

print(model.evaluate(test_dataset).accuracy)
# >> 0.97222

คุณภาพของโมเดลเพิ่มขึ้นด้วยความแม่นยำในการทดสอบจาก 0.9167 เป็น 0.97222 การเปลี่ยนไฮเปอร์พารามิเตอร์นี้เป็นความคิดที่ดี

รายงานก่อนหน้าของป่าการตัดสินใจ

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

model = ydf.RandomForestLearner(label=label).train(pandas_train_dataset)
print("Test accuracy: ", model.evaluate(pandas_test_dataset).accuracy)
# >> Test accuracy: 0.986111

ความแม่นยำของป่าแบบสุ่มดีกว่าต้นไม้ธรรมดาๆ ของเรา คุณจะได้ เรียนรู้ได้ในหน้าถัดไป

การใช้งานและข้อจำกัด

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

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