Spaces:
Sleeping
Sleeping
Upload 5 files
Browse files
.gitattributes
CHANGED
@@ -37,3 +37,4 @@ deliveries.csv filter=lfs diff=lfs merge=lfs -text
|
|
37 |
gru_match_simulation_plot.gif filter=lfs diff=lfs merge=lfs -text
|
38 |
gru_rw_predictor.keras filter=lfs diff=lfs merge=lfs -text
|
39 |
match_momentum_dashboard.gif filter=lfs diff=lfs merge=lfs -text
|
|
|
|
37 |
gru_match_simulation_plot.gif filter=lfs diff=lfs merge=lfs -text
|
38 |
gru_rw_predictor.keras filter=lfs diff=lfs merge=lfs -text
|
39 |
match_momentum_dashboard.gif filter=lfs diff=lfs merge=lfs -text
|
40 |
+
match_live_predictor/gru_score_predictor_rw.keras filter=lfs diff=lfs merge=lfs -text
|
match_live_predictor/gru_score_predictor_rw.keras
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:c6b37bcf62ca560d22dc94033e02817affe1753f720bc9dbdb02086c79fd768e
|
3 |
+
size 211036
|
match_live_predictor/live_predictor.py
ADDED
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# live_predictor.py
|
2 |
+
|
3 |
+
import streamlit as st
|
4 |
+
import numpy as np
|
5 |
+
import pandas as pd
|
6 |
+
import datetime
|
7 |
+
import os
|
8 |
+
import matplotlib.pyplot as plt
|
9 |
+
from tensorflow.keras.models import load_model
|
10 |
+
import joblib
|
11 |
+
|
12 |
+
# App config
|
13 |
+
st.set_page_config(page_title="π IPL Live Match Predictor", layout="wide")
|
14 |
+
st.title("π IPL Live Match Predictor")
|
15 |
+
|
16 |
+
# Match Setup
|
17 |
+
st.header("π Match Setup")
|
18 |
+
col1, col2, col3 = st.columns(3)
|
19 |
+
|
20 |
+
with col1:
|
21 |
+
team_a = st.selectbox("π Team A", ["CSK", "MI", "RCB", "GT", "RR", "LSG", "KKR", "SRH"])
|
22 |
+
with col2:
|
23 |
+
team_b = st.selectbox("π Team B", ["CSK", "MI", "RCB", "GT", "RR", "LSG", "KKR", "SRH"])
|
24 |
+
with col3:
|
25 |
+
venue = st.selectbox("π Venue", ["Wankhede Stadium", "Chepauk", "Eden Gardens", "Narendra Modi Stadium", "Chinnaswamy Stadium"])
|
26 |
+
|
27 |
+
match_date = st.date_input("π
Match Date", datetime.date.today())
|
28 |
+
match_status = st.radio("πΆ Match Status", ["Scheduled", "In Progress", "Completed"])
|
29 |
+
|
30 |
+
# Section: Simulate Match Data
|
31 |
+
st.header("π² Simulate Over-wise Runs & Wickets")
|
32 |
+
|
33 |
+
if st.button("π Generate Match"):
|
34 |
+
overs = list(range(1, 21))
|
35 |
+
runs_this_over = np.random.randint(0, 21, size=20) # realistic run range
|
36 |
+
wickets_this_over = np.random.binomial(1, 0.3, size=20)
|
37 |
+
|
38 |
+
cumulative_runs = np.cumsum(runs_this_over)
|
39 |
+
cumulative_wickets = np.cumsum(wickets_this_over)
|
40 |
+
|
41 |
+
df = pd.DataFrame({
|
42 |
+
"Over": overs,
|
43 |
+
"Runs_This_Over": runs_this_over,
|
44 |
+
"Cumulative_Runs": cumulative_runs,
|
45 |
+
"Wickets_This_Over": wickets_this_over,
|
46 |
+
"Cumulative_Wickets": cumulative_wickets
|
47 |
+
})
|
48 |
+
|
49 |
+
st.session_state["live_df"] = df
|
50 |
+
st.success(f"π {team_a} vs {team_b} at {venue} on {match_date}")
|
51 |
+
st.dataframe(df, use_container_width=True)
|
52 |
+
|
53 |
+
# GRU Prediction
|
54 |
+
if "live_df" in st.session_state:
|
55 |
+
df = st.session_state["live_df"]
|
56 |
+
st.subheader("π Predicted Final Score (GRU Model)")
|
57 |
+
|
58 |
+
try:
|
59 |
+
# Load model and scalers
|
60 |
+
model_path = os.path.join("match_live_predictor", "gru_score_predictor_rw.keras")
|
61 |
+
input_scaler_path = os.path.join("match_live_predictor", "scaler_input_rw.save")
|
62 |
+
output_scaler_path = os.path.join("match_live_predictor", "scaler_output_rw.save")
|
63 |
+
|
64 |
+
model = load_model(model_path, compile=False)
|
65 |
+
scaler_input = joblib.load(input_scaler_path)
|
66 |
+
scaler_output = joblib.load(output_scaler_path)
|
67 |
+
|
68 |
+
# Prepare input
|
69 |
+
match_input = df[["Runs_This_Over", "Wickets_This_Over"]].values
|
70 |
+
padded_input = np.pad(match_input, ((0, 20 - len(match_input)), (0, 0)), mode="constant")
|
71 |
+
|
72 |
+
scaled_input = scaler_input.transform(padded_input)
|
73 |
+
reshaped_input = scaled_input.reshape(1, 20, 2)
|
74 |
+
|
75 |
+
# Predict final score
|
76 |
+
pred_scaled = model.predict(reshaped_input, verbose=0)
|
77 |
+
predicted_final = scaler_output.inverse_transform(pred_scaled)[0][0]
|
78 |
+
|
79 |
+
# Display predicted score
|
80 |
+
st.success(f"π― Predicted Final Score: {predicted_final:.2f} runs")
|
81 |
+
|
82 |
+
# Visualization
|
83 |
+
fig, ax1 = plt.subplots(figsize=(10, 4))
|
84 |
+
|
85 |
+
ax1.plot(df["Over"], df["Cumulative_Runs"], marker='o', label="Cumulative Runs", color="green")
|
86 |
+
ax1.set_xlabel("Overs")
|
87 |
+
ax1.set_ylabel("Runs", color="green")
|
88 |
+
ax1.tick_params(axis='y', labelcolor="green")
|
89 |
+
ax1.set_title("π Match Progression & GRU Prediction")
|
90 |
+
|
91 |
+
ax2 = ax1.twinx()
|
92 |
+
ax2.bar(df["Over"], df["Wickets_This_Over"], alpha=0.3, color="red", label="Wickets")
|
93 |
+
ax2.set_ylabel("Wickets", color="red")
|
94 |
+
ax2.tick_params(axis='y', labelcolor="red")
|
95 |
+
|
96 |
+
plt.axhline(y=predicted_final, color="blue", linestyle="--", label="Predicted Final")
|
97 |
+
fig.legend(loc="upper left", bbox_to_anchor=(0.1, 0.85))
|
98 |
+
st.pyplot(fig)
|
99 |
+
|
100 |
+
except Exception as e:
|
101 |
+
st.error(f"β οΈ Prediction module error: {e}")
|
102 |
+
|
103 |
+
# Footer
|
104 |
+
st.markdown("""
|
105 |
+
---
|
106 |
+
π¨βπ» Built by Dinesh Kumar | Powered by Streamlit, GRU, NumPy
|
107 |
+
""")
|
match_live_predictor/scaler_input_rw.save
ADDED
Binary file (749 Bytes). View file
|
|
match_live_predictor/scaler_output_rw.save
ADDED
Binary file (725 Bytes). View file
|
|
match_live_predictor/train_gru_rw_model.py
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# train_gru_rw_model.py
|
2 |
+
|
3 |
+
import numpy as np
|
4 |
+
import pandas as pd
|
5 |
+
from tensorflow.keras.models import Sequential
|
6 |
+
from tensorflow.keras.layers import GRU, Dense, Input
|
7 |
+
from sklearn.preprocessing import MinMaxScaler
|
8 |
+
import joblib
|
9 |
+
import os
|
10 |
+
|
11 |
+
# Simulate realistic training data
|
12 |
+
np.random.seed(42)
|
13 |
+
X = []
|
14 |
+
y = []
|
15 |
+
|
16 |
+
for _ in range(1000):
|
17 |
+
runs = np.random.randint(1, 15, size=20)
|
18 |
+
wickets = np.random.binomial(1, 0.3, size=20)
|
19 |
+
|
20 |
+
input_seq = np.column_stack((runs, wickets))
|
21 |
+
X.append(input_seq)
|
22 |
+
|
23 |
+
final_score = np.sum(runs)
|
24 |
+
y.append(final_score)
|
25 |
+
|
26 |
+
X = np.array(X) # Shape: (1000, 20, 2)
|
27 |
+
y = np.array(y).reshape(-1, 1) # Shape: (1000, 1)
|
28 |
+
|
29 |
+
# Fit scalers
|
30 |
+
scaler_input = MinMaxScaler()
|
31 |
+
scaler_output = MinMaxScaler()
|
32 |
+
|
33 |
+
X_scaled = np.array([scaler_input.fit_transform(x) for x in X])
|
34 |
+
y_scaled = scaler_output.fit_transform(y)
|
35 |
+
|
36 |
+
# Save scalers
|
37 |
+
os.makedirs("match_live_predictor", exist_ok=True)
|
38 |
+
joblib.dump(scaler_input, "match_live_predictor/scaler_input_rw.save")
|
39 |
+
joblib.dump(scaler_output, "match_live_predictor/scaler_output_rw.save")
|
40 |
+
|
41 |
+
# Build GRU model
|
42 |
+
model = Sequential([
|
43 |
+
Input(shape=(20, 2)),
|
44 |
+
GRU(64, return_sequences=False),
|
45 |
+
Dense(32, activation='relu'),
|
46 |
+
Dense(1)
|
47 |
+
])
|
48 |
+
|
49 |
+
model.compile(optimizer='adam', loss='mse')
|
50 |
+
model.fit(X_scaled, y_scaled, epochs=50, batch_size=32, verbose=1)
|
51 |
+
|
52 |
+
# Save model
|
53 |
+
model.save("match_live_predictor/gru_score_predictor_rw.keras")
|
54 |
+
print("GRU model retrained and saved successfully!")
|
55 |
+
|