DEV Community

Kawin Hongmala
Kawin Hongmala

Posted on

สร้าง Simple Random Forest Model โดยใช้ Python

ถ้าเราจะต้องเดาหรือใช้ดวงตัวเองในการเล่นเสือมังกรว่าตาถัดไปจะออกอะไรหรือแนวโน้มจะเป็นยังไงในอนาคต การใช้ Random Forest เป็นหนึ่งในวิธีที่เหมาะสม เนื่องจากมันสามารถจัดการกับข้อมูลที่มีรูปแบบซับซ้อนได้ดีช่วยให้การทำนายผลมีความแม่นยำ

เกมเสือมังกรเป็นเกมไพ่ที่เล่นง่าย โดยผู้เล่นเลือกว่าจะเดิมพันฝั่ง "เสือ หรือ มังกร" หรืออาจเลือก "เสมอ" ในการแจกไพ่ทั้งสองฝั่งจะได้รับไพ่ 1 ใบ และฝั่งที่ได้ไพ่ที่มีแต้มสูงกว่าจะเป็นผู้ชนะ แต้มของไพ่จะเรียงตามลำดับจากต่ำไปสูง เช่น A=1, 2-10 แต้มตามหน้าไพ่ และไพ่ J, Q, K มีค่า 11, 12, 13 ตามลำดับ

บทความนี้มีเป้าหมายเพื่อแสดงให้เห็นถึงการนำ Machine Learning โดยใช้ Random Forest มาช่วยในการวิเคราะห์และทำนายผลของเกมเสือมังกร จากข้อมูลย้อนหลัง เพื่อทำนายว่าตาถัดไปจะออกมังกร เสือ หรือเสมอ

จากการเก็บข้อมูลย้อนหลัง 10 รอบ
ในแต่ละรอบจะออกทั้งหมดรวม 208 ครั้ง

รอบที่ 1 | มังกร 88 ครั้ง, เสือ 88 ครั้ง, เสมอ 32 ครั้ง
Image description

Image description

รอบที่ 2 | มังกร 88 ครั้ง, เสือ 95 ครั้ง, เสมอ 25 ครั้ง
Image description

Image description

รอบที่ 3 | มังกร 75 ครั้ง, เสือ 101 ครั้ง, เสมอ 32 ครั้ง
Image description

Image description

รอบที่ 4 | มังกร 91 ครั้ง, เสือ 84 ครั้ง, เสมอ 33 ครั้ง
Image description

Image description

รอบที่ 5 | มังกร 70 ครั้ง, เสือ 100 ครั้ง, เสมอ 38 ครั้ง
Image description

Image description

รอบที่ 6 | มังกร 99 ครั้ง, เสือ 79 ครั้ง, เสมอ 30 ครั้ง
Image description

Image description

รอบที่ 7 | มังกร 96 ครั้ง, เสือ 105 ครั้ง, เสมอ 7 ครั้ง
Image description

Image description

รอบที่ 8 | มังกร 91 ครั้ง, เสือ 95 ครั้ง, เสมอ 22 ครั้ง
Image description

Image description

รอบที่ 9 | มังกร 95 ครั้ง, เสือ 96 ครั้ง, เสมอ 27 ครั้ง
Image description

Image description

รอบที่ 10 | มังกร 106 ครั้ง, เสือ 90 ครั้ง, เสมอ 12 ครั้ง
Image description

Image description

ขั้นตอนที่ 1 จัดเตรียมข้อมูล
เริ่มต้นด้วยการเตรียมข้อมูล โดยข้อมูลที่เราใช้จะเป็นผลลัพธ์ของเกมเสือมังกรจากตาก่อนหน้า
แปลงข้อมูลผลลัพธ์จาก มังกร,เสือ,เสมอ ให้เป็นตัวเลข 1,2,3

import pandas as pd  

