ว่าด้วยเรื่องการวัดประสิทธิภาพ
ในครั้งนี้ ผมจะไม่ได้กล่าวถึงเทคนิคใหม่ ๆ ใน Machine Learning แต่ผมเสนอสิ่งที่สำคัญไม่แพ้กันนั่นคือ “การตรวจวัด” คำถามมักจะมีเสมอเมื่อเราเขียนโปรแกรมขึ้นมาโปรแกรมหนึ่ง นั่นคือ “แล้วมันดีแค่ไหนหล่ะ?” อันที่จริงมันขึ้นอยู่กับว่า “อย่างไหนเรียกว่าดีหล่ะ ?”
เราอาจจะนิยามคำว่าดีง่าย ๆ ว่า “ความถูกต้องโดยรวม” นั่นก็คือ “สิ่งที่มันทำถูกหารด้วยสิ่งที่มันทำทั้งหมด” และค่าที่ตรงข้ามกับค่านี้ก็คือ “ความผิดพลาดโดยรวม” ซึ่งก็คือส่วนกลับของค่านี้นั่นเอง
แน่นอนว่าเราอยากให้ค่าความผิดพลาดน้อยที่สุดเท่าที่เป็นไปได้ หากเป็น 0% ได้เลยยิ่งดี ก็แสดงว่า อัลกอริทึมที่เราออกแบบนั้นจะทำงานได้อย่างดีเยี่ยมโดยไร้ข้อผิดพลาด
แต่ช้าก่อนค่าความผิดพลาดมักจะต้องโยงกับว่าเราเอาอะไรมา “ทดสอบ” จริงไหม ยกตัวอย่างเช่น เราเอาข้อมูลที่เราใช้ฝึกฝนมันมาทดสอบมันเอง ต่อให้เราสามารถดันความผิดพลาดให้เหลือ 0% ได้ นั่นหาได้มีค่าใดไม่ ก็เพราะว่าใคร ๆ เค้าก็ทำได้ วิธีนึงก็คือ “จำ” ทุก ๆ อย่างที่ถูกใช้ฝึกฝนและรอตอบตอนที่ทดสอบ
เพราะฉะนั้นมันไม่มีประโยชน์ที่จะทดสอบบนสิ่งที่มันถูกฝึกฝนมา (Training Data) เพราะว่าสุดท้ายแล้วที่เราเลือกที่จะแก้ปัญหาด้วย Machine Learning ก็เพราะว่า เราอยากจะให้เครื่องจักรพยายามสร้างกฎบางอย่าง จากสิ่งที่เราฝึกฝนมัน หรือเครื่องจักรจะต้องมีความสามารถในการ Generalize สิ่งที่เราป้อนเข้าไปนั่นเอง เพื่อเราจะได้ใช้มันในการ “เดาอนาคต” ต่อไป (ซึ่งคนเราเก่งมากในเรื่องการ Generalize เนี่ย คือคนเราขี้เดานั่นเอง แต่ว่าจำไม่เก่ง)
ถึงตรงนี้อาจจะมีคำถามว่า “งั้นจะให้ทดสอบกับอะไรเล่า?“ คำตอบก็คือ “อะไรก็ได้ที่มันไม่รู้มาก่อน” เราเรียกสิ่งนี้ว่า Testing data คือมันจะเอาไว้สำหรับการทดสอบอย่างเดียว
ตอนนี้แสดงว่าเราต้องมีทั้ง Training Data และ Testing Data แย่หน่อยตรงที่ในหลาย ๆ ครั้งเราไม่ได้มี Testing Data มาด้วย ทำให้เราต้องหาวิธีสร้างมันขึ้นมาซึ่งวิธีนึง (และง่าย) ก็คือตัดส่วนของ Training Data สงวนเอามาไว้ทดสอบนั่นเอง ซึ่งวิธีนี้จะทำให้เรามีข้อมูลในการฝึกฝนน้อยลง นั่นแปลว่าเครื่องจักรเราก็ต้องโง่ลงด้วย แต่นั่นเป็นสิ่งที่หลีกเลี่ยงไม่ได้ เพราะว่าหากเราไม่ทดสอบเลยเราก็ไม่รู้อยู่ดีว่ามันฉลาดขนาดไหน
ดังนั้นเราก็ไม่อยากจะตัดข้อมูลออกมาจาก Training Data เยอะ ๆ ถึงตรงนี้เราจะมาพูดถึงวิธีการตัดนั่นเอง วิธีแรกก็คือ Leave one out ชื่อค่อนข้างบ่งบอกว่าเราจะตัดออกมาแค่ 1 ตัว ! แต่การตัดออกมา 1 ตัวแล้วจะตรวจสอบได้ว่าอัลกอริทึมเราทำงานได้ดีแค่ไหน มันก็ดูจะเหลือเชื่อไปซักหน่อย อันที่จริงคือเราจะตัด มันออกมา “หลาย ๆ ครั้ง ครั้งละ 1 ตัว” จะเขียนเป็นขั้นตอนได้ดังนี้
- มีข้อมูล N ตัว
- เลือกออกมา 1 ตัว (ผลัดไปตัวไปเรื่อย ๆ)
- เหลือข้อมูล N-1 ตัว เรียกว่า Training Data เอาตรงนี้ไปฝึกฝนเครื่องจักร
- ได้เครื่องจักร แล้วเอามาทดสอบด้วยข้อมูล 1 ตัว ที่ตัดออกมา หากมันเดาถูก ก็ได้คะแนน หากเดาผิดก็ไม่ได้คะแนน
- เอาข้อมูลตัวนั้นกลับเข้าไปในกองเหมือนเดิม และเริ่มขั้นตอน 1 ใหม่ อีกรอบ
หากเราทำอย่างนี้ N รอบ (ฝึกฝน N ครั้ง) เราก็จะทำการดึงข้อมูลออกมาทั้งหมด N ตัว โดยที่ไม่ซ้ำกันเลย แสดงว่าข้อมูลแต่ละตัวมีโอกาสได้ถูกเดา มีโอกาสได้เป็นตัวที่เราไม่รู้ ซึ่งก็คือส่ิงที่ดี เพราะว่าเราต้องการแสดงให้เห็นว่า การทดสอบแบบนี้ “ครอบคลุม” จริง ๆ ไม่ใช่แค่เอาเสียงส่วนน้อยมาชนะเสียงส่วนมาก
หากเรานับจำนวนครั้งที่หมดที่เราเดาถูก หารด้วย N เราจะได้ ความแม่นยำแบบ Leave one out ซึ่งถือกันว่ามีความใกล้เคียงความแม่นยำจริง ๆ หากอัลกอริทึมนี้ไปใช้ในชีวิตจริง
แต่ปัญหาของวิธี validate แบบ Leave one out ก็คือ เราต้องฝึกฝนถึง N ครั้ง ซึ่งโตเป็น linear แสดงว่าหากเรามีข้อมูล 1 ล้านตัว ก็ต้องเทรน 1 ล้านครั้ง ซึ่งแต่ละครั้งเราอาจจะต้องทำงานกับข้อมูล เกือบล้านตัว จะเห็นว่าวิธีนี้ไม่ได้เหมาะต่อการทำงานจริง ๆ เอาซะเลย แม้ว่าจะเที่ยงตรง และประหยัดข้อมูลทดสอบ แต่กลับทำจริงไม่ได้
จึงมีคนเสนอว่า “เราจะใช้แนวคิดแบบนี้ แต่เราจะทำให้มันเหมาะสมต่อการใช้จริงมากกว่านี้” นั่นก็คือ Cross Validation ชื่อนี้ก็อาจจะคุ้นหูคนหลาย ๆ คนเหมือนกัน ถูกนำเอามาใช้เป็นชื่อ forum เกี่ยวกับ “สถิติ” ของ stackexchange ด้วย (ใช้ชื่อว่า Cross Validated)
ที่วิธีการนี้ดังกว่า เพราะว่ามันเป็นสิ่งที่เป็นจริงได้ และก็ถูกใช้จริง ๆ เพื่อเป็นมาตรฐานการวัดประสิทธิภาพของอัลกอริทึมนั่นเอง
วิธีการของมันละม้ายคล้ายกับ Leave one out เป็นอย่างมาก ต่างก็แค่แทนที่จะหยิบทีละตัว กลายเป็นหยิบทีละ N/K ตัวแทน (ซึ่ง K เป็นค่าคงที่ที่เราเลือกแต่ต้น) และทำอย่างนี้ K ครั้ง ด้วยวิธีการแบบนี้ จะทำให้เราฝึกฝนเครื่องจักรเพียง K ครั้งเท่านั้น ไม่ว่าข้อมูลจะมีมากน้อยเพียงใดก็ตาม (จาก linear กลายเป็น constant) เราเรียกสิ่งนี้ว่า k-fold Cross Validation
ซึ่งค่า K ที่นิยมและถือว่าเป็นมาตรฐานก็คือ K=10 เพราะว่าเราจะเหลือข้อมูลไว้สำหรับฝึกฝนถึง 90% ในแต่ละรอบ (training data) และมี 10% ไว้สำหรับทดสอบ (testing data) แสดงว่าหากเราเอาอับกอริทึมนี้ไปใช้ในชีวิตจริงความเที่ยงของการวัดนี้ก็ยังอยู่ในระดับสูงราว ๆ 90% นั่นเอง
สุดท้ายอย่าลืมว่าทำไมเราต้องพูดกันยืดยาวสำหรับหัวข้อนี้ ก็เพราะว่าไม่ว่าเราจะคิดค้นอัลกอริทึมที่ทรงพลัง ทรงประสิทธิภาพแค่ไหน สิ่งเหล่านั้นก็ไร้ค่าหากเราวัดมันไม่ได้ ทำให้คนอื่นเข้าถึงพลังของมันไม่ได้ นั่นแหละทำไมสิ่งนี้จึงสำคัญ