คาดการณ์ผลคะแนน IPL (Indian Premier League)โดยใช้ RNN ( Recurrent Neural Network)
Tags: ai, python, ipl
Published: 2024-04-02 15:25:22

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

โดยในบทความนี้จะมาดูวิธีการคาดเดาผลการแข่งขันโดยใช้ RNN (Recurrent Neural Network) ซึ่งเป็นโมเดล Deep Learning ประเภทหนึ่งที่เหมาะสำหรับการประมวลผลข้อมูลแบบลำดับ (Sequential data) โดยกระบวนการทำจะทำใน Google colab ส่วน Dataset ที่นำมาใช้จะเป็นข้อมูลสถิติต่างๆของแต่ละทีมใน IPL ตั้งแต่ปี 2008 - 2017 

---

## ขั้นตอนการทำ

1 <u>นำเข้า Library ที่จำเป็นต้องใช้ ลงใน Google colab</u>

```
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import preprocessing
import keras
import tensorflow as tf
```

2 <u>นำข้อมูลทั้งสองชุดเข้า Google colab และใช้ .read_csv() เก็บข้อมูลไว้ในรูปแบบของ Dataframe ผ่าน Pandas และแสดงตัวอย่างข้อมูล 5 แถวแรกของแต่ละชุด</u>

ดาวน์โหลดข้อมูล: {% embed https://drive.google.com/file/d/1qlm4OnaAM3bdgti9xyUqK3eSFokjYdA-/view %}

การนำข้อมูลเข้า Google colab สามารถกดอัปโหลดใน google colab ได้ผ่านปุ่มรูปโฟลเดอร์ตามภาพ


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0xv0mypax8opk6c47v8d.png)

Code อ่านไฟล์csvและแสดงผล5แถวแรกของข้อมูล

```
ipl = pd.read_csv('ipl_dataset.csv')
ipl.head()
```

ภาพตัวอย่างข้อมูล 5 แถวแรก


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/07ufdi6xogo5sfjz2pvr.png)


3 <u>เตรียมข้อมูลโดยสร้างชุดข้อมูลชุดใหม่ที่ตัดข้อมูลบางส่วนจากชุดข้อมูลดั้งเดิม โดยจะเก็บไว้เฉพาะข้อมูลที่ต้องการนำมาใช้เท่านั้น</u>

Code เตรียมข้อมูลชุดใหม่
```
#Dropping certain features
df = ipl.drop(['date', 'runs', 'wickets', 'overs', 'runs_last_5', 'wickets_last_5','mid', 'striker', 'non-striker'], axis =1)
```
4 <u>เตรียมข้อมูลเพิ่มเติมโดยจะแบ่งชุดข้อมูลออกเป็น 2 ส่วน คือ ตัวแปรอิสระ (X) และตัวแปรตาม (y) โดยตัวแปรตามหรือ ค่า y ของเราคือคะแนนรวม</u> 

```
X = df.drop(['total'], axis =1)
y = df['total']
```
5 <u>แปลงข้อมูลที่เป็นข้อความใน dataset ด้วยการ label encoding โดยจะทำการกำหนดค่าให้กับข้อมูลต่างๆและสร้าง mapping เพื่อให้สามารถแปลงค่ากลับคืนสู่ข้อมูลเดิมเพื่อให้ระบบวิเคราะห์ผลได้ง่าย</u>

```
#Label Encoding

from sklearn.preprocessing import LabelEncoder

# Create a LabelEncoder object for each categorical feature
venue_encoder = LabelEncoder()
batting_team_encoder = LabelEncoder()
bowling_team_encoder = LabelEncoder()
striker_encoder = LabelEncoder()
bowler_encoder = LabelEncoder()

# Fit and transform the categorical features with label encoding
X['venue'] = venue_encoder.fit_transform(X['venue'])
X['bat_team'] = batting_team_encoder.fit_transform(X['bat_team'])
X['bowl_team'] = bowling_team_encoder.fit_transform(X['bowl_team'])
X['batsman'] = striker_encoder.fit_transform(X['batsman'])
X['bowler'] = bowler_encoder.fit_transform(X['bowler'])
```
6 <u>แบ่งข้อมูลเป็นชุดฝึก (Train data) และ ชุดทดสอบ (Test data)</u>
โดยจะแบ่งข้อมูลทั้งหมดออกเป็น 2 ชุด: ชุดฝึก (70%) และชุดทดสอบ (30%)
ชุดฝึก : โมเดล AI เราจะใช้ข้อมูลส่วนนี้ในการฝึกฝน
ชุดทดสอบ : โมเดล AI เราใช้ข้อมูลส่วนนี้ในการประเมินประสิทธิภาพของโมเดล

