"Kemenangan kecerdasan buatan atas pakar sepak bola" - ini bisa menjadi judul artikel ini tentang hasil kompetisi sepakbola. Bisa, tetapi, sayangnya, tidak.
Selama Piala Dunia, di perusahaan kami "
NORBIT " mengadakan kompetisi untuk pertandingan ramalan sepakbola terbaik. Saya terlalu berpengalaman dalam sepakbola untuk mengklaim apa pun, tetapi keinginan untuk ikut serta dalam kompetisi masih menang karena kemalasan saya. Di bawah potongan - sebuah cerita tentang bagaimana, berkat pembelajaran mesin, saya berhasil mencapai hasil yang baik di antara para ahli di tim sepak bola. Benar, saya gagal mencapai jackpot, tetapi saya menemukan dunia baru yang menarik dari Ilmu Data.
Saya mulai dengan hipotesis bahwa, di samping keterampilan individu pemain tim nasional, masih ada banyak faktor yang tak terukur, tetapi penting - semangat tim + kerja tim (misalnya, tim dalam permainan dengan lawan yang lebih kuat, tetapi dalam pertandingan uji dan di lapangan mereka lebih sering menang). Tugas ini tidak begitu sederhana untuk seseorang, tetapi cukup dimengerti untuk pembelajaran mesin.
Saya pernah punya sedikit pengalaman bekerja dengan ML (dengan perpustakaan BrainJS), tetapi kali ini saya memutuskan untuk memeriksa pernyataan bahwa Python jauh lebih cocok untuk tugas-tugas seperti itu.
Saya mulai perkenalan saya dengan Python dengan kursus yang sangat baik tentang
Coursera , dan saya belajar dasar-dasar pembelajaran mesin dari serangkaian artikel dari Open Data Science on
HabrΓ© .
Cukup cepat saya menemukan
Dataset yang sangat baik dengan sejarah semua pertandingan tim internasional sejak awal abad ke-20. Setelah mengimpor ke dalam kerangka data Pandas:
Secara total, database berisi informasi tentang 39 ribu permainan tim internasional.
Pandas membuatnya sangat nyaman untuk menganalisis data, misalnya, pertandingan paling produktif adalah antara Australia dan Samoa Amerika pada tahun 2001, yang berakhir dengan skor
31: 0 .
Sekarang Anda perlu menambahkan penilaian objektif tingkat tim pada tahun pertandingan. Penilaian ini ditangani oleh FIFA.
Namun, sayangnya, peringkat FIFA baru dilakukan sejak 1992. Dan, dilihat dari jadwal, peringkat tim sangat rentan terhadap perubahan, dan saya benar-benar tidak ingin rata-rata posisi tim di peringkat dunia hingga tahun ini.
UEFA menyimpan statistiknya dari zaman yang lebih kuno, tetapi saya tidak dapat menemukan dataset yang sudah siap, jadi
situs ini datang untuk menyelamatkan. Di bawah Node.js ada
Cheerio yang kuat dan nyaman untuk tugas-tugas seperti itu, tetapi di bawah Python semuanya ternyata tidak kurang sederhana (maafkan saya administrator situs ini).
Peringkat kerokan webfrom requests import get from requests.exceptions import RequestException from contextlib import closing from bs4 import BeautifulSoup def query_url(url): try: with closing(get(url, stream=True)) as resp: if is_good_response(resp): return resp.content else: return None except RequestException as e: log_error('Error during requests to {0} : {1}'.format(url, str(e))) return None def is_good_response(resp): content_type = resp.headers['Content-Type'].lower() return (resp.status_code == 200 and content_type is not None and content_type.find('html') > -1) def log_error(e): print(e) def parse_ranks(raw_html, year): html = BeautifulSoup(raw_html, 'html.parser') ranks = [] for tr in html.select('tr'): tds = tr.select("td") if len(tds) == 10: rank = (year, tds[2].text, tds[7].text) ranks.append(rank) return ranks def get_url(year): if year in range(1960, 1999): method = 1 if year in range(1999, 2004): method = 2 if year in range(2004, 2009): method = 3 if year in range(2009, 2018): method = 4 if year in range(2018, 2019): method = 5 return f"https://kassiesa.home.xs4all.nl/bert/uefa/data/method{method}/crank{year}.html" ranks = [] for year in range(1960, 2019): url = get_url(year) print(url) raw_html = query_url(url) rank = parse_ranks(raw_html, year) ranks += rank with open('team_ranks.csv', 'w') as f: writer = csv.writer(f , lineterminator='\n') writer.writerow(['year', 'country', 'rank']) for rank in ranks: writer.writerow(rank)
Fluktuasi peringkat setelah menambahkan peringkat UEFA (dan sedikit revisi nama-nama negara sesuai dengan hasil castling geopolitik):
Tetapi bahkan di sini, satu tong tar tidak dibagikan - UEFA hanya mengurutkan tim-tim Eropa (Anda terkadang perlu memikirkan apa yang disembunyikan di bawah singkatan umum sebelum menggunakannya). Untungnya, babak playoff telah berkembang hampir "Eropa".
Tetap sedikit lebih nyaman untuk membagi hasil menjadi permainan yang terpisah dan menambahkan peringkat ke tabel.
Bagian yang paling menarik adalah pelatihan model. Google segera menyarankan opsi paling sederhana dan tercepat - ini adalah MLPClassifier dari Python library - Sklearn. Mari kita coba latih model menggunakan contoh Swedia.
from sklearn.neural_network import MLPClassifier games = pd.read_csv('games.csv')
Akurasi: 0,62Tidak jauh lebih akurat daripada melempar koin, tapi mungkin sudah lebih baik dari perkiraan "ahli" potensial saya. Akan masuk akal untuk mencoba memperkaya data, bermain dengan hyperparameters, tapi saya memutuskan untuk pergi ke arah lain dan mencoba meningkatkan Yandex gradien perpustakaan
Boost . Di satu sisi, ini lebih patriotik, di sisi lain, mereka menjanjikan karya berkualitas dengan atribut kategoris, yang dikonfirmasi oleh berbagai
perbandingan .
Mengambil pengaturan dari
contoh :
Akurasi: 0,73Sudah lebih baik, coba dalam praktek.
def get_prediction(country, against): y = SwdenGames['score'] y = y.astype('int') X = SwdenGames.drop(['score', 'againstTitle'], axis=1) train_pool = Pool(X, y, cat_features=[1, 2, 4]) query = [ get_team_rank(country, 2018), 0, 1 if country == 'Russia' else 0, get_team_rank(against, 2018), against] return cb_model.predict_proba([query])[0] team_1 = 'Belgium' team_2 = 'France' result = get_prediction(team_1, team_2) if result[0] > result[1]: print(f" {team_1} {team_2} {result[0]*100:.1f}%") else: print(f" {team_1} {team_2} {result[1]*100:.1f}%")
Hasil Prediksi untuk Final βTim Crotia Kalah dari Tim Prancis dengan Kemungkinan 93,7%β
Meskipun kali ini saya tidak memenangkan kontes
NORBIT , saya sangat berharap artikel ini akan mengurangi tingkat sihir bagi seseorang dalam penggunaan praktis pembelajaran mesin, atau bahkan mungkin memotivasi saya untuk melakukan eksperimen sendiri.