# ข้อมูลชุดที่ลองเล่น
data = {'result': ['มังกร', 'เสือ', 'มังกร', 'เสือ', 'มังกร', 'เสือ',
'เสือ', 'เสือ', 'มังกร', 'มังกร', 'มังกร', 'เสือ',
'เสือ', 'เสือ', 'เสมอ', 'เสือ', 'มังกร', 'เสือ',
'เสือ', 'เสือ', 'เสือ', 'มังกร', 'มังกร', 'มังกร',
'เสมอ', 'มังกร', 'มังกร', 'เสมอ', 'มังกร', 'มังกร',
'มังกร', 'มังกร', 'เสือ', 'มังกร', 'มังกร', 'มังกร',
'เสือ', 'เสือ', 'เสือ', 'มังกร', 'มังกร', 'มังกร',
'มังกร', 'มังกร', 'มังกร', 'มังกร', 'เสือ', 'มังกร',
'เสมอ', 'มังกร', 'มังกร', 'มังกร', 'มังกร', 'มังกร',
'มังกร', 'มังกร', 'เสือ', 'เสือ', 'เสือ', 'เสือ'
'มังกร', 'มังกร', 'มังกร', 'มังกร', 'เสือ', 'มังกร',
'เสือ', 'เสือ', 'เสมอ', 'มังกร', 'เสือ', 'มังกร',
'เสือ', 'มังกร', 'เสือ', 'เสือ', 'มังกร', 'เสือ',
'มังกร', 'เสือ', 'เสมอ', 'มังกร', 'มังกร', 'มังกร',
'มังกร', 'มังกร', 'เสือ', 'เสือ', 'เสือ', 'เสือ',
'เสือ', 'มังกร', 'มังกร', 'มังกร', 'เสือ', 'เสือ',
'เสือ', 'มังกร', 'มังกร', 'มังกร', 'มังกร', 'เสือ',
'เสือ', 'เสือ', 'เสือ', 'มังกร', 'มังกร', 'เสือ',
'เสมอ', 'เสมอ', 'เสือ', 'เสือ', 'เสือ', 'มังกร',
'มังกร', 'เสือ', 'มังกร', 'เสือ', 'มังกร', 'เสือ', 
'มังกร', 'เสือ', 'เสือ', 'มังกร', 'เสือ', 'มังกร',                   
'เสือ', 'เสือ', 'เสือ', 'มังกร', 'มังกร', 'มังกร',
'มังกร', 'มังกร', 'มังกร', 'มังกร', 'มังกร', 'เสือ',
'มังกร', 'เสือ', 'เสือ', 'มังกร', 'เสือ', 'เสือ',
'เสือ', 'เสือ', 'มังกร', 'เสมอ', 'มังกร', 'เสือ',                  
'มังกร', 'เสือ', 'มังกร', 'เสือ', 'เสือ', 'เสมอ',
'มังกร', 'เสือ', 'เสือ', 'เสมอ', 'มังกร', 'เสือ',                   
'เสือ', 'เสือ', 'เสือ', 'เสมอ', 'มังกร', 'มังกร',
'เสือ', 'เสือ', 'มังกร', 'มังกร', 'มังกร', 'เสือ',                   
'เสือ', 'มังกร', 'มังกร', 'มังกร', 'เสือ', 'มังกร',
'มังกร', 'มังกร', 'มังกร', 'มังกร', 'มังกร', 'เสือ',                   
'เสือ', 'เสือ', 'มังกร', 'เสือ', 'เสือ', 'มังกร',
'เสือ', 'เสือ', 'มังกร', 'เสือ', 'มังกร', 'เสือ',
'มังกร', 'เสือ', 'มังกร', 'เสือ', 'มังกร', 'มังกร',                   
'มังกร', 'มังกร', 'มังกร', 'เสือ']}
df = pd.DataFrame(data)

# แปลงข้อมูลเป็นตัวเลข
df['result'] = df['result'].map({'มังกร': 1, 'เสือ': 2, 'เสมอ': 3})
print(df)

Enter fullscreen mode Exit fullscreen mode
  • กำหนดให้ มังกร,เสือ,เสมอ แปลงเป็นตัวเลข

ตัวอย่างผลที่ได้จาก code

Image description

ขั้นตอนที่ 2: สร้างฟีเจอร์
สร้างฟีเจอร์ที่ใช้สำหรับการทำนาย โดยการใช้ข้อมูลจากตาก่อนหน้าเป็นตัวแปร (Features) เช่น ผลลัพธ์ของตาก่อนหน้า (lag features) เพื่อช่วยให้โมเดลเรียนรู้จากข้อมูลย้อนหลังและคาดการณ์ผลของตาถัดไป

# สร้างฟีเจอร์จากข้อมูลย้อนหลัง

df['prev_1'] = df['result'].shift(1)  
df['prev_2'] = df['result'].shift(2)  
df.dropna(inplace=True) 
print(df)

Enter fullscreen mode Exit fullscreen mode
  • df['prev_1'] = df['result'].shift(1)และ df['prev_2'] = df['result'].shift(2) เป็นการดูผลลัพธ์ของตาก่อนหน้าและตาก่อนหน้าอีก 2 ตา