แยกข้อมูลตามประเภท

X_train เก็บข้อมูล ตัวแปรอิสระ (Input Features) สำหรับชุดฝึก
X_test เก็บข้อมูล ตัวแปรอิสระ (Input Features) สำหรับชุดทดสอบ
y_train เก็บข้อมูล ตัวแปรตาม (Target Variable) สำหรับชุดฝึก 
y_test เก็บข้อมูล ตัวแปรตาม (Target Variable) สำหรับชุดทดสอบ

```
# Train test Split
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
```
7 <u>ปรับขนาดฟีเจอร์ (Feature Scaling)</u>
การปรับขนาดฟีเจอร์จะเหมือนการปรับขนาดไม้บรรทัดให้ทุกฟีเจอร์อยู่บนมาตรฐานเดียวกัน
ช่วยให้โมเดล AI ทำงานได้ดีขึ้น
เราใช้เทคนิค Min-Max Scaling กับฟีเจอร์ ตัวแปรอิสระ (X) ทั้งในชุดฝึกและชุดทดสอบ

```
from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()

# Fit the scaler on the training data and transform both training and testing data
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
```
8 <u>ในขั้นตอนนี้จะออกแบบและปรับแต่ง Neural Network ที่เหมาะสมกับการคาดเดาผลการแข่งขันของAI โดยใช้ code โครงสร้าง RNN (Recurrent Neural Network)</u>

```
# Define the neural network model
model = keras.Sequential([
	keras.layers.Input( shape=(X_train_scaled.shape[1],)), # Input layer
	keras.layers.Dense(512, activation='relu'), # Hidden layer with 512 units and ReLU activation
	keras.layers.Dense(216, activation='relu'), # Hidden layer with 216 units and ReLU activation
	keras.layers.Dense(1, activation='linear') # Output layer with linear activation for regression
])

# Compile the model with Huber loss
huber_loss = tf.keras.losses.Huber(delta=1.0) # You can adjust the 'delta' parameter as needed
model.compile(optimizer='adam', loss=huber_loss) # Use Huber loss for regression
```
9 <u>ฝึกโมเดล</u>

```
# Train the model
model.fit(X_train_scaled, y_train, epochs=50, batch_size=64, validation_data=(X_test_scaled, y_test))
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gnsedn58uw0819sdyodx.png)

โดยเราสามารถฝึกโมเดลด้วยเมธอด `fit` และหลังจากการฝึกจะเก็บค่า Loss ไว้ของข้อมูลชุดฝึกและชุดทดสอบโดย 
ค่า Loss ยิ่งน้อย = AI ทำงานได้แม่นยำมาก

Code plotกราฟค่า loss

```
model_losses = pd.DataFrame(model.history.history)
model_losses.plot()
```
ผลลัพท์

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oyz9h7jwph0ngmnrvgyf.png)

10 <u>ประเมินผลโมเดล</u>
ในขั้นตอนนี้ เราทดสอบโมเดลด้วยชุดทดสอบ และเก็บผลลัพธ์ไว้ในตัวแปร `predictions = model.predict(X_test_scaled)` คะแนนนี้เป็นคะแนนจากการทดสอบการคาดเดาผลที่โมเดลเรียนรู้

```
# Make predictions
predictions = model.predict(X_test_scaled)

from sklearn.metrics import mean_absolute_error,mean_squared_error
mean_absolute_error(y_test,predictions)
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yuywnc97hfe8k6tey177.png)

11 <u>สร้าง Interactive widget </u>

