Compare commits

..

22 Commits

Author SHA1 Message Date
811964e519 readme update and add user instructions 2024-03-09 11:15:21 +00:00
020857a1e7 zmiana leyotu prawegomenu oraz pozycji licznika eX 2024-01-20 20:21:48 +01:00
2d338824f8 usuniecie auomatycznego liczenia 2024-01-20 20:15:03 +01:00
234d08d0c1 naprawa danych kategorycznych 2024-01-20 17:47:55 +01:00
ffe2c13cdf model update 2024-01-20 17:18:19 +01:00
7bbe593dde more data training 2024-01-20 12:55:53 +01:00
09ebd98fb4 train model on new data 2024-01-20 09:26:51 +01:00
Maciej Chmielarz
9b7136b1af Naprawienie checklisty 2024-01-20 00:59:24 +01:00
Maciej Chmielarz
db214d217e Naprawa kategorycznych, Zmiana zapisywania/wczytywania xgboost 2024-01-19 15:25:32 +01:00
Szymon Obst
3749cf22b0 dodanie automatycznego liczenie eX , naprawa bledu zlego generowania kafelkow zawodnikow 2024-01-15 16:33:39 +01:00
5b3ae8684e dodanie ograniczen dodawania pilkarzy 2024-01-14 23:00:13 +01:00
378c897959 kilka mniejszych bledow 2024-01-14 22:01:50 +01:00
1b42cd208b small data and model improvement 2024-01-12 20:39:14 +01:00
412dd57577 Dodanie wszystkich zmiennych z modelu do apki oraz ich obsługa 2024-01-11 20:10:52 +01:00
f93d8c5c67 dodanie nowych parametrów do apki plus edycja UI 2024-01-11 17:32:16 +01:00
Maciej Chmielarz
cd5efc6921 zmiany ustawien domyslnych na angielskie nazwy 2024-01-09 15:34:52 +01:00
Maciej Chmielarz
0da7ccae42 zmiany server.py, ogarniecie xgboosta 2024-01-09 15:26:35 +01:00
Maciej Chmielarz
fc85d2f8f6 Merge branch 'modServera' of https://git.wmi.amu.edu.pl/s478993/fantastyczne_gole into modServera 2024-01-09 00:40:06 +01:00
Maciej Chmielarz
7a49396823 zmiana xgboost, zmiana typu danych, dodanie wartosci domyslnych 2024-01-09 00:39:38 +01:00
e03d8b48af work work work 2024-01-08 23:02:58 +01:00
f96465ed56 zmiana jezyka zmiennych kategorycznych 2024-01-08 22:50:39 +01:00
0b3e58f05e some work 2024-01-08 22:32:55 +01:00
29 changed files with 320629 additions and 38861 deletions

BIN
.DS_Store vendored

Binary file not shown.

BIN
.RData Normal file

Binary file not shown.

Binary file not shown.

View File