ตัวอย่างผลที่ได้จาก code

Image description

  • การใช้ shift() ทำให้ตัวแรก มีค่า NaN เพราะมันไม่มีข้อมูลก่อนหน้าให้ดู

ขั้นตอนที่ 3: แบ่งข้อมูล
แบ่งข้อมูลออกเป็น 2 ส่วน คือ ชุดฝึก (Training Set) และ ชุดทดสอบ (Test Set)
โดยทั่วไปจะใช้ข้อมูล 80% สำหรับฝึกโมเดล และ 20% สำหรับทดสอบความแม่นยำของโมเดล

from sklearn.model_selection import train_test_split

# แบ่งข้อมูลเป็น train และ test
X = df[['prev_1', 'prev_2']]  
y = df['result']  
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

Enter fullscreen mode Exit fullscreen mode
  • from sklearn.model_selection import train_test_split เป็นการนำเข้าจากไลบรารี เพื่อช่วยแบ่งข้อมูลได้ง่าย ๆ

ทำไมต้องแบ่งข้อมูล?
เหตุผลที่ต้องแบ่งข้อมูลเป็น 2 ส่วน คือ

  • Training Set (ชุดฝึก): ใช้เพื่อ "สอน" โมเดลให้เรียนรู้จากข้อมูล

  • Test Set (ชุดทดสอบ): ใช้เพื่อ "ทดสอบ" ว่าโมเดลที่เรียนมาแล้วจะทำนายได้ดีแค่ไหนกับข้อมูลที่ไม่เคยเห็นมาก่อน

  • ใช้ train_test_split เพื่อแบ่งข้อมูลออกเป็น
    X_train y_train สำหรับฝึกโมเดล
    X_test y_test สำหรับทดสอบความแม่นยำของโมเดล

  • test_size=0.2 แบ่ง 20% ของข้อมูลไว้สำหรับทดสอบ และอีก 80% ใช้ฝึก

  • random_state=42 ตั้งค่าให้การแบ่งข้อมูลสุ่มแบบเดิมทุกครั้ง

ขั้นตอนที่ 4: สร้างโมเดล
สร้างโมเดล Random Forest Classifier เพื่อฝึกโมเดล Machine Learning ด้วยข้อมูลในชุดฝึกที่เตรียมไว้เพื่อให้เรียนรู้ว่า ผลลัพธ์ของตาถัดไปจะออกอะไร จากข้อมูลของตาก่อนหน้า

from sklearn.ensemble import RandomForestClassifier

# สร้างโมเดล

model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)  

Enter fullscreen mode Exit fullscreen mode
  • from sklearn.ensemble import RandomForestClassifier เป็นการนำเข้าจากไลบรารี ซึ่งเป็นไลบรารียอดนิยมสำหรับทำ Machine Learning เป็นการใช้ต้นไม้หลายต้นในการร่วมกันตัดสินใจ เพื่อเพิ่มความแม่นยำ

  • n_estimators=100 จะใช้ต้นไม้ 100 ต้น เพื่อช่วยกันตัดสินใจ

  • random_state=42 ช่วยให้ผลลัพธ์เหมือนเดิมทุกครั้ง (ทำให้การทดลองสามารถทำซ้ำได้)

  • หลังจากรันคำสั่งนี้ โมเดลจะ จำรูปแบบของข้อมูล ว่าถ้าผลก่อนหน้าเป็นแบบนี้ มีแนวโน้มจะออกอะไรในตาถัดไป

ขั้นตอนที่ 5: ทำนายผล
หลังจากฝึกโมเดลเสร็จแล้ว ต้องการดูว่าโมเดลสามารถทำนายผลลัพธ์ของเกมได้ดีแค่ไหน

# ทำนายผลจากข้อมูลทดสอบ

y_pred = model.predict(X_test)
print("Predictions:", y_pred)

Enter fullscreen mode Exit fullscreen mode
  • y_pred คือผลลัพธ์ที่โมเดลคิดว่าจะเกิดขึ้น

  • model.predict(X_test) เป็นโมเดลที่ฝึกไว้แล้วในขั้นตอนก่อนหน้า สั่งให้ทำนายผลลัพธ์ จากฟีเจอร์ที่อยู่ใน X_test

ตัวอย่างผลที่ได้จาก code