```
import ipywidgets as widgets
from IPython.display import display, clear_output

import warnings
warnings.filterwarnings("ignore")

venue = widgets.Dropdown(options=df['venue'].unique().tolist(),description='Select Venue:')
batting_team = widgets.Dropdown(options =df['bat_team'].unique().tolist(), description='Select Batting Team:')
bowling_team = widgets.Dropdown(options=df['bowl_team'].unique().tolist(), description='Select Batting Team:')
striker = widgets.Dropdown(options=df['batsman'].unique().tolist(), description='Select Striker:')
bowler = widgets.Dropdown(options=df['bowler'].unique().tolist(), description='Select Bowler:')

predict_button = widgets.Button(description="Predict Score")

def predict_score(b):
	with output:
		clear_output() # Clear the previous output


		# Decode the encoded values back to their original values
		decoded_venue = venue_encoder.transform([venue.value])
		decoded_batting_team = batting_team_encoder.transform([batting_team.value])
		decoded_bowling_team = bowling_team_encoder.transform([bowling_team.value])
		decoded_striker = striker_encoder.transform([striker.value])
		decoded_bowler = bowler_encoder.transform([bowler.value])


		input = np.array([decoded_venue, decoded_batting_team, decoded_bowling_team,decoded_striker, decoded_bowler])
		input = input.reshape(1,5)
		input = scaler.transform(input)
		#print(input)
		predicted_score = model.predict(input)
		predicted_score = int(predicted_score[0,0])

		print(predicted_score)
```

```
predict_button.on_click(predict_score)
output = widgets.Output()
display(venue, batting_team, bowling_team, striker, bowler, predict_button, output)
```

---

## การใช้งานโมเดล

เมื่อกดรัน code 

```
predict_button.on_click(predict_score)
output = widgets.Output()
display(venue, batting_team, bowling_team, striker, bowler, predict_button, output)
```
จะมีหน้า widget ขึ้นมาให้กด

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ifjf6s981g5bwf0nozx0.png)

โดยเราสามารถเลือก สนามที่ใช้แข่งขัน, ทีมที่เข้าแข่งขันทั้ง 2 ทีม, ผู้เล่นตำแหน่ง striker ในเกมนัดนั้นและผู้เล่นตำแหน่ง bowler ในเกมนัดนั้น
เมื่อเลือกครบให้กด Predict score จะสามารถใช้งาน AI ได้

ตัวอย่างผลลัพท์ที่ได้ : 
1 สนามแข่ง : M Chinnaswamy stadium
  ทีมที่แข่ง : Kollkata Knight Rider และ Royal Challengers Bangalore
  ผู้เล่นตำแหน่ง Striker : DJ Hussey
  ผู้เล่นตำแหน่ง Bowler : B Akhil
  ผลคะแนนของการแข่งขัน : 174


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pe72ird79mnd92ejya6z.png)

2 สนามแข่ง : M Chinnaswamy stadium
  ทีมที่แข่ง : Mumbai Indians และ Delhi Daredevils
  ผู้เล่นตำแหน่ง Striker : M Ntini
  ผู้เล่นตำแหน่ง Bowler : D wiese
  ผลคะแนนของการแข่งขัน : 161

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/74s9ipeqiorc7dbl3nr9.png)

---

## สรุปผล

จากผลการทดลองใช้ AI คาดเดาผลการแข่งขัน IPL ซึ่งสามารถคาดเดาผลคะแนนของเกมแต่ละนัดออกมาได้ชัดเจน โดยใช้ RNN (Recurrent Neural Network) โดยความแม่นยำจะขึ้นอยู่กับจำนวนของข้อมูลที่นำมาใช้ฝึกซึ่งสังเกตุได้จากกราฟค่า Loss ที่น้อยลงอย่างต่อเนื่อง 
โดยหากผู้อ่านที่เป็นแฟนกีฬาคริกเก็ตอยากให้ AI คาดเดาผลการแข่งขันได้แม่นยำมากขึ้นก็สามารถหาข้อมูลที่เป็นปัจจุบันและมากพอให้ AI สามารถฝึกฝนเพื่อให้ทำงานได้ดีขึ้นได้เพื่อความสนุกในการติดตามผลการแข่งขันในอนาคตได้เช่นกันครับ

---
อ้างอิง

1 
https://www.geeksforgeeks.org/ipl-score-prediction-using-deep-learning/?ref=rp

2 https://drive.google.com/file/d/1qlm4OnaAM3bdgti9xyUqK3eSFokjYdA-/view