@ -1,4 +1,4 @@
# Analiza piłkarska z aplikacją `CoachStats` # Aplikacja `CoachStats`
## Wstęp ## Wstęp
@ -9,21 +9,18 @@ CoachStats to innowacyjne narzędzie służące do analizowania statystyk Expect
- **Analiza XG:** Analiza XG dla danej sytuacji meczowej. - **Analiza XG:** Analiza XG dla danej sytuacji meczowej.
- **Personalizowana makieta:** Możliwość tworzenia własnej makiety odpowiadającej sytuacji meczowej. - **Personalizowana makieta:** Możliwość tworzenia własnej makiety odpowiadającej sytuacji meczowej.
## Technologie ## Uruchomienie
## Instalacja i Uruchomienie Aby uruchomić aktualną wersję aplikacji, wykonaj następujące kroki:
Aby uruchomić beta wersję aplikacji, wykonaj następujące kroki: 1. **Uruchomienie serwera:** Aby uruchomić serwer należy wejść w [link](https://sg-server-ne4h.onrender.com/) oraz zaczekać do pojawienia się komunikatu o błędzie 404. Aplikacja korzysta z darmowej wersji obsługi serwera, stąd sposób jego uruchomienia nie jest standardowy.
1. **Uruchomienie Klienta:** 2. **Uruchomienie aplikacji webowej** Po wykonaiu kroku 1 można wejść na właściwą stronę [aplikacji](https://statgoals.onrender.com/).
Otwórz terminal w folderze `app` i uruchom następującą komendę:\
`npm run dev`
2. **Uruchomienie Serwera Flask:**
W innym terminalu, przejdź do folderu `app/src/flask-server` i uruchom serwer Flask przy użyciu poniższej komendy:\
`python server.py`
## Dane ## Dane
- <https://statsbomb.com/what-we-do/soccer-data/> - <https://statsbomb.com/what-we-do/soccer-data/>
## Szczegóły
Działanie aplikacji zostało opisane w podręczniku użytkownika znajdującym się w drzewie plików na repozytorium. Poza tym odsyłam do [repozytorium](https://git.wmi.amu.edu.pl/s478993/fantastyczne_gole) uniwersytetu na którym powstała aplikacja. Zawiera ono kod źródłowy aplikacji.

BIN
app/src/assets/bramka.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

View File

@ -5,11 +5,49 @@ import { Link } from "react-router-dom";
const Hero = () => { const Hero = () => {
const [isOpen, setIsOpen] = useState(false);
const [gameMinute, setGameMinute] = useState(''); const [gameMinute, setGameMinute] = useState('');
const toggleDropdown = () => setIsOpen(!isOpen); const [firstShot, setfirstShot] = useState(0);
const handleMinuteChange = (e) => setGameMinute(e.target.value); const [oneOnOne, SetoneOnOne] = useState(0);
const [afterAirDuel, SetafterAirDuele] = useState(0);
const [openGoal, SetOpenGoal] = useState(0);
const [afterDribbling, SetafterDribbling] = useState(0);
const [redirect, SetRedirect] = useState(0);
const handleMinuteChange = (e) => { setGameMinute(e.target.value);
//sentQuestion();
}
const handleFirstShotChange = (event) => {
setfirstShot(event.target.checked);
//sentQuestion();
};
const handleOneOnOneChange = (event) => {
SetoneOnOne(event.target.checked);
//sentQuestion();
};
const handleAfterAirDuelChange = (event) => {
SetafterAirDuele(event.target.checked);
//sentQuestion();
};
const handleOpenGoalChange = (event) => {
SetOpenGoal(event.target.checked);
//sentQuestion();
};
const handleAfterDribblingChange = (event) => {
SetafterDribbling(event.target.checked);
//sentQuestion();
};
const handleRedirectChange = (event) => {
SetRedirect(event.target.checked);
//sentQuestion();
};
const [data, setData] = useState(""); const [data, setData] = useState("");
//zmienne globalne //zmienne globalne
@ -17,10 +55,24 @@ const Hero = () => {
//przez listener nanoszący zawodników na boisko. 1 - strzelec , 2 - bramkarz , 3 - obronca, 4 - napasnik. zmienna przez aktywacje przycskówk bb1, bb2, bb3 i bb4 //przez listener nanoszący zawodników na boisko. 1 - strzelec , 2 - bramkarz , 3 - obronca, 4 - napasnik. zmienna przez aktywacje przycskówk bb1, bb2, bb3 i bb4
let active_bbt = "bbt1"; let active_bbt = "bbt1";
const [number_of_defenders, setNumberOfDevenders] = useState(0); const [number_of_defenders, setNumberOfDevenders] = useState(()=>{
const [number_of_strikers, setNumberOfStrikers] = useState(0) return 0;
const [number_of_goalkeepers, setNumberOfGoalkeppers] = useState(0); });
const [number_of_shooters,setNumberOfShooters] = useState(0);
const [number_of_strikers, setNumberOfStrikers] = useState(() => {
return 0;
})
const [number_of_goalkeepers, setNumberOfGoalkeppers] = useState(()=>{
return 0;
});
const [number_of_shooters,setNumberOfShooters] = useState(() => {
return 0}
);
const number_of_shooters_rev = React.useRef(number_of_shooters)
const number_of_strikers_rev = React.useRef(number_of_strikers)
const number_of_goalkeepers_rev = React.useRef(number_of_goalkeepers)
const number_of_defenders_rev = React.useRef(number_of_defenders)
// zmienne globalne bedace danymi wejsciowymi do modelu // zmienne globalne bedace danymi wejsciowymi do modelu
@ -30,10 +82,10 @@ const Hero = () => {
var stricers = new Array; var stricers = new Array;
var defenders = new Array; var defenders = new Array;
const [bodyPart,setBodyPart] = useState('prawa'); const [bodyPart,setBodyPart] = useState('Right Foot');
const [technique,setTechnique] = useState('zwykly'); const [technique,setTechnique] = useState('Normal');
const [actionType,setActionType] = useState('pozycyjny'); const [actionType,setActionType] = useState('Open Play');
const [shooterPossition,setPossition] = useState('napastnik'); const [shooterPossition,setPossition] = useState('Center Forward');
//zamiana procentowych pozycji na kartezyjskie //zamiana procentowych pozycji na kartezyjskie
function konwerturX(x){ function konwerturX(x){
@ -57,7 +109,6 @@ const Hero = () => {
// Reset Boiska // Reset Boiska
function resetField() { function resetField() {
var footballField = document.getElementById('footballField'); var footballField = document.getElementById('footballField');
var footballs = document.querySelectorAll('.football'); var footballs = document.querySelectorAll('.football');
var list = document.getElementById('list') var list = document.getElementById('list')
@ -69,13 +120,20 @@ const Hero = () => {
players.forEach(function(element) { players.forEach(function(element) {
list.removeChild(element); list.removeChild(element);
}) })
setNumberOfDevenders(0); setNumberOfDevenders(0);
setNumberOfStrikers(0) setNumberOfStrikers(0)
setNumberOfGoalkeppers(0) setNumberOfGoalkeppers(0)
setNumberOfShooters(0) setNumberOfShooters(0)
setGameMinute('')
number_of_shooters_rev.current = 0;
number_of_goalkeepers_rev.current = 0;
number_of_defenders_rev.current = 0;
number_of_strikers_rev.current = 0;
document.getElementById("ex").innerHTML = 0;
} }
//funkcja dodaje zawodnika do listy zawodnikow. zmienne x oraz y to wspolrzedne a position //funkcja dodaje zawodnika do listy zawodnikow. zmienne x oraz y to wspolrzedne a position
// to pozycja zawodnika 0 - strzelec, 1 - bramkarz, 2 - broniacy, 3 napastnik // to pozycja zawodnika 0 - strzelec, 1 - bramkarz, 2 - broniacy, 3 napastnik
// ball - to odnosnik do punktu na boisku // ball - to odnosnik do punktu na boisku
@ -86,14 +144,15 @@ const Hero = () => {
list.removeChild(player) list.removeChild(player)
bojo.removeChild(ball) bojo.removeChild(ball)
if(possition == 1){ if(possition == 1){
setNumberOfGoalkeppers(0) setNumberOfGoalkeppers(number_of_goalkeepers_rev.current -= 1);
}else if(possition == 2){ }else if(possition == 2){
setNumberOfDevenders(number_of_defenders-1) ; setNumberOfDevenders(number_of_defenders_rev.current -= 1) ;
}else if (possition == 3){ }else if (possition == 3){
setNumberOfStrikers(number_of_strikers-1) ; setNumberOfStrikers(number_of_strikers_rev.current -= 1);
}else if(possition == 0){ }else if(possition == 0){
setNumberOfShooters(0) setNumberOfShooters(number_of_shooters_rev.current -= 1);
} }
//sentQuestion()
} }
// funkcja zsczytuje pozycje zawodnikow przed wyslaniem zapytania do serwera // funkcja zsczytuje pozycje zawodnikow przed wyslaniem zapytania do serwera
@ -127,19 +186,22 @@ const Hero = () => {
var pName = "Strzelec" var pName = "Strzelec"
//kolor kropki //kolor kropki
// kolor tła kafelka // kolor tła kafelka
var pColor = "#fc0303" var pColor = "#fc0303"
if(possition == 1){ if(possition == 1){
var pName = "Bramkarz" var pName = "Bramkarz"
var pColor = "#03e7fc" var pColor = "#03e7fc"
setNumberOfGoalkeppers(number_of_goalkeepers_rev.current += 1);
}else if(possition == 2){ }else if(possition == 2){
var pName = "Obrońca" var pName = "Obrońca"
var pColor = "#0324fc" var pColor = "#0324fc"
setNumberOfDevenders(number_of_defenders_rev.current += 1);
}else if (possition ==3){ }else if (possition ==3){
var pName = "Napastnik" var pName = "Napastnik"
var pColor = "#fc6703" var pColor = "#fc6703"
setNumberOfStrikers(number_of_strikers_rev.current += 1);
}else{
setNumberOfShooters(number_of_shooters_rev.current += 1);
} }
var player = document.createElement('div'); var player = document.createElement('div');
player.className = 'player'; player.className = 'player';
player.style.width = "inherit" player.style.width = "inherit"
@ -148,18 +210,18 @@ const Hero = () => {
// div z nazwa gracza // div z nazwa gracza
var tekst = document.createElement('div') var tekst = document.createElement('div')
tekst.style.fontSize = "10px"; tekst.style.fontSize = "12px";
tekst.innerHTML = pName; tekst.innerHTML = pName;
// div z pozycja gracza // div z pozycja gracza
var posytion = document.createElement('div') var posytion = document.createElement('div')
posytion.style.fontSize = "10px" posytion.style.fontSize = "12px"
posytion.innerHTML = "x:" + konwerturX(ball.style.left) + "m " + "y:" + konwetujY(ball.style.top) + "m"; posytion.innerHTML = konwerturX(ball.style.left) + " m, " + konwetujY(ball.style.top) + " m";
player.setAttribute('possition',[konwerturX(ball.style.left),konwetujY(ball.style.top)]) player.setAttribute('possition',[konwerturX(ball.style.left),konwetujY(ball.style.top)])
//div z przyciskiem usuwającym //div z przyciskiem usuwającym
var btnDelete = document.createElement('button') var btnDelete = document.createElement('button')
btnDelete.innerHTML = 'Usun' btnDelete.innerHTML = 'Usuń'
btnDelete.style.fontSize = "10px" btnDelete.style.fontSize = "12px"
btnDelete.style = 'background-color: #FFB266;color:#000000' btnDelete.style = 'background-color: #FFB266;color:#000000'
btnDelete.addEventListener("click",function(){deletePlayer(ball,player,possition)},false) btnDelete.addEventListener("click",function(){deletePlayer(ball,player,possition)},false)
//dodanie elementów do kafelka //dodanie elementów do kafelka
@ -209,8 +271,8 @@ const Hero = () => {
tekst.style.color = "white" tekst.style.color = "white"
posytion.style.color = "white" posytion.style.color = "white"
x = parseFloat(x) -2 x = parseFloat(x) -3
y = parseFloat(y) -2 y = parseFloat(y) -3
if(bojo.parentNode.querySelector(":hover")){ if(bojo.parentNode.querySelector(":hover")){
ball.style.left = x + "%" ball.style.left = x + "%"
@ -220,25 +282,28 @@ const Hero = () => {
//var shooterY = konwetujY(ball.style.top) //var shooterY = konwetujY(ball.style.top)
posytion.innerHTML = "x:" + konwerturX(ball.style.left) + "m " + "y:" + konwetujY(ball.style.top) + "m"; posytion.innerHTML = "x:" + konwerturX(ball.style.left) + "m " + "y:" + konwetujY(ball.style.top) + "m";
player.setAttribute('possition',[konwerturX(ball.style.left),konwetujY(ball.style.top)]); player.setAttribute('possition',[konwerturX(ball.style.left),konwetujY(ball.style.top)]);
bojo.addEventListener("mouseup", function(){ bojo.addEventListener("mouseup", function afterUp(){
ball.style.background = pColor ball.style.background = pColor
bojo.removeEventListener("mousemove", whileMove) bojo.removeEventListener("mousemove", whileMove)
bojo.removeEventListener("mouseup", afterUp)
}) })
})
}) bojo.addEventListener("mouseup", function reload(){
//sentQuestion();
bojo.removeEventListener("mouseup",reload)
})
}) })
//sentQuestion();
} }
// // Wyłanie zapytania do serwera // // Wyłanie zapytania do serwera
function sentQuestion() { function sentQuestion() {
///Dziwny Blad ///Dziwny Blad
loadPlayers() loadPlayers()
if (number_of_shooters == 1) { if (number_of_shooters_rev.current == 1) {
//console.log('Wysyłanie wartości: ', bodyPart, technique, actionType, shooterPossition, gameMinute, firstShot);
// Użyj backticksów zamiast zwykłych cudzysłowów // Użyj backticksów zamiast zwykłych cudzysłowów
fetch(`http://127.0.0.1:5000/get_model?shooter=${shooter}&goalkeeper=${goalkeeper}&defenders=${defenders}&strickers=${stricers}&bodyPart=${bodyPart}&technique=${technique}&actionType=${actionType}&shooterPossition=${shooterPossition}`).then( fetch(`http://127.0.0.1:5000/get_model?shooter=${shooter}&goalkeeper=${goalkeeper}&defenders=${defenders}&strickers=${stricers}&bodyPart=${bodyPart}&technique=${technique}&actionType=${actionType}&shooterPossition=${shooterPossition}&gameMinute=${gameMinute}&shot_first_time=${firstShot}&shot_one_on_one=${oneOnOne}&shot_aerial_won=${afterAirDuel}&shot_open_goal=${openGoal}&shot_follows_dribble=${afterDribbling}&shot_redirect=${redirect}`).then(
res => res.json() res => res.json()
).then( ).then(
data => { data => {
@ -246,7 +311,8 @@ const Hero = () => {
console.log(data); console.log(data);
// Przenieś tę linię do środka bloku .then(), aby uniknąć błędów // Przenieś tę linię do środka bloku .then(), aby uniknąć błędów
let eX = data.response; let eX = data.response;
document.getElementById("ex").innerHTML = "Współczynnik xG: " + eX; document.getElementById("ex").innerHTML = eX;
//updateXGMeter(eX);
} }
).catch(error => { ).catch(error => {
console.error('Błąd:', error); console.error('Błąd:', error);
@ -254,10 +320,9 @@ const Hero = () => {
} else { } else {
alert('Piłka nie jest obecnie na boisku.'); alert('Piłka nie jest obecnie na boisku.');
} }
} }
/* Funkcja dodająca listener do boiska*/ /* Funkcja dodająca listener do boiska*/
@ -276,38 +341,32 @@ const Hero = () => {
ball.style.top = y + "%" ball.style.top = y + "%"
//dodanie zawodnika do listy oraz punktu do mapy w zaleznosci od aktywnosci przycisku 1,2,3 lub 4 //dodanie zawodnika do listy oraz punktu do mapy w zaleznosci od aktywnosci przycisku 1,2,3 lub 4
if(active_bbt=="bbt1"){ if(active_bbt=="bbt1"){
if(number_of_shooters < 1 ){ if(number_of_shooters_rev.current < 1 ){
addPlayer(0,ball) addPlayer(0,ball)
bojo.appendChild(ball) bojo.appendChild(ball)
ball.style.background = "#fc0303" ball.style.background = "#fc0303"
setNumberOfShooters(number_of_shooters+1)
}else{alert("mozesz dodac tylko jednego strzelca")} }else{alert("mozesz dodac tylko jednego strzelca")}
}else if(active_bbt == "bbt2"){ }else if(active_bbt == "bbt2"){
if ( number_of_goalkeepers_rev.current < 1){
if ( number_of_goalkeepers < 1){
addPlayer(1,ball) addPlayer(1,ball)
bojo.appendChild(ball) bojo.appendChild(ball)
ball.style.background = "#03e7fc" ball.style.background = "#03e7fc"
setNumberOfGoalkeppers(number_of_goalkeepers+1)
}else{alert("mozesz dodac tylko jednego bramkarza")} }else{alert("mozesz dodac tylko jednego bramkarza")}
}else if(active_bbt == "bbt3"){ }else if(active_bbt == "bbt3"){
if(number_of_defenders <= 10){ if(number_of_defenders_rev.current < 10){
addPlayer(2,ball); addPlayer(2,ball);
setNumberOfDevenders(number_of_defenders+1)
bojo.appendChild(ball) bojo.appendChild(ball)
ball.style.background = "#0324fc" ball.style.background = "#0324fc"
}else{alert("maksymalna liczba obroncow")} }else{alert("maksymalna liczba obroncow")}
}else if(active_bbt == "bbt4"){ }else if(active_bbt == "bbt4"){
if(number_of_strikers <= 10){ if(number_of_strikers_rev.current < 10){
addPlayer(3,ball); addPlayer(3,ball);
setNumberOfStrikers(number_of_strikers+1);
bojo.appendChild(ball) bojo.appendChild(ball)
ball.style.background = "#fc6703" ball.style.background = "#fc6703"
}else{alert("maksymalna liczba napastnikow")} }else{alert("maksymalna liczba napastnikow")}
} }
} }
// funkcja działą po utworzeniu komponentów, dodaje listenry do elementów // funkcja działą po utworzeniu komponentów, dodaje listenry do elementów
@ -336,16 +395,18 @@ const Hero = () => {
<div className="container"> <div className="container">
{/* Listy zwijane */} {/* Listy zwijane */}
<div className="top-bar"> <div className="top-bar" id = "top-bar">
<form className="dropdown" id = "bodyPartList"> <form className="dropdown" id = "bodyPartList">
<select className="dropbtn" <select className="dropbtn"
onChange={event => setBodyPart(event.target.value)} onChange={event => {setBodyPart(event.target.value);
//sentQuestion()
}}
defaultValue={bodyPart}> defaultValue={bodyPart}>
<option value = "prawa">Noga Prawa</option> <option value = "Right Foot">Noga Prawa</option>
<option value = "lewa">Noga Lewa</option> <option value = "Left Foot">Noga Lewa</option>
<option value = "glowa">Głowa</option> <option value = "Head">Głowa</option>
<option value = "inna" >Inna</option> <option value = "Other" >Inna</option>
</select> </select>
</form> </form>
@ -353,37 +414,62 @@ const Hero = () => {
<form className="dropdown" id = "shootTypeList"> <form className="dropdown" id = "shootTypeList">
<select className="dropbtn" onChange={event => setTechnique(event.target.value)} <select className="dropbtn" onChange={event => {setTechnique(event.target.value);
//sentQuestion()
}}
defaultValue = {technique}> defaultValue = {technique}>
<option value="zwykly"> Zwykły </option> <option value="Normal"> Zwykły </option>
<option value = "voley"> Wolej </option> <option value = "Volley"> Wolej </option>
<option value = "pol-voley"> Półwolej </option> <option value = "Half Volley"> Półwolej </option>
<option value = "lob"> Lob </option> <option value = "Lob"> Lob </option>
<option value = "szczupak"> Szczupak </option> <option value = "Diving Header"> Szczupak </option>
<option value = "z_gory"> Kopnięcie z góry </option> <option value = "Overhead Kick"> Kopnięcie z góry </option>
<option value = "pietka"> Piętka </option> <option value = "Backheel"> Piętka </option>
</select> </select>
</form> </form>
<form className="dropdown" id = "actionTypeList" onChange={event => setActionType(event.target.value)} <form className="dropdown" id = "actionTypeList" onChange={event => {setActionType(event.target.value);
//sentQuestion()
}}
defaultValue={technique}> defaultValue={technique}>
<select className="dropbtn"> <select className="dropbtn">
<option value = "pozycyjny"> Atak Pozycyjny </option> <option value = "Open Play"> Atak Pozycyjny </option>
<option value = "wolny"> Rzut Wolny </option> <option value = "Free Kick"> Rzut Wolny </option>
<option value = "karny"> Rzut Karny </option> <option value = "Penalty"> Rzut Karny </option>
<option value= "rozny"> Rzut Rozny </option> <option value= "Corner"> Rzut Rozny </option>
<option value="rozpoczecie"> Rozpoczęcie </option>
</select> </select>
</form> </form>
<form className="dropdown" id = "possitionList" <form className="dropdown" id = "possitionList"
onChange={event => setPossition(event.target.value)} onChange={event => {setPossition(event.target.value);
//sentQuestion()
}}
defaultValue={shooterPossition}> defaultValue={shooterPossition}>
<select className="dropbtn"> <select className="dropbtn">
<option value= "napastnik" > Napastnik </option> <option value="Right Center Forward">Prawy Środkowy Napastnik</option>
<option value = "bramkarz"> Bramkarz </option> <option value="Left Center Forward">Lewy Środkowy Napastnik</option>
<option value = "obronca"> Obrońca </option> <option value="Secondary Striker">Drugi Napastnik</option>
<option value = "pomocnik"> Pomocnik </option> <option value="Center Forward">Środkowy Napastnik</option>
<option value="Center Midfield">Środkowy Pomocnik</option>
<option value="Left Center Midfield">Lewy Środkowy Pomocnik</option>
<option value="Right Center Midfield">Prawy Środkowy Pomocnik</option>
<option value="Left Midfield">Lewy Pomocnik</option>
<option value="Center Attacking Midfield">Środkowy Ofensywny Pomocnik</option>
<option value="Left Defensive Midfield">Lewy Defensywny Pomocnik</option>
<option value="Left Attacking Midfield">Lewy Ofensywny Pomocnik</option>
<option value="Right Attacking Midfield">Prawy Ofensywny Pomocnik</option>
<option value="Right Defensive Midfield">Prawy Defensywny Pomocnik</option>
<option value="Center Defensive Midfield">Środkowy Defensywny Pomocnik</option>
<option value="Right Midfield">Prawy Pomocnik</option>
<option value="Left Wing Back">Lewy Pomocnik Skrzydłowy</option>
<option value="Left Wing">Lewe Skrzydło</option>
<option value="Right Wing">Prawe Skrzydło</option>
<option value="Right Wing Back">Prawy Pomocnik Skrzydłowy</option>
<option value="Center Back">Środkowy Obrońca</option>
<option value="Left Center Back">Lewy Środkowy Obrońca</option>
<option value="Right Center Back">Prawy Środkowy Obrońca</option>
<option value="Right Back">Prawy Obrońca</option>
<option value="Left Back">Lewy Obrońca</option>
<option value="Goalkeeper">Bramkarz</option>
</select> </select>
</form> </form>
@ -409,25 +495,40 @@ const Hero = () => {
<div className="field-pic"></div> <div className="field-pic"></div>
</div> </div>
<div className="rightMenu">
<div className="xg-meter">
<b id="ex" className="xg-value">0</b>
</div> </div>
<div className="additional-parameters">
{/* <div className="ChoosingPlayer"> <h3>Parametry strzału</h3>
<button className="cho-one_on_one" id = "bbt8">Sam na sam</button> <label>
</div> <input type="checkbox" id="firstShot" onChange={handleFirstShotChange} />
<div className="ChoosingPlayer"> Pierwszy w meczu
<button className="cho-first_time" id = "bbt12">Pierwszy w meczu</button> </label>
</div> <label>
<div className="ChoosingPlayer"> <input type="checkbox" id="oneOnOne" onChange={handleOneOnOneChange} />
<button className="cho-aerial_won" id = "bbt13">Pojedynek powietrzny</button> Akcja sam na sam
</div> </label>
<div className="ChoosingPlayer"> <label>
<button className="cho-follows_dribble" id = "bbt14">Drybling</button> <input type="checkbox" id="afterAirDuel" onChange={handleAfterAirDuelChange} />
</div> Po pojedynku powietrznym
<div className="ChoosingPlayer"> </label>
<button className="cho-redirect" id = "bbt15">Rykoszet</button> <label>
</div> */} <input type="checkbox" id="openGoal" onChange={handleOpenGoalChange} />
Na pustą bramkę
</label>
<label>
<input type="checkbox" id="afterDribbling" onChange={handleAfterDribblingChange} />
Poprzedzony dryblingiem
</label>
<label>
<input type="checkbox" id="redirect" onChange={handleRedirectChange} />
Rykoszet
</label>
</div>
</div>
</div>
<div className="bottom-bar"> <div className="bottom-bar">
<button className="cho-shooter" id = "bbt1">Strzelec</button> <button className="cho-shooter" id = "bbt1">Strzelec</button>
@ -437,13 +538,8 @@ const Hero = () => {
<button className="reset-button" onClick={resetField}>Reset</button> <button className="reset-button" onClick={resetField}>Reset</button>
<button className="info-button" onClick={sentQuestion}>xG</button> <button className="info-button" onClick={sentQuestion}>xG</button>
</div> </div>
<div>
<b id = "ex" className="Ex">
</b>
</div> </div>
</div> </div>
</div>
); );
}; };

View File

@ -3,6 +3,7 @@ import React from 'react'
const Loader = () => { const Loader = () => {
return ( return (
<div>Loader</div> <div>Loader</div>
) )
} }

Binary file not shown.

View File

@ -2,105 +2,157 @@ from joblib import load
import pandas as pd import pandas as pd
from math import sqrt from math import sqrt
import math import math
import numpy as np
import xgboost
from sklearn.preprocessing import OrdinalEncoder
# Funkcja zwraca prawdopodobieństwo zdobycia gola # Funkcja zwraca prawdopodobieństwo zdobycia gola
def LogisticRegression_predict_proba(position_x, position_y, distance_to_goalM, angle, match_minute, Number_Intervening_Opponents, Number_Intervening_Teammates, isFoot, isHead): def LogisticRegression_predict_proba(position_x, position_y, distance_to_goalM, angle, match_minute, Number_Intervening_Opponents, Number_Intervening_Teammates, isFoot, isHead):
# distance_to_goalM = sqrt(( (position_x**2) + (position_y**2)))
# distance_to_goalM = sqrt(( (position_x**2) + (position_y**2)))
model = load('regresja_logistyczna.joblib') model = load('regresja_logistyczna.joblib')
X_new = pd.DataFrame(columns=['position_x', 'position_y', 'distance_to_goalM', 'angle','match_minute', 'Number_Intervening_Opponents','Number_Intervening_Teammates', 'isFoot', 'isHead']) X_new = pd.DataFrame(columns=['position_x', 'position_y', 'distance_to_goalM', 'angle','match_minute', 'Number_Intervening_Opponents','Number_Intervening_Teammates', 'isFoot', 'isHead'])
X_new.loc[len(X_new.index)] = [position_x, position_y, distance_to_goalM, angle, match_minute, Number_Intervening_Opponents, Number_Intervening_Teammates, isFoot, isHead] X_new.loc[len(X_new.index)] = [position_x, position_y, distance_to_goalM, angle, match_minute, Number_Intervening_Opponents, Number_Intervening_Teammates, isFoot, isHead]
return model.predict_proba(X_new)[0][1].round(2) return model.predict_proba(X_new)[0][1].round(2)
#xgBoost #xgBoost
def xgboost_predict_proba(minute, position_name, shot_body_part_name, shot_technique_name, def xgboost_predict_proba(minute=0, position_name='Center Forward', shot_body_part_name='Right Foot',
shot_type_name, shot_first_time, shot_one_on_one, shot_technique_name='Normal', shot_type_name='Open Play', shot_first_time=False,
shot_aerial_won, shot_deflected, shot_open_goal, shot_one_on_one=False, shot_aerial_won=False,
shot_follows_dribble, shot_redirect, x1, y1, shot_open_goal=False, shot_follows_dribble=False, shot_redirect=False, x1=0.0, y1=0.0,
number_of_players_opponents, number_of_players_teammates, number_of_players_opponents=0, number_of_players_teammates=0,
angle, distance, x_player_opponent_Goalkeeper, angle=0.0, distance=0.0, x_player_opponent_Goalkeeper=np.nan,
x_player_opponent_8, x_player_opponent_1, x_player_opponent_2, x_player_opponent_8=np.nan, x_player_opponent_1=np.nan, x_player_opponent_2=np.nan,
x_player_opponent_3, x_player_teammate_1, x_player_opponent_4, x_player_opponent_3=np.nan, x_player_teammate_1=np.nan, x_player_opponent_4=np.nan,
x_player_opponent_5, x_player_opponent_6, x_player_teammate_2, x_player_opponent_5=np.nan, x_player_opponent_6=np.nan, x_player_teammate_2=np.nan,
x_player_opponent_9, x_player_opponent_10, x_player_opponent_11, x_player_opponent_9=np.nan, x_player_opponent_10=np.nan, x_player_opponent_11=np.nan,
x_player_teammate_3, x_player_teammate_4, x_player_teammate_5, x_player_teammate_3=np.nan, x_player_teammate_4=np.nan, x_player_teammate_5=np.nan,
x_player_teammate_6, x_player_teammate_7, x_player_teammate_8, x_player_teammate_6=np.nan, x_player_teammate_7=np.nan, x_player_teammate_8=np.nan,
x_player_teammate_9, x_player_teammate_10, y_player_opponent_Goalkeeper=np.nan, y_player_opponent_8=np.nan,
y_player_opponent_Goalkeeper, y_player_opponent_8, x_player_teammate_9=np.nan, x_player_teammate_10=np.nan,
y_player_opponent_1, y_player_opponent_2, y_player_opponent_3, y_player_opponent_1=np.nan, y_player_opponent_2=np.nan, y_player_opponent_3=np.nan,
y_player_teammate_1, y_player_opponent_4, y_player_opponent_5, y_player_teammate_1=np.nan, y_player_opponent_4=np.nan, y_player_opponent_5=np.nan,
y_player_opponent_6, y_player_teammate_2, y_player_opponent_9, y_player_opponent_6=np.nan, y_player_teammate_2=np.nan, y_player_opponent_9=np.nan,
y_player_opponent_10, y_player_opponent_11, y_player_teammate_3, y_player_opponent_10=np.nan, y_player_opponent_11=np.nan, y_player_teammate_3=np.nan,
y_player_teammate_4, y_player_teammate_5, y_player_teammate_6, y_player_teammate_4=np.nan, y_player_teammate_5=np.nan, y_player_teammate_6=np.nan,
y_player_teammate_7, y_player_teammate_8, y_player_teammate_9, y_player_teammate_7=np.nan, y_player_teammate_8=np.nan, y_player_teammate_9=np.nan,
y_player_teammate_10, x_player_opponent_7, y_player_opponent_7, y_player_teammate_10=np.nan, x_player_opponent_7=np.nan, y_player_opponent_7=np.nan,
x_player_teammate_Goalkeeper, y_player_teammate_Goalkeeper, x_player_teammate_Goalkeeper=np.nan, y_player_teammate_Goalkeeper=np.nan):
shot_kick_off):
model = load('xgboost.joblib') model = xgboost.XGBClassifier()
X_new = pd.DataFrame(columns=['minute', 'position_name', 'shot_body_part_name', 'shot_technique_name', model.load_model('xgboost.json')
'shot_type_name', 'shot_first_time', 'shot_one_on_one',
'shot_aerial_won', 'shot_deflected', 'shot_open_goal', enc = OrdinalEncoder()
'shot_follows_dribble', 'shot_redirect', 'x1', 'y1', enc = load('labelEncoder.joblib')
'number_of_players_opponents', 'number_of_players_teammates',
'angle', 'distance', 'x_player_opponent_Goalkeeper', X_new = pd.DataFrame(columns=['minute', 'position_name', 'shot_body_part_name', 'shot_technique_name',
'x_player_opponent_8', 'x_player_opponent_1', 'x_player_opponent_2', 'shot_type_name', 'shot_first_time', 'shot_one_on_one',
'x_player_opponent_3', 'x_player_teammate_1', 'x_player_opponent_4', 'shot_aerial_won', 'shot_open_goal',
'x_player_opponent_5', 'x_player_opponent_6', 'x_player_teammate_2', 'shot_follows_dribble', 'shot_redirect', 'x1', 'y1',
'x_player_opponent_9', 'x_player_opponent_10', 'x_player_opponent_11', 'number_of_players_opponents', 'number_of_players_teammates',
'x_player_teammate_3', 'x_player_teammate_4', 'x_player_teammate_5', 'angle', 'distance', 'x_player_opponent_Goalkeeper',
'x_player_teammate_6', 'x_player_teammate_7', 'x_player_teammate_8', 'x_player_opponent_8', 'x_player_opponent_1', 'x_player_opponent_2',
'x_player_teammate_9', 'x_player_teammate_10', 'x_player_opponent_3', 'x_player_teammate_1', 'x_player_opponent_4',
'y_player_opponent_Goalkeeper', 'y_player_opponent_8', 'x_player_opponent_5', 'x_player_opponent_6', 'x_player_teammate_2',
'y_player_opponent_1', 'y_player_opponent_2', 'y_player_opponent_3', 'x_player_opponent_9', 'x_player_opponent_10', 'x_player_opponent_11',
'y_player_teammate_1', 'y_player_opponent_4', 'y_player_opponent_5', 'x_player_teammate_3', 'x_player_teammate_4', 'x_player_teammate_5',
'y_player_opponent_6', 'y_player_teammate_2', 'y_player_opponent_9', 'x_player_teammate_6', 'x_player_teammate_7', 'x_player_teammate_8',
'y_player_opponent_10', 'y_player_opponent_11', 'y_player_teammate_3', 'x_player_teammate_9', 'x_player_teammate_10',
'y_player_teammate_4', 'y_player_teammate_5', 'y_player_teammate_6', 'y_player_opponent_Goalkeeper', 'y_player_opponent_8',
'y_player_teammate_7', 'y_player_teammate_8', 'y_player_teammate_9', 'y_player_opponent_1', 'y_player_opponent_2', 'y_player_opponent_3',
'y_player_teammate_10', 'x_player_opponent_7', 'y_player_opponent_7', 'y_player_teammate_1', 'y_player_opponent_4', 'y_player_opponent_5',
'x_player_teammate_Goalkeeper', 'y_player_teammate_Goalkeeper', 'y_player_opponent_6', 'y_player_teammate_2', 'y_player_opponent_9',
'shot_kick_off']) 'y_player_opponent_10', 'y_player_opponent_11', 'y_player_teammate_3',
'y_player_teammate_4', 'y_player_teammate_5', 'y_player_teammate_6',
'y_player_teammate_7', 'y_player_teammate_8', 'y_player_teammate_9',
'y_player_teammate_10', 'x_player_opponent_7', 'y_player_opponent_7',
'x_player_teammate_Goalkeeper', 'y_player_teammate_Goalkeeper'])
X_new.loc[len(X_new.index)] = [minute, position_name, shot_body_part_name, shot_technique_name, X_new.loc[len(X_new.index)] = [minute, position_name, shot_body_part_name, shot_technique_name,
shot_type_name, shot_first_time, shot_one_on_one, shot_type_name, shot_first_time, shot_one_on_one,
shot_aerial_won, shot_deflected, shot_open_goal, shot_aerial_won, shot_open_goal,
shot_follows_dribble, shot_redirect, x1, y1, shot_follows_dribble, shot_redirect, x1, y1,
number_of_players_opponents, number_of_players_teammates, number_of_players_opponents, number_of_players_teammates,
angle, distance, x_player_opponent_Goalkeeper, angle, distance, x_player_opponent_Goalkeeper,
x_player_opponent_8, x_player_opponent_1, x_player_opponent_2, x_player_opponent_8, x_player_opponent_1, x_player_opponent_2,
x_player_opponent_3, x_player_teammate_1, x_player_opponent_4, x_player_opponent_3, x_player_teammate_1, x_player_opponent_4,
x_player_opponent_5, x_player_opponent_6, x_player_teammate_2, x_player_opponent_5, x_player_opponent_6, x_player_teammate_2,
x_player_opponent_9, x_player_opponent_10, x_player_opponent_11, x_player_opponent_9, x_player_opponent_10, x_player_opponent_11,
x_player_teammate_3, x_player_teammate_4, x_player_teammate_5, x_player_teammate_3, x_player_teammate_4, x_player_teammate_5,
x_player_teammate_6, x_player_teammate_7, x_player_teammate_8, x_player_teammate_6, x_player_teammate_7, x_player_teammate_8,
x_player_teammate_9, x_player_teammate_10, x_player_teammate_9, x_player_teammate_10,
y_player_opponent_Goalkeeper, y_player_opponent_8, y_player_opponent_Goalkeeper, y_player_opponent_8,
y_player_opponent_1, y_player_opponent_2, y_player_opponent_3, y_player_opponent_1, y_player_opponent_2, y_player_opponent_3,
y_player_teammate_1, y_player_opponent_4, y_player_opponent_5, y_player_teammate_1, y_player_opponent_4, y_player_opponent_5,
y_player_opponent_6, y_player_teammate_2, y_player_opponent_9, y_player_opponent_6, y_player_teammate_2, y_player_opponent_9,
y_player_opponent_10, y_player_opponent_11, y_player_teammate_3, y_player_opponent_10, y_player_opponent_11, y_player_teammate_3,
y_player_teammate_4, y_player_teammate_5, y_player_teammate_6, y_player_teammate_4, y_player_teammate_5, y_player_teammate_6,
y_player_teammate_7, y_player_teammate_8, y_player_teammate_9, y_player_teammate_7, y_player_teammate_8, y_player_teammate_9,
y_player_teammate_10, x_player_opponent_7, y_player_opponent_7, y_player_teammate_10, x_player_opponent_7, y_player_opponent_7,
x_player_teammate_Goalkeeper, y_player_teammate_Goalkeeper, x_player_teammate_Goalkeeper, y_player_teammate_Goalkeeper]
shot_kick_off]
return model.predict_proba(X_new)[0][1].round(2) X_new[['position_name',
'shot_technique_name',
'shot_type_name',
'shot_body_part_name']] = enc.transform(X_new[['position_name', 'shot_technique_name', 'shot_type_name', 'shot_body_part_name']], )
X_new[['minute',
'position_name',
'shot_technique_name',
'shot_type_name',
'number_of_players_opponents',
'number_of_players_teammates',
'shot_body_part_name']] = X_new[['minute',
'position_name',
'shot_technique_name',
'shot_type_name',
'number_of_players_opponents',
'number_of_players_teammates',
'shot_body_part_name']].astype(int)
# X_new[['minute',
# 'position_name',
# 'shot_technique_name',
# 'shot_type_name',
# 'number_of_players_opponents',
# 'number_of_players_teammates',
# 'shot_body_part_name']] = X_new[['minute',
# 'position_name',
# 'shot_technique_name',
# 'shot_type_name',
# 'number_of_players_opponents',
# 'number_of_players_teammates',
# 'shot_body_part_name']].astype('category')
X_new[['shot_first_time',
'shot_one_on_one',
'shot_aerial_won',
'shot_open_goal',
'shot_follows_dribble',
'shot_redirect']] = X_new[['shot_first_time',
'shot_one_on_one',
'shot_aerial_won',
'shot_open_goal',
'shot_follows_dribble',
'shot_redirect']].astype(int)
print(X_new)
print(X_new.dtypes)
return model.predict_proba(X_new)[0][1].round(3)
#XgBoost_2 #XgBoost_2
def xgboost_predict_proba_v2(shooter,goalkeeper,teamMatesList,opponentsList, minute,position_name,shot_body_part_name, def xgboost_predict_proba_v2(shooter,goalkeeper,teamMatesList,opponentsList, minute,position_name,shot_body_part_name,
shot_technique_name,shot_type_name,shot_first_time,shot_aerial_won,shot_deflected,shot_open_goal, shot_technique_name,shot_type_name,shot_first_time,shot_aerial_won,shot_open_goal,
shot_follows_dribble,shot_redirect, shot_kick_off): shot_follows_dribble,shot_redirect):
model = load('xgboost.joblib') model = load('xgboost.joblib')
X_new = pd.DataFrame(columns=['minute', 'position_name', 'shot_body_part_name', X_new = pd.DataFrame(columns=['minute', 'position_name', 'shot_body_part_name',
'shot_technique_name','shot_type_name', 'shot_first_time', 'shot_technique_name','shot_type_name', 'shot_first_time',
'shot_one_on_one','shot_aerial_won', 'shot_deflected', 'shot_one_on_one','shot_aerial_won',
'shot_open_goal','shot_follows_dribble', 'shot_redirect', 'shot_open_goal','shot_follows_dribble', 'shot_redirect',
'x1', 'y1','number_of_players_opponents', 'x1', 'y1','number_of_players_opponents',
'number_of_players_teammates','angle', 'distance', 'number_of_players_teammates','angle', 'distance',
'x_player_opponent_Goalkeeper', 'x_player_opponent_Goalkeeper', 'x_player_opponent_8',
'x_player_opponent_1', 'x_player_opponent_2','x_player_opponent_3', 'x_player_opponent_1', 'x_player_opponent_2','x_player_opponent_3',
'x_player_opponent_4','x_player_opponent_5', 'x_player_opponent_6', 'x_player_opponent_4','x_player_opponent_5', 'x_player_opponent_6',
'x_player_teammate_2','x_player_opponent_9', 'x_player_opponent_10', 'x_player_teammate_2','x_player_opponent_9', 'x_player_opponent_10',
@ -116,8 +168,7 @@ def xgboost_predict_proba_v2(shooter,goalkeeper,teamMatesList,opponentsList, min
'y_player_teammate_4', 'y_player_teammate_5', 'y_player_teammate_6', 'y_player_teammate_4', 'y_player_teammate_5', 'y_player_teammate_6',
'y_player_teammate_7', 'y_player_teammate_8', 'y_player_teammate_9', 'y_player_teammate_7', 'y_player_teammate_8', 'y_player_teammate_9',
'y_player_teammate_10', 'x_player_opponent_7', 'y_player_opponent_7', 'y_player_teammate_10', 'x_player_opponent_7', 'y_player_opponent_7',
'x_player_teammate_Goalkeeper', 'y_player_teammate_Goalkeeper', 'x_player_teammate_Goalkeeper', 'y_player_teammate_Goalkeeper'])
'shot_kick_off'])
shooter = konwertujDoListy(shooter) shooter = konwertujDoListy(shooter)
@ -137,8 +188,10 @@ def xgboost_predict_proba_v2(shooter,goalkeeper,teamMatesList,opponentsList, min
teamMatesList = zmienWMaciez(teamMatesList) teamMatesList = zmienWMaciez(teamMatesList)
opponentsList = zmienWMaciez(opponentsList) opponentsList = zmienWMaciez(opponentsList)
number_of_players_opponents = len(teamMatesList)
number_of_players_teammates = len(opponentsList) # DO ROZBUDOWY
number_of_players_opponents = 3
number_of_players_teammates = 3
# Bramkarz # Bramkarz
x_player_opponent_Goalkeeper = goalkeeper[0] x_player_opponent_Goalkeeper = goalkeeper[0]
y_player_opponent_Goalkeeper = goalkeeper[1] y_player_opponent_Goalkeeper = goalkeeper[1]
@ -146,19 +199,16 @@ def xgboost_predict_proba_v2(shooter,goalkeeper,teamMatesList,opponentsList, min
shot_one_on_one = True if number_of_players_opponents == 1 else False shot_one_on_one = True if number_of_players_opponents == 1 else False
# TeamMate goalkeppe # TeamMate goalkeppe
x_player_teammate_Goalkeeper = None x_player_teammate_Goalkeeper = np.nan
y_player_teammate_Goalkeeper = None y_player_teammate_Goalkeeper = np.nan
#Reszta Zawodnikow #Reszta Zawodnikow
print("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
print(X_new.head)
X_new.loc[len(X_new.index)] = [minute, position_name, shot_body_part_name, X_new.loc[len(X_new.index)] = [minute, position_name, shot_body_part_name,
shot_technique_name,shot_type_name, shot_first_time, shot_technique_name,shot_type_name, shot_first_time,
shot_one_on_one,shot_aerial_won, shot_deflected, shot_one_on_one,shot_aerial_won,
shot_open_goal,shot_follows_dribble, shot_redirect, shot_open_goal,shot_follows_dribble, shot_redirect,
shooter[0], shooter[1],number_of_players_opponents, shooter[0], shooter[1],number_of_players_opponents,
number_of_players_teammates,angle, distance, number_of_players_teammates,angle, distance,
x_player_opponent_Goalkeeper, x_player_opponent_Goalkeeper, opponentsList[8][0],
opponentsList[0][0], opponentsList[1][0], opponentsList[2][0], opponentsList[0][0], opponentsList[1][0], opponentsList[2][0],
opponentsList[3][0], opponentsList[4][0], opponentsList[5][0], opponentsList[3][0], opponentsList[4][0], opponentsList[5][0],
opponentsList[6][0], opponentsList[7][0], teamMatesList[8][0], opponentsList[6][0], opponentsList[7][0], teamMatesList[8][0],
@ -175,13 +225,17 @@ def xgboost_predict_proba_v2(shooter,goalkeeper,teamMatesList,opponentsList, min
teamMatesList[0][1],teamMatesList[1][1], teamMatesList[2][1], teamMatesList[0][1],teamMatesList[1][1], teamMatesList[2][1],
teamMatesList[4][1],teamMatesList[5][1], teamMatesList[6][1], teamMatesList[7][1], teamMatesList[4][1],teamMatesList[5][1], teamMatesList[6][1], teamMatesList[7][1],
teamMatesList[8][1], teamMatesList[9][1], teamMatesList[8][1], teamMatesList[9][1],
x_player_teammate_Goalkeeper, y_player_teammate_Goalkeeper, x_player_teammate_Goalkeeper, y_player_teammate_Goalkeeper]
shot_kick_off]
categorical_columns = ['position_name', 'shot_technique_name', 'shot_type_name', 'number_of_players_opponents', 'number_of_players_teammates', 'shot_body_part_name'] # list all your object columns here
# X_new = pd.get_dummies(X_new, columns=categorical_columns)
X_new[categorical_columns] = X_new[categorical_columns].astype('category')
return model.predict_proba(X_new)[0][1].round(2) return model.predict_proba(X_new)[0][1].round(2)
# Pomocnicze Funkcje # Pomocnicze Funkcje
# trzeba uzupelnic
def sortNearestToShooter(playerList, shooter): def sortNearestToShooter(playerList, shooter):
return playerList return playerList
@ -198,14 +252,14 @@ def loc2angle(x, y):
rads = math.pi + rads if rads < 0 else rads rads = math.pi + rads if rads < 0 else rads
deg = math.degrees(rads) deg = math.degrees(rads)
return deg return deg
# zamiana stringa odzielonego ',' na liste
def konwertujDoListy(listaString): def konwertujDoListy(listaString):
listaString = listaString.split(",") listaString = listaString.split(",")
listaFloat = [] listaFloat = []
for elem in listaString: for elem in listaString:
listaFloat.append(float(elem)) listaFloat.append(float(elem))
return listaFloat return listaFloat
#Zamiana listy w formie [1x,1y,2x,2y,3x,3y...] do postaci maciezy [xi, yi]
def zmienWMaciez(lista): def zmienWMaciez(lista):
maciez = [] maciez = []
for i in range(0,len(lista),2): for i in range(0,len(lista),2):
@ -213,5 +267,5 @@ def zmienWMaciez(lista):
maciez.append(player) maciez.append(player)
if(len(maciez) < 10): if(len(maciez) < 10):
for i in range(len(maciez),11,1): for i in range(len(maciez),11,1):
maciez.append([None,None]) maciez.append([np.nan,np.nan])
return maciez return maciez

View File

@ -1,6 +1,8 @@
from flask import Flask, request, jsonify from flask import Flask, request, jsonify
from flask_cors import CORS from flask_cors import CORS
from modele.modele import LogisticRegression_predict_proba, xgboost_predict_proba, xgboost_predict_proba_v2 from modele.modele import LogisticRegression_predict_proba, xgboost_predict_proba, xgboost_predict_proba_v2
import numpy as np
import math
app = Flask(__name__) app = Flask(__name__)
@ -24,37 +26,218 @@ def get_model():
# Elementy z list: czesc ciała,rodzaj uderzenia,pozycja strzelca oraz typ akcji # Elementy z list: czesc ciała,rodzaj uderzenia,pozycja strzelca oraz typ akcji
position_name = request.args.get('shooter')
body_part = request.args.get('bodyPart') body_part = request.args.get('bodyPart')
technique = request.args.get('technique') technique = request.args.get('technique')
acionType = request.args.get('actionType') acionType = request.args.get('actionType')
minute = request.args.get('gameMinute')
position_name = request.args.get('shooterPossition')
gameMinute = request.args.get('gameMinute')
print("pozycja strzelca: " + position_name) shot_first_time = request.args.get('shot_first_time')
shot_one_on_one = request.args.get('shot_one_on_one')
shot_aerial_won = request.args.get('shot_aerial_won')
shot_open_goal = request.args.get('shot_open_goal')
shot_follows_dribble = request.args.get('shot_follows_dribble')
shot_redirect = request.args.get('shot_redirect')
shooter_x, shooter_y = shooter.split(',')
shooter_x = float(shooter_x)
shooter_y = float(shooter_y)
print("minuta: ", minute)
print("pozycja x1 strzelca: ", shooter_x)
print("pozycja y1 strzelca: ", shooter_y)
print("czesc ciala: " + body_part) print("czesc ciala: " + body_part)
print("technika: " + technique) print("technika: " + technique)
print("typ akcji: " + acionType) print("typ akcji: " + acionType)
# lista wspolzawodnikow oraz przeciwnikow # lista atakujacy oraz obroncy
teamMatesList = request.args.get('defenders') def konwertujDoListy(listaString):
opponentsList = request.args.get('strickers') listaString = listaString.split(",")
listaFloat = []
for elem in listaString:
listaFloat.append(float(elem))
return listaFloat
def zmienWMaciez(lista):
maciez = []
for i in range(0,len(lista),2):
player = [float(lista[i]),float(lista[i+1])]
maciez.append(player)
if(len(maciez) < 10):
for i in range(len(maciez),11,1):
maciez.append([np.nan,np.nan])
return maciez
obroncy = request.args.get('defenders')
atakujacy = request.args.get('strickers')
print("wspolrzedne obroncow: ", obroncy)
if obroncy == "":
obroncy_macierz = [[np.nan, np.nan]]
else:
obroncy_lista = konwertujDoListy(obroncy)
obroncy_macierz = zmienWMaciez(obroncy_lista)
print("wspolrzedne obroncow: " + teamMatesList) if atakujacy == "":
print("wspolrzedne przeciwnikow: " + opponentsList) atakujacy_macierz = [[np.nan, np.nan]]
else:
atakujacy_lista = konwertujDoListy(atakujacy)
atakujacy_macierz = zmienWMaciez(atakujacy_lista)
if gameMinute == "":
gameMinute = 1.0 # to change
# Bramkarz print("wspolrzedne obroncow: ", obroncy)
goalkepper = "2,2" print("wspolrzedne atakujacych: ", atakujacy)
#goalkepper = request.args.get('goalkeeper')
def euclidean_distance(point1, point2):
"""Calculate the Euclidean distance between two points."""
return math.sqrt((point1[0] - point2[0])**2 + (point1[1] - point2[1])**2)
def sort_coordinates_by_distance(coordinates, reference_point):
"""Sort a list of coordinates based on Euclidean distance from a reference point.
Coordinates with NaN values are placed at the end of the list.
"""
def distance_or_inf(coord):
"""Helper function to handle coordinates with NaN values."""
if hasattr(coord, '__iter__') and len(coord) >= 2:
if np.isnan(coord[0]) or np.isnan(coord[1]):
return float('inf') # Set distance to infinity for NaN coordinates
return euclidean_distance(coord, reference_point)
return float('inf') # Set distance to infinity for non-iterable coordinates
sorted_coordinates = sorted(coordinates, key=distance_or_inf)
if(len(sorted_coordinates) < 10):
for i in range(len(sorted_coordinates),11,1):
sorted_coordinates.append([np.nan,np.nan])
return sorted_coordinates
print("bramkarz: " + str(goalkepper) ) # POSORTOWANI OBRONCY I ATAKUJACY
posortowani_obroncy = sort_coordinates_by_distance(obroncy_macierz, [shooter_x, shooter_y])
posortowani_atakujacy = sort_coordinates_by_distance(atakujacy_macierz, [shooter_x, shooter_y])
response = xgboost_predict_proba_v2(shooter = shooter, print("Posortowani obroncy: ", posortowani_obroncy)
opponentsList = opponentsList, teamMatesList = teamMatesList ,minute = 20, position_name = position_name, shot_body_part_name = body_part, shot_technique_name = technique,
shot_type_name = acionType, shot_first_time = False, print("Posortowani atakujacy: ", posortowani_atakujacy)
shot_aerial_won = False, shot_deflected = False, shot_open_goal = False,
shot_follows_dribble = False, shot_redirect = False, shot_kick_off = False, goalkeeper= goalkepper
) number_of_players_opponents = float(np.sum(~np.isnan(posortowani_obroncy).all(axis=1)))
number_of_players_teammates = float(np.sum(~np.isnan(posortowani_atakujacy).all(axis=1)))
print("Liczba obroncow:", number_of_players_opponents)
print("Liczba atakujacych:", number_of_players_teammates)
## add angle, match minutes and number of players
def loc2angle(x, y):
rads = math.atan(7.32 * x / (x**2 + (y - 34)**2 - (7.32/2)**2))
rads = math.pi + rads if rads < 0 else rads
deg = math.degrees(rads)
return deg
def loc2distance(x, y):
return math.sqrt(x**2 + (y - 34)**2)
angle = loc2angle(x = shooter_x, y = shooter_y)
dist = loc2distance(x = shooter_x, y = shooter_y)
# BRAMKARZ
goalkepper = request.args.get('goalkeeper')
if goalkepper == "null":
goalkepper_x, goalkepper_y = np.nan, np.nan
else:
goalkepper_x, goalkepper_y = goalkepper.split(',')
goalkepper_x = float(goalkepper_x)
goalkepper_y = float(goalkepper_y)
print("bramkarz:", goalkepper_x, goalkepper_y)
if shot_first_time == 'true':
shot_first_time = True
else:
shot_first_time = False
if shot_one_on_one == 'true':
shot_one_on_one = True
else:
shot_one_on_one = False
if shot_aerial_won == 'true':
shot_aerial_won = True
else:
shot_aerial_won = False
if shot_open_goal == 'true':
shot_open_goal = True
else:
shot_open_goal = False
if shot_follows_dribble == 'true':
shot_follows_dribble = True
else:
shot_follows_dribble = False
if shot_redirect == 'true':
shot_redirect = True
else:
shot_redirect = False
#### CHECKLIST
print('CHECKLISTA')
print('shot_first_time', shot_first_time)
print('shot_one_on_one', shot_one_on_one)
print('shot_aerial_won', shot_aerial_won)
print('shot_open_goal', shot_open_goal)
print('shot_follows_dribble', shot_follows_dribble)
print('shot_redirect', shot_redirect)
# MODEL XGBOOST
response = xgboost_predict_proba(minute=int(gameMinute), #minute=0,
position_name=position_name,
shot_body_part_name=body_part,
shot_technique_name=technique,
shot_type_name=acionType,
shot_first_time=shot_first_time,
shot_one_on_one=shot_one_on_one,
shot_aerial_won=shot_aerial_won,
shot_open_goal=shot_open_goal,
shot_follows_dribble=shot_follows_dribble,
shot_redirect=shot_redirect,
x1=shooter_x, y1=shooter_y,
number_of_players_opponents=number_of_players_opponents,
number_of_players_teammates=number_of_players_teammates,
angle=angle, distance=dist,
x_player_opponent_Goalkeeper=goalkepper_x, y_player_opponent_Goalkeeper=goalkepper_y,
x_player_opponent_1=posortowani_obroncy[0][0], y_player_opponent_1=posortowani_obroncy[0][1],
x_player_opponent_2=posortowani_obroncy[1][0], y_player_opponent_2=posortowani_obroncy[1][1],
x_player_opponent_3=posortowani_obroncy[2][0], y_player_opponent_3=posortowani_obroncy[2][1],
x_player_opponent_4=posortowani_obroncy[3][0], y_player_opponent_4=posortowani_obroncy[3][1],
x_player_opponent_5=posortowani_obroncy[4][0], y_player_opponent_5=posortowani_obroncy[4][1],
x_player_opponent_6=posortowani_obroncy[5][0], y_player_opponent_6=posortowani_obroncy[5][1],
x_player_opponent_7=posortowani_obroncy[6][0], y_player_opponent_7=posortowani_obroncy[6][1],
x_player_opponent_8=posortowani_obroncy[7][0], y_player_opponent_8=posortowani_obroncy[7][1],
x_player_opponent_9=posortowani_obroncy[8][0], y_player_opponent_9=posortowani_obroncy[8][1],
x_player_opponent_10=posortowani_obroncy[9][0], y_player_opponent_10=posortowani_obroncy[9][1],
x_player_teammate_Goalkeeper=np.nan, y_player_teammate_Goalkeeper=np.nan,
x_player_teammate_1=posortowani_atakujacy[0][0], y_player_teammate_1=posortowani_atakujacy[0][1],
x_player_teammate_2=posortowani_atakujacy[1][0], y_player_teammate_2=posortowani_atakujacy[1][1],
x_player_teammate_3=posortowani_atakujacy[2][0], y_player_teammate_3=posortowani_atakujacy[2][1],
x_player_teammate_4=posortowani_atakujacy[3][0], y_player_teammate_4=posortowani_atakujacy[3][1],
x_player_teammate_5=posortowani_atakujacy[4][0], y_player_teammate_5=posortowani_atakujacy[4][1],
x_player_teammate_6=posortowani_atakujacy[5][0], y_player_teammate_6=posortowani_atakujacy[5][1],
x_player_teammate_7=posortowani_atakujacy[6][0], y_player_teammate_7=posortowani_atakujacy[6][1],
x_player_teammate_8=posortowani_atakujacy[7][0], y_player_teammate_8=posortowani_atakujacy[7][1],
x_player_teammate_9=posortowani_atakujacy[8][0], y_player_teammate_9=posortowani_atakujacy[8][1],
x_player_teammate_10=posortowani_atakujacy[9][0], y_player_teammate_10=posortowani_atakujacy[9][1])
# response = xgboost_predict_proba(shooter = shooter,
# opponentsList = opponentsList, teamMatesList = teamMatesList, minute = 20, position_name = position_name, shot_body_part_name = body_part, shot_technique_name = technique,
# shot_type_name = acionType, shot_first_time = False,
# shot_aerial_won = False, shot_deflected = False, shot_open_goal = False,
# shot_follows_dribble = False, shot_redirect = False, shot_kick_off = False, goalkeeper= goalkepper
# )
#print(response) #print(response)
res = str(response) res = str(response)

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -4,19 +4,55 @@
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
.Ex{ .Ex {
display: block; /* Może być inline-block, jeśli preferujesz */ display: block; /* Może być inline-block, jeśli preferujesz */
margin: 20px auto; /* Centralnie i z marginesem */ margin: 20px auto; /* Centralnie i z marginesem */
padding: 10px; padding: 10px;
background-color: #4CAF50; /* Przykładowy kolor tła */ background-color: #4CAF50; /* Przykładowy kolor tła */
color: white; /* Kolor tekstu */ color: white; /* Kolor tekstu */
text-align: center; text-align: center;
border-radius: 5px; /* Lekko zaokrąglone rogi */ border-radius: 5px; /* Lekko zaokrąglone rogi */
font-size: 20px; /* Duża, czytelna czcionka */ font-size: 20px; /* Duża, czytelna czcionka */
font-weight: bold; /* Pogrubienie dla lepszej widoczności */ font-weight: bold; /* Pogrubienie dla lepszej widoczności */
width: 50%; /* Dostosuj szerokość zgodnie z potrzebami */ width: 100%; /* Poszerzone pole */
/* Dodatkowe style, takie jak cienie, mogą być dodane */ box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.5); /* Cień dla dodatkowej głębi */
} /* Opcjonalnie, można dodać gradient tła dla większego efektu */
background-image: linear-gradient(to right, #32CD32 , #4CAF50);
transition: transform 0.3s ease; /* Delikatna animacja */
}
.Ex:hover {
transform: scale(1.10); /* Efekt powiększenia przy najechaniu */
}
.xg-meter {
width: 200px;
height: 100px; /* Zmiana wysokości, aby pasowała do proporcji bramki */
display: flex;
align-items: center;
justify-content: center;
text-align: center;
color: white;
font-size: 48px;
font-weight: bold;
background: url('assets/bramka.jpeg') no-repeat center center; /* Tło z obrazem bramki */
background-size: cover; /* Dopasowanie obrazu do rozmiaru elementu */
border-radius: 10px; /* Opcjonalnie, dla zaokrąglonych rogów */
}
.xg-value {
display: block;
background: rgba(0, 0, 0, 0.5); /* Półprzezroczyste tło dla lepszej czytelności tekstu */
padding: 5px 10px; /* Dodanie odstępu */
border-radius: 5px; /* Zaokrąglone rogi dla tekstu */
}
/* Funkcja JavaScript będzie sterować stopniem gradientu */
body { body {
margin: 50px; margin: 50px;
display: grid; display: grid;
@ -25,7 +61,7 @@
grid-template-rows: auto; grid-template-rows: auto;
grid-template-columns: auto auto auto; grid-template-columns: auto auto auto;
} }
.container { .container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -49,19 +85,20 @@
max-height: 100%; max-height: 100%;
} }
.container span { .container span {
display: block; display: block;
} }
.main-content { .main-content {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
} }
.player{ .player{
width: inherit; width: inherit;
height: 8vh; height: 8vh;
@ -84,7 +121,7 @@
background-color: #cccccc; background-color: #cccccc;
justify-content: space-between; justify-content: space-between;
} }
.subMenu { .subMenu {
display: grid; display: grid;
grid-template-rows: auto auto auto; grid-template-rows: auto auto auto;
@ -95,14 +132,15 @@
background-color: #f0f0f0; /* Example background color */ background-color: #f0f0f0; /* Example background color */
z-index: 1000; /* Ensure it stays on top of other content */ z-index: 1000; /* Ensure it stays on top of other content */
} }
.player-list{
.player-list {
background-color: rgb(61, 38, 38); background-color: rgb(61, 38, 38);
width: 13vw; width: 13vw;
height: calc(50vw*68/105); height: calc(50vw*68/105);
overflow: scroll; overflow: scroll;
font-size: 12px; /* Example font size - adjust as needed */
} }
.top-bar { .top-bar {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@ -112,7 +150,7 @@
/* Możesz dodać dodatkowe style, jak tło, obramowanie itp. */ /* Możesz dodać dodatkowe style, jak tło, obramowanie itp. */
z-index: 2; z-index: 2;
} }
.bottom-bar { .bottom-bar {
display: flex; display: flex;
justify-content: space-between; /* Rozmieszcza przyciski równomiernie */ justify-content: space-between; /* Rozmieszcza przyciski równomiernie */
@ -128,7 +166,7 @@
border-radius: 50%; border-radius: 50%;
position: absolute position: absolute
} }
.reset-button { .reset-button {
position: relative; position: relative;
margin: 5px; margin: 5px;
@ -200,7 +238,7 @@
color: #000000; color: #000000;
font-size: 16px; font-size: 16px;
} }
.cho-first_time { .cho-first_time {
position: relative; position: relative;
padding: 10px; padding: 10px;
@ -237,7 +275,38 @@
color: #000000; color: #000000;
font-size: 16px; font-size: 16px;
} }
.additional-parameters {
position: relative; /* Or absolute, depending on layout */
right: 0;
top: 30%; /* Adjusted to a higher position */
width: 250px; /* Increased width */
background-color: #000000;
padding: 15px; /* Increased padding */
border: 1px solid #ddd;
border-radius: 5px;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
z-index: 100; /* To ensure it stays on top */
color: #ffffff; /* Optional: change text color for better visibility on dark background */
}
.additional-parameters h3 {
margin-top: 0;
font-size: 18px; /* Increased font size for heading */
}
.additional-parameters label {
display: flex; /* Updated to flex for better alignment */
align-items: center; /* Aligns checkbox and label text vertically */
margin-bottom: 10px; /* Increased spacing between checkboxes */
font-size: 16px; /* Increased font size for labels */
}
.additional-parameters input[type="checkbox"] {
margin-right: 10px; /* Adds spacing between checkbox and label text */
}
/* DROPDOWNS */ /* DROPDOWNS */
/* Style the dropdown button */ /* Style the dropdown button */
.dropbtn { .dropbtn {
@ -253,13 +322,13 @@
.dropbtn:hover, .dropbtn:focus { .dropbtn:hover, .dropbtn:focus {
background-color: #3e8e41; background-color: #3e8e41;
} }
/* The container <div> - needed to position the dropdown content */ /* The container <div> - needed to position the dropdown content */
.dropdown { .dropdown {
position: relative; position: relative;
display: inline-block; display: inline-block;
} }
.cho-dropdown_body_part { .cho-dropdown_body_part {
display: none; display: none;
position: absolute; position: absolute;
@ -268,7 +337,7 @@
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1; z-index: 1;
} }
.cho-dropdown_body_part a{ .cho-dropdown_body_part a{
color: black; color: black;
padding: 12px 16px; padding: 12px 16px;
@ -276,15 +345,15 @@
display: block; display: block;
font-size: 16px; font-size: 16px;
} }
/* Change color of dropdown links on hover */ /* Change color of dropdown links on hover */
.cho-dropdown_body_part a:hover {background-color: #f1f1f1} .cho-dropdown_body_part a:hover {background-color: #f1f1f1}
/* Show the dropdown menu on hover */ /* Show the dropdown menu on hover */
.dropdown:hover .cho-dropdown_body_part { .dropdown:hover .cho-dropdown_body_part {
display: block; display: block;
} }
.cho-dropdown_position_name { .cho-dropdown_position_name {
display: none; display: none;
position: absolute; position: absolute;
@ -293,7 +362,7 @@
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1; z-index: 1;
} }
.cho-dropdown_position_name a { .cho-dropdown_position_name a {
color: black; color: black;
padding: 12px 16px; padding: 12px 16px;
@ -301,15 +370,15 @@
display: block; display: block;
font-size: 16px; font-size: 16px;
} }
/* Change color of dropdown links on hover */ /* Change color of dropdown links on hover */
.cho-dropdown_position_name a:hover {background-color: #f1f1f1} .cho-dropdown_position_name a:hover {background-color: #f1f1f1}
/* Show the dropdown menu on hover */ /* Show the dropdown menu on hover */
.dropdown:hover .cho-dropdown_position_name { .dropdown:hover .cho-dropdown_position_name {
display: block; display: block;
} }
.cho-dropdown_technique_name { .cho-dropdown_technique_name {
position: relative; position: relative;
display: none; display: none;
@ -319,7 +388,7 @@
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1; z-index: 1;
} }
.cho-dropdown_technique_name a { .cho-dropdown_technique_name a {
color: black; color: black;
padding: 12px 16px; padding: 12px 16px;
@ -327,15 +396,15 @@
display: block; display: block;
font-size: 16px; font-size: 16px;
} }
/* Change color of dropdown links on hover */ /* Change color of dropdown links on hover */
.cho-dropdown_technique_name a:hover {background-color: #f1f1f1} .cho-dropdown_technique_name a:hover {background-color: #f1f1f1}
/* Show the dropdown menu on hover */ /* Show the dropdown menu on hover */
.dropdown:hover .cho-dropdown_technique_name { .dropdown:hover .cho-dropdown_technique_name {
display: block; display: block;
} }
.cho-dropdown_type_name { .cho-dropdown_type_name {
display: none; display: none;
position: absolute; position: absolute;
@ -344,7 +413,7 @@
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1; z-index: 1;
} }
.cho-dropdown_type_name a { .cho-dropdown_type_name a {
color: black; color: black;
padding: 12px 16px; padding: 12px 16px;
@ -352,16 +421,16 @@
display: block; display: block;
font-size: 16px; font-size: 16px;
} }
/* Change color of dropdown links on hover */ /* Change color of dropdown links on hover */
.cho-dropdown_type_name a:hover {background-color: #f1f1f1} .cho-dropdown_type_name a:hover {background-color: #f1f1f1}
/* Show the dropdown menu on hover */ /* Show the dropdown menu on hover */
.dropdown:hover .cho-dropdown_type_name { .dropdown:hover .cho-dropdown_type_name {
display: block; display: block;
} }
/* MANUAL INPUT */ /* MANUAL INPUT */
.cho-minute { .cho-minute {
margin-top: 10px; margin-top: 10px;
@ -574,5 +643,5 @@
-2.6em 0em 0 0em rgba(255, 255, 255, 0.7), -1.8em -1.8em 0 0em #ffffff; -2.6em 0em 0 0em rgba(255, 255, 255, 0.7), -1.8em -1.8em 0 0em #ffffff;
} }
} }

BIN
data/.DS_Store vendored

Binary file not shown.

File diff suppressed because it is too large Load Diff

82822
data/final_data_new.csv Normal file

File diff suppressed because it is too large Load Diff

38343
data/final_data_old.csv Normal file

File diff suppressed because it is too large Load Diff

BIN
notebooks/.DS_Store vendored

Binary file not shown.

View File

@ -11,33 +11,33 @@ library(purrr)
# code and data from https://github.com/Dato-Futbol/xg-model # code and data from https://github.com/Dato-Futbol/xg-model
get_shots <- function(file_path, name_detail, save_files = F){ get_shots <- function(file_path, name_detail, save_files = F){
players <- fromJSON("data/players.json") players <- fromJSON("data/players.json")
shots <- fromJSON(file_path) %>% shots <- fromJSON(file_path) %>%
filter(subEventName == "Shot") filter(subEventName == "Shot")
tags <- tibble(tags = shots$tags) %>% tags <- tibble(tags = shots$tags) %>%
hoist(tags, hoist(tags,
tags_id = "id") %>% tags_id = "id") %>%
unnest_wider(tags_id, names_sep = "") unnest_wider(tags_id, names_sep = "")
tags2 <- tags %>% tags2 <- tags %>%
mutate(is_goal = ifelse(rowSums(. == "101", na.rm = T) > 0, 1, 0), mutate(is_goal = ifelse(rowSums(. == "101", na.rm = T) > 0, 1, 0),
is_blocked = ifelse(rowSums(. == "2101", na.rm = T) > 0, 1, 0), is_blocked = ifelse(rowSums(. == "2101", na.rm = T) > 0, 1, 0),
is_CA = ifelse(rowSums(. == "1901", na.rm = T) > 0, 1, 0), # is countre attack is_CA = ifelse(rowSums(. == "1901", na.rm = T) > 0, 1, 0), # is countre attack
body_part = ifelse(rowSums(. == "401", na.rm = T) > 0, "left", body_part = ifelse(rowSums(. == "401", na.rm = T) > 0, "left",
ifelse(rowSums(. == "402", na.rm = T) > 0, "right", ifelse(rowSums(. == "402", na.rm = T) > 0, "right",
ifelse(rowSums(. == "403", na.rm = T) > 0, "head/body", "NA")))) ifelse(rowSums(. == "403", na.rm = T) > 0, "head/body", "NA"))))
pos <- tibble(positions = shots$positions) %>% pos <- tibble(positions = shots$positions) %>%
hoist(positions, hoist(positions,
y = "y", y = "y",
x = "x") %>% x = "x") %>%
unnest_wider(y, names_sep = "") %>% unnest_wider(y, names_sep = "") %>%
unnest_wider(x, names_sep = "") %>% unnest_wider(x, names_sep = "") %>%
dplyr::select(-c(x2, y2)) dplyr::select(-c(x2, y2))
shots_ok <- shots %>% shots_ok <- shots %>%
dplyr::select(matchId, teamId, playerId, eventSec, matchPeriod) %>% dplyr::select(matchId, teamId, playerId, eventSec, matchPeriod) %>%
bind_cols(pos, tags2) %>% bind_cols(pos, tags2) %>%
@ -46,14 +46,14 @@ get_shots <- function(file_path, name_detail, save_files = F){
left_join(players %>% left_join(players %>%
dplyr::select(c("wyId", "foot")), by = c("playerId" = "wyId")) %>% dplyr::select(c("wyId", "foot")), by = c("playerId" = "wyId")) %>%
mutate(league = name_detail) mutate(league = name_detail)
if(save_files){ if(save_files){
write_rds(shots, paste0("shots", name_detail, ".rds")) write_rds(shots, paste0("shots", name_detail, ".rds"))
write_rds(tags2, paste0("tags2", name_detail, ".rds")) write_rds(tags2, paste0("tags2", name_detail, ".rds"))
write_rds(pos, paste0("pos", name_detail, ".rds")) write_rds(pos, paste0("pos", name_detail, ".rds"))
write_rds(shots_ok, paste0("unblocked_shots", name_detail, ".rds")) write_rds(shots_ok, paste0("unblocked_shots", name_detail, ".rds"))
} }
shots_ok shots_ok
} }
# shotsEN <- get_shots("data/events/events_England.json", "EN") # shotsEN <- get_shots("data/events/events_England.json", "EN")
@ -63,12 +63,12 @@ get_shots <- function(file_path, name_detail, save_files = F){
# shotsGE <- get_shots("data/events/events_Germany.json", "GE") # shotsGE <- get_shots("data/events/events_Germany.json", "GE")
# shotsFR <- get_shots("data/events/events_France.json", "FR") # shotsFR <- get_shots("data/events/events_France.json", "FR")
# shotsEC <- get_shots("data/events/events_European_Championship.json", "EC") # shotsEC <- get_shots("data/events/events_European_Championship.json", "EC")
# #
# shots <- shotsEN %>% # shots <- shotsEN %>%
# bind_rows(shotsFR, shotsGE, shotsIT, shotsSP, shotsWC, shotsEC) # bind_rows(shotsFR, shotsGE, shotsIT, shotsSP, shotsWC, shotsEC)
get_final_data <- function(data) { get_final_data <- function(data) {
data <- data %>% select(eventSec, y1, x1, is_goal, is_blocked, is_CA, body_part, foot) data <- data %>% select(eventSec, y1, x1, is_goal, is_blocked, is_CA, body_part, foot)
data$x1 <- (100 - data$x1) * 105/100 data$x1 <- (100 - data$x1) * 105/100
data$y1 <- data$y1 * data$y1/100 data$y1 <- data$y1 * data$y1/100
@ -77,7 +77,7 @@ get_final_data <- function(data) {
data <- data %>% mutate(distance = sqrt( (100 - x1)^2 + (34 - y1)^2), data <- data %>% mutate(distance = sqrt( (100 - x1)^2 + (34 - y1)^2),
minute = round(eventSec / 60), minute = round(eventSec / 60),
eventSec = round(eventSec)) eventSec = round(eventSec))
data data
} }
@ -89,14 +89,14 @@ get_final_data <- function(data) {
get_data <- function(event_path, info_path) { get_data <- function(event_path, info_path) {
events <- read.csv(event_path) events <- read.csv(event_path)
info <- read.csv(info_path) info <- read.csv(info_path)
events <- merge(events, info[, c('id_odsp', 'country', 'date')], by = 'id_odsp', all.x = TRUE) events <- merge(events, info[, c('id_odsp', 'country', 'date')], by = 'id_odsp', all.x = TRUE)
data <- subset(events, event_type == 1) data <- subset(events, event_type == 1)
data_final <- data %>% select(sort_order, time, shot_place, shot_outcome, is_goal, location, bodypart, assist_method, situation, data_final <- data %>% select(sort_order, time, shot_place, shot_outcome, is_goal, location, bodypart, assist_method, situation,
fast_break) fast_break)
data_final data_final
} }
# data2 <- get_data(event_path = "data/events.csv", info_path = "data/ginf.csv") # data2 <- get_data(event_path = "data/events.csv", info_path = "data/ginf.csv")
@ -124,18 +124,18 @@ loc2locdistance <- function(x1, y1, x2, y2) {
get_shots2 <- function(json_file) { get_shots2 <- function(json_file) {
data <- fromJSON(json_file) %>% filter(type$name == "Shot") %>% dplyr::select(c(minute, position, location, shot)) data <- fromJSON(json_file) %>% filter(type$name == "Shot") %>% dplyr::select(c(minute, position, location, shot))
df_temp <- do.call(rbind, lapply(data$location, function(loc) c(120, 80) - loc)) df_temp <- do.call(rbind, lapply(data$location, function(loc) c(120, 80) - loc))
colnames(df_temp) <- c("x1", "y1") colnames(df_temp) <- c("x1", "y1")
data$x1 <- df_temp[,1] data$x1 <- df_temp[,1]
data$y1 <- df_temp[,2] data$y1 <- df_temp[,2]
data$shot$freeze_frame <- Map(function(ff, x1, y1) { data$shot$freeze_frame <- Map(function(ff, x1, y1) {
ff$x1 <- yd_to_m(x1) ff$x1 <- yd_to_m(x1)
ff$y1 <- yd_to_m(y1) ff$y1 <- yd_to_m(y1)
return(ff) return(ff)
}, },
data$shot$freeze_frame, data$x1, data$y1) data$shot$freeze_frame, data$x1, data$y1)
tryCatch({ tryCatch({
@ -148,17 +148,17 @@ get_shots2 <- function(json_file) {
df <- df %>% mutate(teammate = ifelse(teammate, "teammate", "opponent"), df <- df %>% mutate(teammate = ifelse(teammate, "teammate", "opponent"),
distance = loc2locdistance(x1 = x, y1 = y, x2 = x1, y2 = y1)) %>% distance = loc2locdistance(x1 = x, y1 = y, x2 = x1, y2 = y1)) %>%
arrange(distance) arrange(distance)
groups_count <- df %>% group_by(teammate) %>% count() %>% as.data.frame() groups_count <- df %>% group_by(teammate) %>% count() %>% as.data.frame()
if ( !("opponent" %in% groups_count$teammate) ) { if ( !("opponent" %in% groups_count$teammate) ) {
groups_count <- groups_count %>% add_row(teammate = "opponent", n = 0) groups_count <- groups_count %>% add_row(teammate = "opponent", n = 0)
} else if ( !("teammate" %in% groups_count$teammate) ) { } else if ( !("teammate" %in% groups_count$teammate) ) {
groups_count <- groups_count %>% add_row(teammate = "teammate", n = 0) groups_count <- groups_count %>% add_row(teammate = "teammate", n = 0)
} }
na_df <- as.data.frame(matrix("na", nrow = 21 - nrow(df), ncol = ncol(df))) na_df <- as.data.frame(matrix("na", nrow = 21 - nrow(df), ncol = ncol(df)))
colnames(na_df) <- colnames(df) colnames(na_df) <- colnames(df)
na_df$teammate <- rep(c("opponent", "teammate"), c(11, 10) - groups_count$n) na_df$teammate <- rep(c("opponent", "teammate"), c(11, 10) - groups_count$n)
dff <- rbind(df, na_df) dff <- rbind(df, na_df)
dff <- dff %>% group_by(teammate) %>% mutate(rown = row_number(distance)) %>% ungroup() %>% dff <- dff %>% group_by(teammate) %>% mutate(rown = row_number(distance)) %>% ungroup() %>%
@ -170,9 +170,9 @@ get_shots2 <- function(json_file) {
dff <- as.data.frame(matrix("na", nrow = 21, ncol = 3)) dff <- as.data.frame(matrix("na", nrow = 21, ncol = 3))
colnames(dff) <- c("x", "y", "teammate") colnames(dff) <- c("x", "y", "teammate")
dff$teammate <- rep(c("opponent", "teammate"), c(11, 10)) dff$teammate <- rep(c("opponent", "teammate"), c(11, 10))
dff <- dff %>% group_by(teammate) %>% mutate(rown = row_number()) %>% ungroup() %>% dff <- dff %>% group_by(teammate) %>% mutate(rown = row_number()) %>% ungroup() %>%
mutate(position_teammate = paste(teammate, rown, sep = "_")) %>% mutate(position_teammate = paste(teammate, rown, sep = "_")) %>%
select(-c(teammate, rown)) %>% select(-c(teammate, rown)) %>%
mutate(x = ifelse(x == "na", NA, x), mutate(x = ifelse(x == "na", NA, x),
y = ifelse(x == "na", NA, y)) y = ifelse(x == "na", NA, y))
} }
@ -181,7 +181,7 @@ get_shots2 <- function(json_file) {
# %>% # %>%
# stop("123") # stop("123")
wider_df <- dff %>% wider_df <- dff %>%
pivot_wider(names_from = position_teammate, values_from = c(x, y), names_sep = "_player_") %>% pivot_wider(names_from = position_teammate, values_from = c(x, y), names_sep = "_player_") %>%
mutate(across(everything(), as.numeric)) mutate(across(everything(), as.numeric))
wider_df wider_df
# wider_df <- apply(wider_df, MARGIN = 2, unlist) # wider_df <- apply(wider_df, MARGIN = 2, unlist)
@ -193,7 +193,7 @@ get_shots2 <- function(json_file) {
print(paste("An error occurred:", e$message)) print(paste("An error occurred:", e$message))
}) })
df_players_location <- df_players_location %>% t() df_players_location <- df_players_location %>% t()
tryCatch({ # TODO reduce error cases tryCatch({ # TODO reduce error cases
data$number_of_players_opponents <- mapply(function(sublist, x1_threshold) { data$number_of_players_opponents <- mapply(function(sublist, x1_threshold) {
# Extracting the first location value and converting it to numeric # Extracting the first location value and converting it to numeric
@ -213,12 +213,12 @@ get_shots2 <- function(json_file) {
# handle the error # handle the error
print(paste("An error occurred:", e$message)) print(paste("An error occurred:", e$message))
}) })
tryCatch({ # TODO reduce error cases tryCatch({ # TODO reduce error cases
data$number_of_players_teammates <- mapply(function(sublist, x1_threshold) { data$number_of_players_teammates <- mapply(function(sublist, x1_threshold) {
# Extracting the first location value and converting it to numeric # Extracting the first location value and converting it to numeric
first_location_values <- sapply(sublist$location, function(loc) as.numeric(loc[1])) first_location_values <- sapply(sublist$location, function(loc) as.numeric(loc[1]))
if ("teammate" %in% names(sublist)) { if ("teammate" %in% names(sublist)) {
# Filtering and counting # Filtering and counting
res <- sum(sublist$teammate & first_location_values > x1_threshold) # error here res <- sum(sublist$teammate & first_location_values > x1_threshold) # error here
@ -233,71 +233,71 @@ get_shots2 <- function(json_file) {
# handle the error # handle the error
print(paste("An error occurred:", e$message)) print(paste("An error occurred:", e$message))
}) })
data$shot <- data$shot %>% select(-freeze_frame, -statsbomb_xg, -key_pass_id) data$shot <- data$shot %>% select(-freeze_frame, -statsbomb_xg, -key_pass_id)
data$shot$body_part <- data$shot$body_part %>% select(-id) data$shot$body_part <- data$shot$body_part %>% select(-id)
data$shot$technique <- data$shot$technique %>% select(-id) data$shot$technique <- data$shot$technique %>% select(-id)
data$shot$type <- data$shot$type %>% select(-id) data$shot$type <- data$shot$type %>% select(-id)
data$position <- data$position %>% select(-id) data$position <- data$position %>% select(-id)
data$shot <- data$shot %>% select(-end_location) data$shot <- data$shot %>% select(-end_location)
tryCatch({ # TODO reduce error cases tryCatch({ # TODO reduce error cases
if ("one_on_one" %in% colnames(data$shot)) { if ("one_on_one" %in% colnames(data$shot)) {
data[is.na(data$shot$one_on_one), ]$shot$one_on_one <- FALSE data[is.na(data$shot$one_on_one), ]$shot$one_on_one <- FALSE
} else { } else {
data$shot$one_on_one <- FALSE data$shot$one_on_one <- FALSE
} }
if ("first_time" %in% colnames(data$shot)) { if ("first_time" %in% colnames(data$shot)) {
data[is.na(data$shot$first_time), ]$shot$first_time <- FALSE data[is.na(data$shot$first_time), ]$shot$first_time <- FALSE
} else { } else {
data$shot$first_time <- FALSE data$shot$first_time <- FALSE
} }
if ("aerial_won" %in% colnames(data$shot)) { if ("aerial_won" %in% colnames(data$shot)) {
data[is.na(data$shot$aerial_won), ]$shot$aerial_won <- FALSE data[is.na(data$shot$aerial_won), ]$shot$aerial_won <- FALSE
} else { } else {
data$shot$aerial_won <- FALSE data$shot$aerial_won <- FALSE
} }
if ("saved_to_post" %in% colnames(data$shot)) { if ("saved_to_post" %in% colnames(data$shot)) {
data[is.na(data$shot$saved_to_post), ]$shot$saved_to_post <- FALSE data[is.na(data$shot$saved_to_post), ]$shot$saved_to_post <- FALSE
} else { } else {
data$shot$saved_to_post <- FALSE data$shot$saved_to_post <- FALSE
} }
if ("deflected" %in% colnames(data$shot)) { if ("deflected" %in% colnames(data$shot)) {
data[is.na(data$shot$deflected), ]$shot$deflected <- FALSE data[is.na(data$shot$deflected), ]$shot$deflected <- FALSE
} else { } else {
data$shot$deflected <- FALSE data$shot$deflected <- FALSE
} }
if ("saved_off_target" %in% colnames(data$shot)) { if ("saved_off_target" %in% colnames(data$shot)) {
data[is.na(data$shot$saved_off_target), ]$shot$saved_off_target <- FALSE data[is.na(data$shot$saved_off_target), ]$shot$saved_off_target <- FALSE
} else { } else {
data$shot$saved_off_target <- FALSE data$shot$saved_off_target <- FALSE
} }
if ("open_goal" %in% colnames(data$shot)) { if ("open_goal" %in% colnames(data$shot)) {
data[is.na(data$shot$open_goal), ]$shot$open_goal <- FALSE data[is.na(data$shot$open_goal), ]$shot$open_goal <- FALSE
} else { } else {
data$shot$open_goal <- FALSE data$shot$open_goal <- FALSE
} }
if ("follows_dribble" %in% colnames(data$shot)) { if ("follows_dribble" %in% colnames(data$shot)) {
data[is.na(data$shot$follows_dribble), ]$shot$follows_dribble <- FALSE data[is.na(data$shot$follows_dribble), ]$shot$follows_dribble <- FALSE
} else { } else {
data$shot$follows_dribble <- FALSE data$shot$follows_dribble <- FALSE
} }
if ("redirect" %in% colnames(data$shot)) { if ("redirect" %in% colnames(data$shot)) {
data[is.na(data$shot$redirect), ]$shot$redirect <- FALSE data[is.na(data$shot$redirect), ]$shot$redirect <- FALSE
} else { } else {
data$shot$redirect <- FALSE data$shot$redirect <- FALSE
} }
if ("kick_off" %in% colnames(data$kick_off)) { if ("kick_off" %in% colnames(data$kick_off)) {
data[is.na(data$shot$kick_off), ]$shotf$kick_off <- FALSE data[is.na(data$shot$kick_off), ]$shotf$kick_off <- FALSE
} else { } else {
@ -308,21 +308,21 @@ get_shots2 <- function(json_file) {
# handle the error # handle the error
print(paste("An error occurred:", e$message)) print(paste("An error occurred:", e$message))
}) })
data <- data %>% mutate(is_goal = ifelse(shot$outcome$id == 97, 1, 0), data <- data %>% mutate(is_goal = ifelse(shot$outcome$id == 97, 1, 0),
x1 = yd_to_m(x1) %>% round(., digits = 1), x1 = yd_to_m(x1) %>% round(., digits = 1),
y1 = yd_to_m(y1) %>% round(., digits = 1), y1 = yd_to_m(y1) %>% round(., digits = 1),
angle = loc2angle(x1, y1) %>% round(., digits = 1), angle = loc2angle(x1, y1) %>% round(., digits = 1),
distance = loc2distance(x = x1, y = y1)) %>% distance = loc2distance(x = x1, y = y1)) %>%
select(-location) select(-location)
data$shot$outcome <- data$shot$outcome %>% select(-id) data$shot$outcome <- data$shot$outcome %>% select(-id)
data <- data %>% unnest(shot, names_sep = "_") %>% data <- data %>% unnest(shot, names_sep = "_") %>%
unnest(position, names_sep = "_") %>% unnest(position, names_sep = "_") %>%
unnest(shot_type, names_sep = "_") %>% unnest(shot_type, names_sep = "_") %>%
unnest(shot_outcome, names_sep = "_") %>% unnest(shot_outcome, names_sep = "_") %>%
unnest(shot_technique, names_sep = "_") %>% unnest(shot_technique, names_sep = "_") %>%
unnest(shot_body_part, names_sep = "_") unnest(shot_body_part, names_sep = "_")
data <- cbind(data, df_players_location) data <- cbind(data, df_players_location)
data data
} }
@ -338,12 +338,12 @@ skimr::skim(combined_data)
data3_final <- combined_data %>% select(-c(shot_outcome_name, data3_final <- combined_data %>% select(-c(shot_outcome_name,
shot_saved_off_target, shot_saved_off_target,
shot_saved_to_post, shot_saved_to_post,
kick_off)) %>% kick_off)) %>%
mutate(shot_kick_off = ifelse(is.na(shot_kick_off), FALSE, shot_kick_off)) mutate(shot_kick_off = ifelse(is.na(shot_kick_off), FALSE, shot_kick_off))
pattern <- "^(x_player_|y_player_).*$" pattern <- "^(x_player_|y_player_).*$"
cols <- names(data3_final)[grepl(pattern, names(data3_final))] cols <- names(data3_final)[grepl(pattern, names(data3_final))]
data_final <- data3_final %>% unnest(all_of(cols)) data_final <- data3_final %>% unnest(all_of(cols))
skimr::skim(data_final) skimr::skim(data_final)
write_csv(data_final, file = "data/final_data.csv") write_csv(data_final, file = "data/final_data.csv")
df_test <- read.csv("data/final_data.csv", nrows = 1000) #df_test <- read.csv("data/final_data.csv", nrows = 10000)
##################### The fourth dataset ############################## ##################### The fourth dataset ##############################

38343
notebooks/final_data.csv Normal file

File diff suppressed because it is too large Load Diff

82822
notebooks/final_data_new.csv Normal file

File diff suppressed because it is too large Load Diff

38343
notebooks/final_data_old.csv Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long