Image description

  • `1. 2. 1. 1. 2. 2. 2. 1. 2. 2. 2. 1. 1. 1. 2. 1. 1. 1. 1. 2. 1. 2. 2. 1.
    1. 2. 1. 2. 1. 1. 1. 1. 2. 1. 1. 1. 2. 1. 2. 2. 1.` จาก 20% ที่ทดสอบ

ขั้นตอนที่ 6: ประเมินผล
สุดท้ายจะประเมินผลการทำนายของโมเดลโดยใช้ตัวชี้วัดต่างๆ เช่น Accuracy, Confusion Matrix หรือ Classification Report เพื่อดูว่าโมเดลทำงานได้ดีแค่ไหน

from sklearn.metrics import accuracy_score, confusion_matrix, classification_report

print("Accuracy:", accuracy_score(y_test, y_pred))

print("Confusion Matrix:")
print(confusion_matrix(y_test, y_pred))

print("Classification Report:")
print(classification_report(y_test, y_pred))

Enter fullscreen mode Exit fullscreen mode
  • from sklearn.metrics import accuracy_score, confusion_matrix, classification_report นำเข้าโมดูลที่ใช้วัดผล

  • print("Accuracy:", accuracy_score(y_test, y_pred)) คือสัดส่วนของจำนวนที่ทำนายถูกต้องทั้งหมด เช่น
    ถ้า test set มี 10 ตัว และทำนายถูก 8 ตัว จะได้ Accuracy = 0.8 หรือ 80%

  • print("Confusion Matrix:") print(confusion_matrix(y_test, y_pred))คือตารางที่บอกว่าโมเดลทำนายผลแต่ละประเภทอย่างไร เช่น
    [5,1,0]
    [0,2,3]
    [1,1,0]
    จากตัวอย่างอธิบายง่ายๆ แถวแต่ละแถวคือ มังกร,เสือ,เสมอ ที่ออกจริงๆ ส่วนคอลัมน์แต่ละคอลัมน์คือ มังกร,เสือ,เสมอ ที่มีการทำนายไว้
    [5,1,0] 5 คือ ทำนายมังกรถูก 5 ครั้ง ทำนายผิดเป็นเสือ 1 ครั้ง ทำนายผิดเป็นเสมอ 0 ครั้ง
    [0,2,3] 0 คือ ทำนายผิดเป็นมังกร 0 ครั้ง ทำนายเสือถูก 2 ครั้ง ทำนายผิดเป็นเสมอ 3 ครั้ง
    [1,1,0] 1 คือ ทำนายผิดเป็นมังกร 1 ครั้ง ทำนายผิดเป็นเสือ 1 ครั้ง ทำนายเสมอไม่ถูกเลย

  • print("Classification Report:") print(classification_report(y_test, y_pred)) รายงานสรุปค่าความแน่นอน,recall,ประสิทธิภาพ ของโมเดลแต่ละผลลัพธ์

ตัวอย่างผลที่ได้จาก code

Image description

  • อธิบาย Precision = ทายว่าเป็น class นี้ แล้วถูกจริงกี่ %
    Recall = ในบรรดาที่ควรเป็น class นี้ โมเดลทายถูกกี่ %
    F1-score = ค่ากลางระหว่าง precision กับ recall (ค่านี้ยิ่งใกล้ 1.0 ยิ่งดี)
    Support = จำนวนข้อมูลจริงในแต่ละคลาส

  • Class 1 (มังกร): precision 0.48 → ทำนายว่าเป็นมังกร แต่จริงแค่ 48%
    recall 0.65 → ข้อมูลที่ควรเป็นมังกร โมเดลทายถูก 65%

  • Class 2 (เสือ): precision 0.67 → ทำนายว่าเป็นเสือ แล้วถูกจริง 67%
    recall 0.55 → ทำนายเสือถูกประมาณครึ่งหนึ่ง

  • Class 3 (เสมอ): ทุกค่าคือ 0 เพราะโมเดลไม่เคยทำนายว่าเป็นเสมอเลย

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

Reference
https://algoaddict.wordpress.com/2022/02/12/%E0%B8%A1%E0%B8%B2%E0%B8%A5%E0%B8%AD%E0%B8%87%E0%B9%83%E0%B8%8A%E0%B9%89-random-forest-%E0%B8%8A%E0%B9%88%E0%B8%A7%E0%B8%A2%E0%B9%83%E0%B8%99%E0%B8%81%E0%B8%B2%E0%B8%A3%E0%B8%A5%E0%B8%87%E0%B8%97/?utm_source=chatgpt.com




Top comments (0)