ทำนายผลบอลด้วย stats ผู้เล่นจาก FIFA19 และค่าสถิติแมทช์ที่ผ่านมา
เราจะหาเงินได้มากขนาดไหนถ้าเรามีโมเดลทายผลบอลที่แม่นซะยิ่งกว่าหมึกพอล?
แน่นอนครับว่าถ้าทำได้จริง ป่านนี้ก็คงไม่มีใครรับแทงบอลกันแล้วเพราะจะเจ๊งเอากันซะหมด แต่ไหนๆก็หลงเข้ามาอ่านกันแล้วในบล็อกนี้ผมจะพาทุกคนไปสร้างโมเดลทำนายผลบอลด้วย Machine Learning ให้ได้ค่า accuracy 50% เองครับ
⚠️⚠️ NOOB ALERT ⚠️⚠️
ก่อนอื่นเลย datasets ที่ผมใช้จะมีอยู่ทั้งหมด 2 ตัวด้วยกัน ซึ่งตัวแรกนั้นก็คือ
ซึ่งจะครอบคลุมตั้งแต่ชื่อของผู้เล่น สังกัดทีม เชื้อชาติ ไปจนถึงค่า stats ต่างๆของผู้เล่นคนนั้นๆ และอีก datasets นึงนั่นก็คือ
ที่ประกอบไปด้วยผลการแข่งขัน English Premier League (ขอเรียกสั้นๆว่า EPL) ทุกแมทช์ตั้งแต่ปี 2010–2021 รวมไปถึงค่าสถิติต่างๆจากทั้งทีมเย้าและทีมเยือนภายในแมทช์นั้นๆ
เริ่มจัดการกับ Data
ก่อนอื่นคงต้องเริ่มจากการวางแผนกันก่อน ผมคาดหวังไว้ว่าท้ายที่สุดแล้วเราอยากได้ฟังก์ชั่นที่สามารถใส่ชื่อ “ทีม A” เจอกับ “ทีม B” แล้วสามารถบอกผลลัพธ์ออกมาได้
ดังนั้นเราต้องยุบรวม stats ผู้เล่นจาก datasets FIFA19 ให้กลายเป็น stats ของทีมเสียก่อน แต่การจะเอา stats ผู้เล่นทุกคนมายำรวมกันหมดแล้วหาค่าเฉลี่ยโดยไม่สนว่าจะเป็นตัวจริงหรือตัวสำรอง หรือตำแหน่งของผู้เล่นเลย ก็ดูจะไม่ใช่ทางที่ดีเสียเท่าไหร่
อันดับแรกผมสร้างฟังก์ชั่น simple_position() ขึ้นมาเพื่อหาตำแหน่งอย่างง่ายของผู้เล่นแต่ละคนก่อนว่าเป็นกองหน้า กองกลาง กองหลัง หรือผู้รักษาประตู
จากนั้นก็เลือกก็ผู้เล่นแต่ละตำแหน่งโดยยึดตาม overall stats เป็นหลัก โดยจะเลือกกองหน้าที่มีค่า overall สูงที่สุดในทีมมา 2 คน กองกลางและกองหลังอีกตำแหน่งละ 4 คน และผู้รักษาประตูอีก 1 คน โดยเราจะถือให้ผู้เล่นทั้ง 11 คนนี้เป็นตัวแทนของทีมนั้นๆไปเลย
จากนั้นก็หาค่า stats เฉลี่ยแยกตามแต่ละตำแหน่ง เปลี่ยนชื่อ columns แล้วนำทั้งหมดมา concatenate กันเพื่อสร้างเป็น dataframe เดียวที่มี features เป็น stats ต่างๆของแต่ละตำแหน่งรวมกันอยู่ใน rows เดียวกลายเป็นค่า stats ของทีม
ตอนนี้เราก็ได้ค่า stats ของแต่ละทีมมาตามที่ต้องการแล้ว ซึ่งนั่นก็หมายความว่า
เราหมดธุระกับ datasets FIFA19 แล้ว
แต่ที่เรายังขาดไปอยู่คือผลการแข่งขัน EPL แต่ละแมทช์ ซึ่งจะอยู่ในอีก datasets นึงแต่เนื่องจากค่า stats ผู้เล่นของเราที่มาจากเกม FIFA19 นั้นถูกสร้างขึ้นมาในปี 2019 การเอาผลการแข่งขันของปีที่ห่างกันมากมาใช้อาจจะไม่ดีเท่าไหร่นัก ผมจึงเลือกใช้ผลการแข่ง EPL ในซีซัน 2018–19 และ 2019–20 เพียงเท่านั้น
ดึงผลลัพธ์ของแมทช์นั้นๆออกมาเพื่อดูว่าฝั่งไหนแพ้ ฝั่งไหนชนะ หรือว่าเสมอ จากนั้นก็แปลงจากค่า boolean ไปเป็น int ด้วย .astype(int) เพื่อนำไปใช้เป็นค่า y ในโมเดล
อยากให้ features มีอะไรมากกว่านี้อีก
จาก datasets นี้ที่ผมใช้ดึงผลการแข่ง EPL มา นอกจากจะบอกประตูที่แต่ละฝ่ายทำได้แล้วยังบอกค่าสถิติต่างๆภายในแมทช์นั้นอีกด้วยเช่น %การครองบอล แต่ละฝ่ายมีโอกาสยิงทำประตูไปกี่ครั้ง ยิงเข้ากรอบกี่ครั้ง ได้เตะมุมกี่ครั้ง ส่งบอลกี่คร้ั้ง ฯลฯ ซึ่งก็เป็นค่าเหล่านี้เองที่ผมจะนำมาใช้เป็น features ในโมเดลของเรา
โดยถ้าสมมติว่าเราอยากรู้ผลการแข่งระหว่าง “ทีม A” เจอกับ “ทีม B” เราก็จะย้อนกลับไปเมื่อ 3 ปีก่อนเพื่อนำค่าสถิติต่างๆจากทุกแมทช์ที่ “ทีม A” เจอกับ “ทีม B” ในระยะเวลา 3 ปีที่ผ่านมา มาหาเป็นค่าเฉลี่ยและนำค่าเหล่านี้ไปใช้เป็น features ในโมเดล และในแมทช์อื่นๆเองก็ทำเช่นเดียวกัน ผลสุดท้ายจะได้ dataframe ออกมาประมาณนี้
จะถึงขั้นสุดท้ายของการเตรียมข้อมูลแล้ว!
มาพัก recap กันก่อนสักนิด ตอนนี้เรามี dataframe อยู่ทั้งหมด 3 ชุดด้วยกันนั่นคือ
- ค่า stats รวมของแต่ละทีม
- ค่าสถิติย้อนหลังจากแมทช์ตลอด 3 ปีก่อนที่ทีมเจ้าบ้านและทีมเยือนเคยเตะกัน
- ผลการแข่งทุกแมทช์จาก EPL ซีซัน 2018–19 และ 2019–20
สิ่งที่เราต้องทำตอนนี้ก็คือเอา dataframe ตัวที่ 3 เป็นตัวตั้ง จากนั้นก็เอา features จาก dataset ที่ 1 และ 2 เข้าไปใส่ตามชื่อทีมให้ตรงกัน
ยกตัวอย่างเช่น dataframe3 มี row แรกเป็นผลการแข่งของ Liverpool กับ Man U เราก็ต้องไปเอา stats ทีมของ Liverpool กับ Man U จาก dataframe1 มาใส่ แล้วจากนั้นไปหาสถิติย้อนหลังที่ทั้งสองทีมนี้เคยเจอกันจาก dataframe2 มาใส่ไว้ด้วยเช่นกัน
โดยท้ายที่สุดแล้วเราจะได้ออกมาเป็น dataframe ที่มีทั้งข้อมูลผลการแข่งในแมทช์นั้นๆ รวมทั้งค่า stats ของทีมแต่ละฝั่ง และค่าสถิติย้อนหลังที่ทั้งสองทีมนั้นเคยเจอกันรวมอยู่ใน row เดียว
แต่!!! ปัญหาคือ dataframe ของเรานั้นมีทั้งหมด 235 features ด้วยกัน!!
ดังนั้นสิ่งที่ต้องทำก่อนที่จะไปสร้างโมเดลก็คือการทำ Feature Engineering นั่นเอง
Feature Engineering
การมีจำนวน features ที่มากเกินไปนั้นนอกจากจะทำให้โมเดลรันนานแล้ว ยังอาจส่งผลให้โมเดลของเราได้ประสิทธิภาพต่ำกว่าที่ควรจะเป็นด้วย ดังนั้นเราจึงต้องทำ feature engineering เสียก่อนที่จะไปสร้างโมเดล เพื่อเลือกเพียงแต่ features ที่สำคัญไปใช้และตัดเอา features ที่ไม่เกี่ยวข้องออกไป
โดยก่อนอื่นเลย สิ่งแรกที่ผมทำคือการสร้างฟังก์ชั่นเพื่อหา correlated features ที่มีค่า colleration มากกว่า 0.8 และตัด features เหล่านั้นออกไปก่อน เพื่อป้องกันไม่ให้เกิดปัญหา multicollinearity ขึ้น
ซึ่งก็ทำให้เราสามารถตัดออกไปได้มากถึง 135 features แต่ก็ยังคงเหลืออีก 100 features ซึ่งก็ยังคงถือว่ามากเกินไปอยู่ดี ดังนั้นสิ่งต่อไปที่ผมจะทำนั่นก็คือการทำ forward selection ซึ่งจะเป็นการเลือกเพิ่ม feature เข้ามาทีละ feature โดยจะเลือกเฉพาะตัวที่เพิ่มเข้ามาแล้วทำให้โมเดลทำนายได้ดีขึ้นอย่างมีนัยสำคัญเท่านั้น
เท่านี้เราก็ได้ค่า X และค่า y สำหรับการนำไปสร้างโมเดลแล้ว!!
การสร้างโมเดล
โมเดลที่ผมเลือกใช้คือ k-nearest neighbors โดยเหตุผลก็คือส่วนตัวเคยลองใช้ algorithm อื่นแล้วมันไม่เวิร์คครับ
ตอนที่เรียกใช้โมเดลก็ทำการ fine tune โมเดลด้วย GridSearchCV ไปด้วยเลย
และท้ายที่สุดเราก็ได้ออกมาเป็นโมเดลทำนายผลบอลที่มี accuracy 50% นั่นเอง!!
การนำไปใช้งาน
ทีนี้เพื่อให้ง่ายต่อการนำไปใช้งาน เราเลยต้องมีการเขียนฟังก์ชั่นอะไรขึ้นมาเล็กน้อย
โดยตัวฟังก์ชั่นนี้จะทำงานโดยมี input เป็นชื่อทีมเย้าและทีมเยือน จากนั้นก็จะนำชื่อทีมนี้ไปเทียบกับตัว dataframe ที่เรามีอยู่ก่อนแล้ว และนำค่า stats ของทั้ง 2 ทีมและค่าสถิติจากแมทช์ก่อนหน้าที่ทั้ง 2 ทีมนี้เคยเตะกัน ใช้เป็น features และนำไปเข้าโมเดลทำนายผลบอลและแสดงผลการแข่งขันออกมา
เท่านี้ก็เป็นอันเสร็จสิ้นการทำโมเดลทำนายผลบอลของเราแล้วครับ
พูดทิ้งท้ายซักหน่อย
สุดท้ายนี้ ผมอาจจะพูดไม่ได้เต็มปากว่านี่เป็นโมเดลทำนายผลบอลที่มีประสิทธิภาพซักเท่าไหร่จากค่า accuracy ของโมเดลที่มีีเพียง 50% เท่านั้น แต่จากโมเดลที่เคยมีคนทำไว้บน Kaggle เอง ส่วนใหญ่ก็จะได้ accuracy เพียง 4X%++ เท่านั้นเช่นกัน
ทั้งนี้อาจเป็นเพราะในระหว่างช่วงเวลา 90 นาทีที่แข่งบอลกันนั้นมีความเป็นไปได้มากมายที่สามารถเกิดขึ้นได้ ซึ่งรวมถึงการเปลี่ยนตัวหรือผู้เล่นได้รับบาดเจ็บตัวระหว่างการแข่งขัน หรือแม้แต่แผนการเล่นของแต่ละทีมที่ไม่เหมือนกัน ตัวแปรต่างๆเหล่านี้นั้นยากที่จะแปลงเป็น features เพื่อให้ครอบคลุมถึงความเป็นไปได้ทั้งหมด
ด้วยความไม่มีรูปแบบที่ตายตัวนี้ จึงทำให้การแข่งขันไม่สามารถคาดเดาได้ และยังเป็นอีกสเน่ห์หนึ่งของกีฬาด้วยนั่นเอง
สุดท้ายจริงๆแล้ว
บล็อกนี้เป็นบล็อกแรกของผมที่เขียนเกี่ยวกับ Machine Learning และยังถือเป็นโปรเจค Machine Learning โปรเจคแรกของผมเองเช่นกัน หากผิดพลาดประการใดหรือผู้อ่านท่านใดมีข้อแนะนำ ผมยินดีน้อมรับคำติชมไว้ทั้งหมดเลยครับ
ทั้งโปรเจคและบล็อกที่ทำขึ้นนี้เป็นส่วนหนึ่งของโครงการ “AI Builders”
โครงการที่เปิดโอกาสให้เด็กม.ปลายแบบผมได้เรียนรู้และได้ลองทำโปรเจค AI ขึ้นมาเป็นของตัวเอง สุดท้ายนี้ก็ต้องขอขอบคุณทุกคนที่เกี่ยวข้องและเมนเทอร์กลุ่มของผม พี่ปิง พี่เพิร์ช และผู้อ่านทุกคนที่หลงเข้ามาอ่านไว้ ณ ที่นี้ด้วยครับ ⚽⚽⚽