{"id":90,"date":"2023-04-14T21:53:23","date_gmt":"2023-04-14T21:53:23","guid":{"rendered":"https:\/\/thedataprocessblog.com\/?p=90"},"modified":"2023-04-14T21:53:23","modified_gmt":"2023-04-14T21:53:23","slug":"prevendo-gols-em-partidas-de-futebol-com-um-modelo-de-ia","status":"publish","type":"post","link":"https:\/\/thedataprocessblog.com\/?p=90&lang=pt","title":{"rendered":"Prevendo gols em partidas de futebol com um modelo de IA"},"content":{"rendered":"\n<p>Neste artigo, apresentarei os resultados e parte do processo de desenvolvimento do nosso atual modelo de probabilidade de gols.<\/p>\n\n\n\n<h3>Definindo o problema<\/h3>\n\n\n\n<p>Em primeiro lugar, explicarei nossa abordagem ao problema de prever gols em uma partida. Ao construir um modelo de previs\u00e3o, deve-se primeiro decidir se ele far\u00e1 previs\u00f5es durante o jogo ou apenas antes de acontecer. \u00c9 claro que o modelo que prev\u00ea partidas ao vivo tamb\u00e9m ser\u00e1 capaz de fazer previs\u00f5es antes dela come\u00e7ar (<em>t=0<\/em>), e por isso, optamos por desenvolver esse tipo de modelo.<\/p>\n\n\n\n<p>Tecnicamente falando, nosso modelo teria in\u00fameras vari\u00e1veis independentes, chamadas de recursos em modelos de IA, como entradas e, al\u00e9m disso, o n\u00famero relativo de gols que gostar\u00edamos de obter a probabilidade. Um exemplo \u00e9 mostrado abaixo.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/thedataprocessblog.com\/wp-content\/uploads\/2023\/04\/Captura-de-tela-de-2023-04-09-20-11-35.png\" alt=\"\" class=\"wp-image-91\" width=\"466\" height=\"452\" srcset=\"https:\/\/thedataprocessblog.com\/wp-content\/uploads\/2023\/04\/Captura-de-tela-de-2023-04-09-20-11-35.png 695w, https:\/\/thedataprocessblog.com\/wp-content\/uploads\/2023\/04\/Captura-de-tela-de-2023-04-09-20-11-35-300x292.png 300w\" sizes=\"(max-width: 466px) 100vw, 466px\" \/><figcaption class=\"wp-element-caption\">Vis\u00e3o geral do modelo: Gh = gols da casa, Ga=gols do visitante, <br>Ch=escanteios da casa, Ca=escanteios do visitante<\/figcaption><\/figure><\/div>\n\n\n<h3>Preparando os dados<\/h3>\n\n\n\n<p>Para resolver o problema, optamos por usar modelos de aprendizado de m\u00e1quina porque as rela\u00e7\u00f5es entre as vari\u00e1veis independentes e a vari\u00e1vel de destino s\u00e3o desconhecidas e muitas vezes muito complexas. Al\u00e9m disso, n\u00e3o estamos interessados em tirar conclus\u00f5es do pr\u00f3prio modelo de dados (ou seja: como \u00e9 a rela\u00e7\u00e3o entre vari\u00e1veis independentes e alvo), mas estamos apenas interessados em obter a sa\u00edda (previs\u00e3o).<\/p>\n\n\n\n<p>Conforme discutido no \u00f3timo artigo <a href=\"https:\/\/www.football-data.co.uk\/The_Wisdom_of_the_Crowd.pdf\" title=\"The Wisdom of the Crowd\">The Wisdom of the Crowd<\/a>, a melhor forma de estimar as probabilidades de um determinado evento no futebol seria pedir a v\u00e1rios apostadores que estimassem as pr\u00f3prias probabilidades. Felizmente, isso se traduz nas probabilidades de um determinado mercado para uma casa de apostas ou uma bolsa de apostas. Como voc\u00ea deve saber, a probabilidade est\u00e1 relacionada \u00e0 probabilidade impl\u00edcita da casa de apostas pela seguinte equa\u00e7\u00e3o:<\/p>\n\n\n\n<p class=\"has-text-align-center\"><em>odd = 1\/prob<\/em><sub>bm<\/sub><\/p>\n\n\n\n<p>A probabilidade impl\u00edcita da casa de apostas est\u00e1 relacionada com a probabilidade justa pela seguinte equa\u00e7\u00e3o:<\/p>\n\n\n\n<p class=\"has-text-align-center\"><em><strong>\u2211<\/strong>prob<\/em><sub><em>fair<\/em><\/sub> + M<em> = <strong>\u2211<\/strong>prob<\/em><sub>bm<\/sub> <\/p>\n\n\n\n<p>onde M \u00e9 a margem da casa de apostas.<\/p>\n\n\n\n<p>Resolvendo esta equa\u00e7\u00e3o podemos chegar a uma aproxima\u00e7\u00e3o da probabilidade justa calculada pela casa de apostas. Esse resultado \u00e9 o alvo do nosso modelo e foi usado para trein\u00e1-lo.<\/p>\n\n\n\n<h3>Treinando o modelo<\/h3>\n\n\n\n<p>O modelo foi treinado usando muitas estat\u00edsticas da partida, tanto estat\u00edsticas ao vivo quanto estat\u00edsticas pr\u00e9, e teve a probabilidade justa de o jogo terminar com a quantidade especificada de gols totais como resultado. O conjunto de dados foi dividido em dois conjuntos, o conjunto de treinamento e o conjunto de teste, como \u00e9 usual em modelos de aprendizado de m\u00e1quina. O ponto principal aqui foi que essa divis\u00e3o garantiu que as partidas do conjunto de teste n\u00e3o fossem encontradas no conjunto de treinamento, pois isso seria considerado vazamento de dados.<\/p>\n\n\n\n<p>Al\u00e9m disso, o modelo foi ajustado para usar os melhores hiperpar\u00e2metros usando <em>grid search<\/em>, sempre classificando os resultados pela fun\u00e7\u00e3o de perda, neste caso, a fun\u00e7\u00e3o de erro quadr\u00e1tico m\u00e9dio. Abaixo est\u00e3o os resultados da melhor configura\u00e7\u00e3o de modelo no conjunto de teste.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>M\u00e9trica<\/strong><\/td><td><strong>Valor<\/strong><\/td><\/tr><tr><td>Erro Absoluto M\u00e9dio<\/td><td>0.024<\/td><\/tr><tr><td>Erro Quadr\u00e1tico M\u00e9dio<\/td><td>0.00096<\/td><\/tr><tr><td>Erro m\u00e9dio<\/td><td>-0.0021<\/td><\/tr><tr><td>Desvio-pad\u00e3o do erro<\/td><td>0.031<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">M\u00e9tricas do conjunto de teste<\/figcaption><\/figure>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/thedataprocessblog.com\/wp-content\/uploads\/2023\/04\/results_xgoals-2.png\" alt=\"\" class=\"wp-image-98\" width=\"577\" height=\"433\" srcset=\"https:\/\/thedataprocessblog.com\/wp-content\/uploads\/2023\/04\/results_xgoals-2.png 640w, https:\/\/thedataprocessblog.com\/wp-content\/uploads\/2023\/04\/results_xgoals-2-300x225.png 300w\" sizes=\"(max-width: 577px) 100vw, 577px\" \/><figcaption class=\"wp-element-caption\">Valor de perda no treinamento (azul) e no teste (laranja)<\/figcaption><\/figure><\/div>\n\n\n<p>Podemos ver acima que a perda de treino diminui muito no in\u00edcio do treino e a perda de teste \u00e9 bem pequena j\u00e1 no in\u00edcio. \u00c0 primeira vista, esse gr\u00e1fico n\u00e3o parecia certo. (1) Este parece ser um exemplo de um modelo que tem uma taxa de aprendizado muito alta: o modelo se ajusta muito aos dados na primeira <em>epoch<\/em> e depois disso a taxa de aprendizado \u00e9 t\u00e3o alta que o modelo n\u00e3o consegue aprender mais nada . (2) Tamb\u00e9m \u00e9 estranho, a princ\u00edpio, que a perda de teste seja muito menor do que a perda de treinamento na primeira <em>epoch<\/em>.<\/p>\n\n\n\n<p>Em rela\u00e7\u00e3o a (1), alguns fatores devem ser considerados primeiro: 1. o conjunto de treinamento \u00e9 muito grande e 2. a perda de teste \u00e9 calculada ap\u00f3s a primeira <em>epoch<\/em> de treinamento. Se o modelo aprendeu tudo o que pode com os dados da primeira <em>epoch<\/em>, espera-se que a perda de valida\u00e7\u00e3o seja muito menor do que a perda de treinamento (lembre-se de que a perda \u00e9 calculada no final de cada processamento de lote (<em>batch)<\/em>, mesmo quando o modelo \u00e9 muito &#8220;burro&#8221;).<\/p>\n\n\n\n<p>Isso levanta a quest\u00e3o: Por que usar essa configura\u00e7\u00e3o ent\u00e3o? Por que n\u00e3o usar uma taxa de aprendizado mais baixa? A resposta \u00e9: porque depois de testar exaustivamente o modelo com v\u00e1rias configura\u00e7\u00f5es, aquele que melhor desempenhou teve a configura\u00e7\u00e3o escolhida, embora a maioria n\u00e3o tenha tido desempenho muito diferente.<\/p>\n\n\n\n<p>J\u00e1 em rela\u00e7\u00e3o a (2), o fato de a perda de teste ser menor que a perda de treinamento em \u00e9pocas posteriores se deve ao fato de que a regulariza\u00e7\u00e3o foi utilizada no treinamento do modelo. Como voc\u00ea deve saber, a regulariza\u00e7\u00e3o \u00e9 usada no treinamento, mas n\u00e3o na previs\u00e3o. Isso \u00e9 bem explicado por <a href=\"https:\/\/twitter.com\/aureliengeron\/status\/1110839223878184960\" title=\"essa thread\">essa thread<\/a>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/thedataprocessblog.com\/wp-content\/uploads\/2023\/04\/histogram_xgoals-2.png\" alt=\"\" class=\"wp-image-97\" width=\"469\" height=\"351\" srcset=\"https:\/\/thedataprocessblog.com\/wp-content\/uploads\/2023\/04\/histogram_xgoals-2.png 640w, https:\/\/thedataprocessblog.com\/wp-content\/uploads\/2023\/04\/histogram_xgoals-2-300x225.png 300w\" sizes=\"(max-width: 469px) 100vw, 469px\" \/><figcaption class=\"wp-element-caption\">Histograma do conjunto de teste<\/figcaption><\/figure><\/div>\n\n\n<p>A distribui\u00e7\u00e3o dos erros pode ser claramente vista como normal, como seria de esperar, com a m\u00e9dia e o desvio padr\u00e3o descritos acima. Com esta informa\u00e7\u00e3o, podemos concluir que aproximadamente 95% dos erros cair\u00e3o entre -5,2pp e 4,4pp de diferen\u00e7a da verdadeira probabilidade. Este \u00e9 um resultado muito interessante, especialmente considerando que as casas de apostas e as bolsas de apostas t\u00eam em m\u00e9dia 2,5pp de diferen\u00e7a entre as suas probabilidades impl\u00edcitas e podem mesmo apresentar diferen\u00e7as muito superiores.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Neste artigo, apresentarei os resultados e parte do processo de desenvolvimento do nosso atual modelo de probabilidade de gols. Definindo o problema Em primeiro lugar, explicarei nossa abordagem ao problema de prever gols em uma partida. Ao construir um modelo de previs\u00e3o, deve-se primeiro decidir se ele far\u00e1 previs\u00f5es durante o jogo ou apenas antes &hellip; <a href=\"https:\/\/thedataprocessblog.com\/?p=90&#038;lang=pt\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Prevendo gols em partidas de futebol com um modelo de IA<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[9],"tags":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/thedataprocessblog.com\/index.php?rest_route=\/wp\/v2\/posts\/90"}],"collection":[{"href":"https:\/\/thedataprocessblog.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thedataprocessblog.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thedataprocessblog.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/thedataprocessblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=90"}],"version-history":[{"count":2,"href":"https:\/\/thedataprocessblog.com\/index.php?rest_route=\/wp\/v2\/posts\/90\/revisions"}],"predecessor-version":[{"id":99,"href":"https:\/\/thedataprocessblog.com\/index.php?rest_route=\/wp\/v2\/posts\/90\/revisions\/99"}],"wp:attachment":[{"href":"https:\/\/thedataprocessblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=90"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thedataprocessblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=90"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thedataprocessblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=90"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}