Futbolli (futbolli) është sporti më i ndjekur në botë dhe asnjë ngjarje klubi nuk është më e madhe se finalet e UEFA Champions League (UCL). Me finalen mes Manchester Cityt dhe Interit që do të luhet këtë të dielë, siç shihet në tendencat e fundit, ka pasur një rritje të mënyrave të ndryshme të parashikimit të rezultatit të kësaj loje. Ekspertët kanë bërë parashikimet e tyre dhe vezët kanë bërë të tyret. Ekspertët përgjithësisht pajtohen se Manchester City është favorit për të fituar Ligën e Kampionëve këtë vit dhe për të plotësuar kështu trefishin e tyre. Megjithatë, një parashikim që përfshin një tufë vezësh parashikon që Interi do ta fitojë atë. Kjo më bëri të shfrytëzoj fuqinë e të dhënave për të bërë parashikimin tim dhe për të testuar fuqinë e vezës.
Në epokën e Inteligjencës Artificiale dhe informatikës me kompleksitet të lartë, është bërë shumë më e lehtë përdorimi i të dhënave për të bërë parashikimet e veta. Për të arritur qëllimin tim për të parashikuar rezultatin e finaleve të UCL, krijova një program duke përdorur Python3, Keras dhe TensorFlow, NumPy, Pandas, Scikit-learn, SciPy dhe të dhëna nga FBref.
TL;DR
Për ata që janë këtu vetëm për të ditur se çfarë parashikoi AI, rezultati ka të ngjarë të jetë 2–1 për Cityme një shans 67.5% që Manchester City të fitojë në çdo rezultat. Për ata që duan të kuptojnë procesin pas marrjes së këtij parashikimi, lexoni më tej.
Marrja e të dhënave
Ju mund të përdorni një skedar Jupyter Notebook dhe Python për kodin për të parashikuar rezultatet e ndeshjes për sezonin 2022–23 për UCL dhe të dhënat që kam fshirë nga FBref si tre skedarë të Microsoft Excel përmes lidhjes GitHub më poshtë:
Parapërpunimi
Ok, le të fillojmë. Së pari përpunova të dhënat nga tre skedarë duke përfshirë ndeshjet, statistikat e secilit ekip që luan dhe statistikat kundër secilit ekip që luan. I bashkova të dhënat në dy matrica, X (të dhënat që do të hartohen) dhe y (vlerat me të cilat do të hartohen të dhënat në X). X përbëhej nga statistikat e çdo ndeshjeje për një ekip të caktuar (d.m.th., për Chelsea kundër Real, ne do të kishim X të përbërë nga statistikat e Chelsea dhe statistikat e Realit kundër dhe y që përbëhet nga golat e Chelsea të shënuar në lojë). E kam përjashtuar qëllimisht shtëpi/lag në matricën time X pasi finalet nuk janë as në shtëpi e as jashtë për asnjërën skuadër.
#Importing libraries for data processing import pandas as pd import numpy as np #Getting the data (fixtures, team stats, and stats against the team) fixtures = pd.read_excel('Fixtures.xlsx').values stats = pd.read_excel("Team Stats.xlsx").values vs_stats = pd.read_excel("Vs Stats.xlsx").values #Temp is used & re-used to visualize the intermediate steps temp=[] for i in fixtures: temp.append(str(i[1]).split("–")) fixtures = np.delete(fixtures, 1, 1) fixtures = np.append(fixtures, temp, 1) fixturesArranged=[] y = [] for i in fixtures: fixturesArranged.append([i[0], i[1]]) y.append(i[2]) fixturesArranged.append([i[1], i[0]]) y.append(i[3]) #Creating a function that would prepare our dataset for the neural network as a tensor/matrix def process_fixtures(fixturesArranged): temp=[] temp2=[] for i in fixturesArranged: _t1 = str(i[0]).split() print(_t1) _t2 = str(i[1]).split() print(_t2) for j in stats: if ((_t1[0] in str(j[0])) and (_t1[1] in str(j[0]))): temp.append(j) for j in vs_stats: if ((_t2[0] in str(j[0])) and (_t2[1] in str(j[0]))): temp2.append(j) X = np.append(fixturesArranged, temp, 1) X = np.append(X, temp2, 1) X = np.delete(X, [0,1,2], 1) X = np.delete(X, 21, 1) return X from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler sc = StandardScaler() def split_data(): X = process_fixtures(fixturesArranged) #Splitting data into training and testing datasets X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0) #Scaling the data appropriately to impart uniformity to the data X_train = sc.fit_transform(X_train) X_test = sc.transform(X_test) return X_train, X_test, y_train, y_test
Vini re se funksionet përdoren këtu për të lejuar ripërdorimin e të njëjtit proces dhe/ose për ta bërë më të lehtë ndjekjen.
Trajnimi
Më pas, ne krijojmë modelin tonë. Kjo mund të bëhet në mënyra të ndryshme, por unë përdora qasjen vijuese:
from keras.models import Sequential from keras.layers import Dense from keras.layers import Dropout import os checkpoint_path = "/content/ucl.ckpt" checkpoint_dir = os.path.dirname(checkpoint_path) import tensorflow as tf es = tf.keras.callbacks.EarlyStopping(monitor='loss', patience=16) ckpt = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_dir, monitor='loss', verbose=1, save_best_only=True, save_weights_only=True, mode='min') def create_regressor(): # Initialising the regressor regressor = Sequential() # input layer and first hidden layer regressor.add(Dense(units = 32, kernel_initializer = 'uniform', activation = 'relu', input_dim = 46)) regressor.add(Dropout(0.2)) # second hidden layer regressor.add(Dense(units = 16, kernel_initializer = 'uniform', activation = 'relu')) regressor.add(Dropout(0.2)) # third hidden layer regressor.add(Dense(units = 8, kernel_initializer = 'uniform', activation = 'relu')) regressor.add(Dropout(0.2)) # fourth hidden layer regressor.add(Dense(units = 4, kernel_initializer = 'uniform', activation = 'relu')) regressor.add(Dropout(0.2)) # output layer regressor.add(Dense(units = 1, kernel_initializer = 'uniform', activation = 'linear')) # compiling the model regressor.compile(optimizer = 'adam', loss = 'mean_squared_error', metrics = ['accuracy']) return regressor
Përmbledhja e modelit është si më poshtë:
Model: "sequential_2" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense_10 (Dense) (None, 32) 1504 dropout_8 (Dropout) (None, 32) 0 dense_11 (Dense) (None, 16) 528 dropout_9 (Dropout) (None, 16) 0 dense_12 (Dense) (None, 8) 136 dropout_10 (Dropout) (None, 8) 0 dense_13 (Dense) (None, 4) 36 dropout_11 (Dropout) (None, 4) 0 dense_14 (Dense) (None, 1) 5 ================================================================= Total params: 2,209 Trainable params: 2,209 Non-trainable params: 0 _________________________________________________________________
Për të trajnuar modelin, unë thjesht e vendos këtë model në të dhënat e mia X-train dhe y_train, duke përdorur Ndalimin e Hershëm për të përfunduar stërvitjen kur regresori nuk po përmirësohet për periudha të gjata kohore. Unë përdor gjithashtu një pikë kontrolli model për të ruajtur versionin më të mirë të modelit tim, d.m.th., versionin me humbjen më të vogël.
#Training regressor = create_regressor() X_train, X_test, y_train, y_test = split_data() regressor.fit(np.asarray(X_train).astype('float32'), np.asarray(y_train).astype('float32'), batch_size = 10, epochs = 10000, shuffle = True, callbacks=[es,ckpt])
Testimi dhe Vlerësimi
Tani për pak minuta modelja u trajnua. Megjithatë, përpara se të bëja ndonjë parashikim, më duhej të testoja modelin tim dhe të merrja statistika që do të na jepnin njohuri se sa i besueshëm është modeli.
# Evaluating the model preds = regressor.predict(X_test) y_test = np.array([int(i) for i in y_test]) print(y_test) print(preds[:,0]) diff = preds[:,0] - y_test print(diff) mean = np.mean(diff) std = np.std(diff) print("[error_mean: {:.2f}, sample_error_stddev: {:.2f}".format(mean, std))
Zbulova se modeli im kishte një mesatare gabimi prej afërsisht -0.06 dhe një devijim standard prej 1.34, që është një vlerë e respektueshme për një sport të dominuar nga kaosi matematik.
Parashikimet
Tani mund të parashikojmë rezultatin e ndeshjes City-Inter.
import math fixturePred = [["Manchester City eng", "it Inter"], ["it Inter", "Manchester City eng"]] #Manchester City Eng and it Inter were formatting of FBref data X_pred = process_fixtures(fixturePred) X_pred = sc.transform(X_pred) y_pred = np.reshape(regressor.predict(X_pred), (1,-1))[0] print(y_pred) #The regressor's prediction of the scoreline from scipy.stats import norm z_score = ((y_pred[0]-y_pred[1])-mean)/math.sqrt(2*std) p_value = norm.cdf(z_score) #probability that City wins given that errors made by the regressor are independent print(p_value) #The probability that Manchester City wins the game
Mjerisht, modelja arriti në përfundimin e saj. Dhe, përfundimi ishte diçka që ne e presim në këtë pikë: një shans afërsisht 67.5% që Manchester City të fitojë në çdo rezultat, më e mundshme nga të cilat ai parashikoi ishte 1.54–0.8, që në rrumbullakim ishte rezultati 2–1 (si pikët dhjetore nuk janë të mundshme).
Kështu, shanset nuk janë në favor të vezëve me një shans të ulët 32.5% për të fituar (duke supozuar se një barazim zgjidhet përpara gjuajtjeve të penalltive), por kush e di? Sportet, veçanërisht futbolli, janë të njohur për (dhe tërheqës) për shkak të paparashikueshmërisë së tyre.