Pular para o conteúdo principal

Scikit-Learn Tutorial: Baseball Analytics Pt 1

A scikit-learn tutorial to predicting MLB wins per season by modeling data to KMeans clustering model and linear regression models.
Atualizado 17 de set. de 2026  · 14 min lido

Explorar com IA

ChatGPTClaudePerplexity

A linguagem de programação Python é uma ótima opção para ciência de dados e analytics preditivo, pois vem equipada com vários pacotes que cobrem a maior parte das suas necessidades de análise. Para machine learning em Python, Scikit-learn (sklearn) é uma excelente escolha e é construída sobre NumPy, SciPy e Matplotlib (respectivamente: arrays N-dimensionais, computação científica e visualização de dados).

Neste tutorial, você vai ver como carregar dados de um banco com sqlite3, como explorar e melhorar a qualidade dos dados com pandas e matplotlib, e como usar o pacote Scikit-Learn para extrair insights reais a partir do seu conjunto de dados.

Se quiser fazer um curso de machine learning, confira o curso Supervised Learning with scikit-learn da DataCamp.

Parte 1: prevendo vitórias de times da MLB por temporada

Neste projeto, você vai testar vários modelos de machine learning do sklearn para prever o número de jogos que um time da Major League Baseball venceu em uma temporada, com base nas estatísticas do time e outras variáveis daquele ano. Se eu fosse apostador (e eu certamente sou), poderia construir um modelo usando dados históricos de temporadas anteriores para projetar a próxima. Dado o caráter de série temporal, você poderia criar indicadores como média de vitórias por ano nos últimos cinco anos, entre outros fatores, para montar um modelo bem preciso. Isso foge ao escopo deste tutorial; aqui, cada linha será tratada como independente. Cada linha dos dados representa um único time em um ano específico.

Sean Lahman compilou esses dados em seu site, e eles foram transformados em um banco sqlite aqui.

Importando os dados

Você vai ler os dados consultando um banco sqlite com o pacote sqlite3 e convertendo o resultado em um DataFrame com pandas. Os dados serão filtrados para incluir apenas times modernos atualmente ativos e apenas anos em que o time jogou 150 partidas ou mais.

Primeiro, baixe o arquivo “lahman2016.sqlite” (aqui). Em seguida, carregue o Pandas e renomeie para pd para agilizar o uso. Você deve lembrar que pd é o alias mais comum de Pandas. Por fim, carregue sqlite3 e conecte ao banco assim:

# import `pandas` and `sqlite3`import pandas as pdimport sqlite3# Connecting to SQLite Databaseconn = sqlite3.connect('lahman2016.sqlite')

Depois, escreva uma query, execute e busque os resultados.

# Querying Database for all seasons where a team played 150 or more games and is still active today. query = '''select * from Teams inner join TeamsFranchiseson Teams.franchID == TeamsFranchises.franchIDwhere Teams.G >= 150 and TeamsFranchises.active == 'Y';'''# Creating dataframe from query.Teams = conn.execute(query).fetchall()

Dica: se você quer aprender mais sobre como usar SQL com Python, considere fazer o curso Introduction to Databases in Python da DataCamp.

Usando pandas, então converta os resultados em um DataFrame e imprima as 5 primeiras linhas com o método head():

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuVGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL3RlYW1zX2RmLmNzdlwiKSIsInNhbXBsZSI6IiMgQ29udmVydCBgVGVhbXNgIHRvIERhdGFGcmFtZVxudGVhbXNfZGYgPSBwZC5EYXRhRnJhbWUoX19fX18pXG5cbiMgUHJpbnQgb3V0IGZpcnN0IDUgcm93c1xucHJpbnQoX19fX19fX19fX19fX19fKSIsInNvbHV0aW9uIjoiIyBDb252ZXJ0IHJlc3VsdHMgdG8gRGF0YUZyYW1lXG50ZWFtc19kZiA9IHBkLkRhdGFGcmFtZShUZWFtcylcblxuIyBQcmludCBvdXQgZmlyc3QgNSByb3dzXG5wcmludCh0ZWFtc19kZi5oZWFkKCkpIiwic2N0IjoiRXgoKS50ZXN0X29iamVjdChcInRlYW1zX2RmXCIpXG5FeCgpLnRlc3RfZnVuY3Rpb24oXCJwcmludFwiKSJ9

Cada coluna traz dados de um time em um ano específico. Algumas das variáveis mais importantes estão abaixo. A lista completa pode ser encontrada aqui.

  • yearID - Ano
  • teamID - Time
  • franchID - Franquia (liga com a tabela TeamsFranchise)
  • G - Jogos disputados
  • W - Vitórias
  • LgWin - Campeão da liga (Y ou N)
  • WSWin - Campeão da World Series (Y ou N)
  • R - Corridas anotadas
  • AB - At bats (idas ao bastão)
  • H - Rebatidas
  • HR - Home runs
  • BB - Walks (bases por bolas)
  • SO - Strikeouts (eliminações por strike)
  • SB - Bases roubadas
  • CS - Pego roubando base
  • HBP - Rebatedor atingido por arremesso
  • SF - Sacrifice flies (bolas de sacrifício)
  • RA - Corridas sofridas
  • ER - Corridas merecidas permitidas
  • ERA - Média de corridas merecidas
  • CG - Jogos completos
  • SHO - Shutouts (jogos sem sofrer corridas)
  • SV - Saves
  • IPOuts - Eliminações arremessadas (innings arremessados x 3)
  • HA - Rebatidas permitidas
  • HRA - Home runs sofridos
  • BBA - Walks permitidos
  • SOA - Strikeouts dos arremessadores
  • E - Erros
  • DP - Double plays
  • FP - Fielding percentage (aproveitamento defensivo)
  • name - Nome completo do time

Se você não está tão familiarizado com beisebol, aqui vai um resumo de como o jogo funciona, incluindo algumas das variáveis.

O beisebol é jogado entre dois times (que você verá nos dados por name ou teamID) com nove jogadores cada. As equipes se revezam atacando (rebater) e defendendo (campo). O time ao bastão tenta marcar corridas rebatendo a bola arremessada pelo pitcher do time de defesa e correndo, em sentido anti-horário, pelas quatro bases: primeira, segunda, terceira e home plate. A equipe de defesa tenta evitar corridas eliminando rebatedores ou corredores de base de várias maneiras, e uma corrida (R) é anotada quando um jogador completa o circuito e retorna ao home plate. Um jogador que chega em base com segurança tentará avançar nas rebatidas dos colegas, como em uma rebatida (H), roubo de base (SB) ou por outros meios.

baseball

Os times trocam ataque e defesa sempre que a equipe de campo registra três eliminações (outs). Um turno de ataque para cada time, começando pelo visitante, constitui uma entrada (inning). Um jogo tem nove entradas e vence quem tiver mais corridas ao final. O beisebol não tem cronômetro e, embora a maioria dos jogos termine na nona entrada, se houver empate após nove, o jogo vai para entradas extras e continua indefinidamente até que um time esteja à frente ao final de uma entrada extra.

Para uma explicação detalhada das regras, confira as regras oficiais da Major League Baseball.

Limpando e preparando os dados

Como você viu acima, o DataFrame não tem cabeçalhos de coluna. Você pode adicioná-los passando uma lista de nomes para o atributo columns do pandas.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxudGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL3RlYW1zX2RmLmNzdlwiKVxudGVhbXNfZGYgPSBwZC5EYXRhRnJhbWUodGVhbXMpIiwic2FtcGxlIjoiIyBBZGRpbmcgY29sdW1uIG5hbWVzIHRvIGRhdGFmcmFtZVxuY29scyA9IFsneWVhcklEJywnbGdJRCcsJ3RlYW1JRCcsJ2ZyYW5jaElEJywnZGl2SUQnLCdSYW5rJywnRycsJ0dob21lJywnVycsJ0wnLCdEaXZXaW4nLCdXQ1dpbicsJ0xnV2luJywnV1NXaW4nLCdSJywnQUInLCdIJywnMkInLCczQicsJ0hSJywnQkInLCdTTycsJ1NCJywnQ1MnLCdIQlAnLCdTRicsJ1JBJywnRVInLCdFUkEnLCdDRycsJ1NITycsJ1NWJywnSVBvdXRzJywnSEEnLCdIUkEnLCdCQkEnLCdTT0EnLCdFJywnRFAnLCdGUCcsJ25hbWUnLCdwYXJrJywnYXR0ZW5kYW5jZScsJ0JQRicsJ1BQRicsJ3RlYW1JREJSJywndGVhbUlEbGFobWFuNDUnLCd0ZWFtSURyZXRybycsJ2ZyYW5jaElEJywnZnJhbmNoTmFtZScsJ2FjdGl2ZScsJ05BYXNzb2MnXVxudGVhbXNfZGYuY29sdW1ucyA9IF9fX19cblxuIyBQcmludCB0aGUgZmlyc3Qgcm93cyBvZiBgdGVhbXNfZGZgXG5wcmludChfX19fX19fX19fX19fXylcblxuIyBQcmludCB0aGUgbGVuZ3RoIG9mIGB0ZWFtc19kZmBcbnByaW50KGxlbihfX19fX19fXykpIiwic29sdXRpb24iOiIjIEFkZGluZyBjb2x1bW4gbmFtZXMgdG8gZGF0YWZyYW1lXG5jb2xzID0gWyd5ZWFySUQnLCdsZ0lEJywndGVhbUlEJywnZnJhbmNoSUQnLCdkaXZJRCcsJ1JhbmsnLCdHJywnR2hvbWUnLCdXJywnTCcsJ0RpdldpbicsJ1dDV2luJywnTGdXaW4nLCdXU1dpbicsJ1InLCdBQicsJ0gnLCcyQicsJzNCJywnSFInLCdCQicsJ1NPJywnU0InLCdDUycsJ0hCUCcsJ1NGJywnUkEnLCdFUicsJ0VSQScsJ0NHJywnU0hPJywnU1YnLCdJUG91dHMnLCdIQScsJ0hSQScsJ0JCQScsJ1NPQScsJ0UnLCdEUCcsJ0ZQJywnbmFtZScsJ3BhcmsnLCdhdHRlbmRhbmNlJywnQlBGJywnUFBGJywndGVhbUlEQlInLCd0ZWFtSURsYWhtYW40NScsJ3RlYW1JRHJldHJvJywnZnJhbmNoSUQnLCdmcmFuY2hOYW1lJywnYWN0aXZlJywnTkFhc3NvYyddXG50ZWFtc19kZi5jb2x1bW5zID0gY29sc1xuXG4jIFByaW50IHRoZSBmaXJzdCByb3dzIG9mIGB0ZWFtc19kZmBcbnByaW50KHRlYW1zX2RmLmhlYWQoKSlcblxuIyBQcmludCB0aGUgbGVuZ3RoIG9mIGB0ZWFtc19kZmBcbnByaW50KGxlbih0ZWFtc19kZikpIiwic2N0IjoiRXgoKS5jaGVja19vYmplY3QoXCJjb2xzXCIpLmlzX2luc3RhbmNlKGxpc3QpXG5FeCgpLnRlc3RfZGF0YV9mcmFtZShcInRlYW1zX2RmXCIsIGNvbHVtbnM9Wyd5ZWFySUQnLCdsZ0lEJywndGVhbUlEJywnZnJhbmNoSUQnLCdkaXZJRCcsJ1JhbmsnLCdHJywnR2hvbWUnLCdXJywnTCcsJ0RpdldpbicsJ1dDV2luJywnTGdXaW4nLCdXU1dpbicsJ1InLCdBQicsJ0gnLCcyQicsJzNCJywnSFInLCdCQicsJ1NPJywnU0InLCdDUycsJ0hCUCcsJ1NGJywnUkEnLCdFUicsJ0VSQScsJ0NHJywnU0hPJywnU1YnLCdJUG91dHMnLCdIQScsJ0hSQScsJ0JCQScsJ1NPQScsJ0UnLCdEUCcsJ0ZQJywnbmFtZScsJ3BhcmsnLCdhdHRlbmRhbmNlJywnQlBGJywnUFBGJywndGVhbUlEQlInLCd0ZWFtSURsYWhtYW40NScsJ3RlYW1JRHJldHJvJywnZnJhbmNoSUQnLCdmcmFuY2hOYW1lJywnYWN0aXZlJywnTkFhc3NvYyddLCB1bmRlZmluZWRfY29sc19tc2c9XCJEaWQgeW91IGFzc2lnbiBgY29sc2AgdG8gYHRlYW1zX2RmLmNvbHVtbnNgP1wiKVxuRXgoKS50ZXN0X2Z1bmN0aW9uKFwidGVhbXNfZGYuaGVhZFwiLCBub3RfY2FsbGVkX21zZz1cIkRpZCB5b3UgcHJpbnQgb3V0IGB0ZWFtc19kZi5oZWFkKClgP1wiKVxuRXgoKS5jaGVja19mdW5jdGlvbihcInByaW50XCIsIGluZGV4PTApXG5FeCgpLnRlc3RfZnVuY3Rpb24oXCJsZW5cIilcbkV4KCkudGVzdF9mdW5jdGlvbihcInByaW50XCIsIGluZGV4PTEpIn0=

A função len() mostra quantas linhas você tem: 2.287 não é um volume tão grande assim, então torcemos para não haver muitos valores ausentes.

Antes de avaliar a qualidade dos dados, vamos eliminar colunas desnecessárias ou derivadas da variável alvo (Wins). Aqui, o conhecimento do domínio faz muita diferença. Não adianta saber muito de código ou estatística se você não entende os dados com que trabalha. Ser fã de beisebol a vida toda certamente me ajudou neste projeto.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZCBcbnRlYW1zID0gcGQucmVhZF9jc3YoXCJodHRwczovL3MzLmFtYXpvbmF3cy5jb20vYXNzZXRzLmRhdGFjYW1wLmNvbS9ibG9nX2Fzc2V0cy90ZWFtc19kZi5jc3ZcIikgXG50ZWFtc19kZiA9IHBkLkRhdGFGcmFtZSh0ZWFtcylcbmNvbHMgPSBbJ3llYXJJRCcsJ2xnSUQnLCd0ZWFtSUQnLCdmcmFuY2hJRCcsJ2RpdklEJywnUmFuaycsJ0cnLCdHaG9tZScsJ1cnLFxuJ0wnLCdEaXZXaW4nLCdXQ1dpbicsJ0xnV2luJywnV1NXaW4nLCdSJywnQUInLCdIJywnMkInLCczQicsJ0hSJywnQkInLCdTTycsJ1NCJyxcbidDUycsJ0hCUCcsJ1NGJywnUkEnLCdFUicsJ0VSQScsJ0NHJywnU0hPJywnU1YnLCdJUG91dHMnLCdIQScsJ0hSQScsJ0JCQScsXG4nU09BJywnRScsJ0RQJywnRlAnLCduYW1lJywncGFyaycsJ2F0dGVuZGFuY2UnLCdCUEYnLCdQUEYnLCd0ZWFtSURCUicsJ3RlYW1JRGxhaG1hbjQ1JywndGVhbUlEcmV0cm8nLCdmcmFuY2hJRCcsJ2ZyYW5jaE5hbWUnLCdhY3RpdmUnLCdOQWFzc29jJ11cbnRlYW1zX2RmLmNvbHVtbnMgPSBjb2xzIiwic2FtcGxlIjoiIyBEcm9wcGluZyB5b3VyIHVubmVjZXNhcnkgY29sdW1uIHZhcmlhYmxlcy5cbmRyb3BfY29scyA9IFsnbGdJRCcsJ2ZyYW5jaElEJywnZGl2SUQnLCdSYW5rJywnR2hvbWUnLCdMJywnRGl2V2luJywnV0NXaW4nLCdMZ1dpbicsJ1dTV2luJywnU0YnLCduYW1lJywncGFyaycsJ2F0dGVuZGFuY2UnLCdCUEYnLCdQUEYnLCd0ZWFtSURCUicsJ3RlYW1JRGxhaG1hbjQ1JywndGVhbUlEcmV0cm8nLCdmcmFuY2hJRCcsJ2ZyYW5jaE5hbWUnLCdhY3RpdmUnLCdOQWFzc29jJ11cblxuZGYgPSB0ZWFtc19kZi5kcm9wKGRyb3BfY29scywgYXhpcz0xKVxuXG4jIFByaW50IG91dCBmaXJzdCByb3dzIG9mIGBkZmBcbnByaW50KF9fX19fX19fXykiLCJzb2x1dGlvbiI6IiMgRHJvcHBpbmcgeW91ciB1bm5lY2VzYXJ5IGNvbHVtbiB2YXJpYWJsZXMuXG5kcm9wX2NvbHMgPSBbJ2xnSUQnLCdmcmFuY2hJRCcsJ2RpdklEJywnUmFuaycsJ0dob21lJywnTCcsJ0RpdldpbicsJ1dDV2luJywnTGdXaW4nLCdXU1dpbicsJ1NGJywnbmFtZScsJ3BhcmsnLCdhdHRlbmRhbmNlJywnQlBGJywnUFBGJywndGVhbUlEQlInLCd0ZWFtSURsYWhtYW40NScsJ3RlYW1JRHJldHJvJywnZnJhbmNoSUQnLCdmcmFuY2hOYW1lJywnYWN0aXZlJywnTkFhc3NvYyddXG5cbmRmID0gdGVhbXNfZGYuZHJvcChkcm9wX2NvbHMsIGF4aXM9MSlcblxuIyBQcmludCBvdXQgZmlyc3Qgcm93cyBvZiBgZGZgXG5wcmludChkZi5oZWFkKCkpIiwic2N0IjoiRXgoKS50ZXN0X29iamVjdChcImRyb3BfY29sc1wiKVxuRXgoKS50ZXN0X29iamVjdChcImRmXCIpXG5FeCgpLnRlc3RfZnVuY3Rpb24oXCJwcmludFwiKSJ9

Como você leu acima, valores nulos afetam a qualidade dos dados e podem causar problemas em algoritmos de machine learning.

Por isso, vamos removê-los em seguida. Há várias formas de eliminar valores nulos, mas primeiro é uma boa ideia exibir a contagem de nulos por coluna para decidir a melhor estratégia.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZCBcbnRlYW1zID0gcGQucmVhZF9jc3YoXCJodHRwczovL3MzLmFtYXpvbmF3cy5jb20vYXNzZXRzLmRhdGFjYW1wLmNvbS9ibG9nX2Fzc2V0cy90ZWFtc19kZi5jc3ZcIikgXG50ZWFtc19kZiA9IHBkLkRhdGFGcmFtZSh0ZWFtcylcbmNvbHMgPSBbJ3llYXJJRCcsJ2xnSUQnLCd0ZWFtSUQnLCdmcmFuY2hJRCcsJ2RpdklEJywnUmFuaycsJ0cnLCdHaG9tZScsJ1cnLFxuJ0wnLCdEaXZXaW4nLCdXQ1dpbicsJ0xnV2luJywnV1NXaW4nLCdSJywnQUInLCdIJywnMkInLCczQicsJ0hSJywnQkInLCdTTycsJ1NCJyxcbidDUycsJ0hCUCcsJ1NGJywnUkEnLCdFUicsJ0VSQScsJ0NHJywnU0hPJywnU1YnLCdJUG91dHMnLCdIQScsJ0hSQScsJ0JCQScsXG4nU09BJywnRScsJ0RQJywnRlAnLCduYW1lJywncGFyaycsJ2F0dGVuZGFuY2UnLCdCUEYnLCdQUEYnLCd0ZWFtSURCUicsJ3RlYW1JRGxhaG1hbjQ1JywndGVhbUlEcmV0cm8nLCdmcmFuY2hJRCcsJ2ZyYW5jaE5hbWUnLCdhY3RpdmUnLCdOQWFzc29jJ11cbnRlYW1zX2RmLmNvbHVtbnMgPSBjb2xzXG5kcm9wX2NvbHMgPSBbJ2xnSUQnLCdmcmFuY2hJRCcsJ2RpdklEJywnUmFuaycsJ0dob21lJywnTCcsJ0RpdldpbicsJ1dDV2luJywnTGdXaW4nLCdXU1dpbicsJ1NGJywnbmFtZScsJ3BhcmsnLCdhdHRlbmRhbmNlJywnQlBGJywnUFBGJywndGVhbUlEQlInLCd0ZWFtSURsYWhtYW40NScsJ3RlYW1JRHJldHJvJywnZnJhbmNoSUQnLCdmcmFuY2hOYW1lJywnYWN0aXZlJywnTkFhc3NvYyddXG5kZiA9IHRlYW1zX2RmLmRyb3AoZHJvcF9jb2xzLCBheGlzPTEpIiwic2FtcGxlIjoiIyBQcmludCBvdXQgbnVsbCB2YWx1ZXMgb2YgYWxsIGNvbHVtbnMgb2YgYGRmYFxucHJpbnQoX19fX19fX19fLnN1bShheGlzPTApLnRvbGlzdCgpKSIsInNvbHV0aW9uIjoiIyBQcmludCBvdXQgbnVsbCB2YWx1ZXMgb2YgYWxsIGNvbHVtbnMgb2YgYGRmYFxucHJpbnQoZGYuaXNudWxsKCkuc3VtKGF4aXM9MCkudG9saXN0KCkpIiwic2N0IjoiRXgoKS50ZXN0X2Z1bmN0aW9uKFwicHJpbnRcIikifQ==

E aqui aparece um trade-off: você precisa de dados limpos, mas não tem tanto volume para desperdiçar. Duas colunas têm poucos nulos: são 110 em SO (strikeouts) e 22 em DP (double plays). Outras duas têm muitos nulos: 419 em CS (pego roubando) e 1777 em HBP (rebatedor atingido por arremesso).

Se você eliminar as linhas com poucos nulos, perde pouco mais de 5% dos dados. Como estamos prevendo vitórias, corridas anotadas e corridas sofridas são altamente correlacionadas com o alvo. Queremos esses dados bem precisos.

Strikeouts (SO) e double plays (DP) não são tão críticos.

É melhor manter as linhas e preencher os nulos com a mediana de cada coluna usando fillna(). Já CS e HBP também não são tão importantes e têm nulos demais; o melhor é remover essas colunas.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZCBcbnRlYW1zID0gcGQucmVhZF9jc3YoXCJodHRwczovL3MzLmFtYXpvbmF3cy5jb20vYXNzZXRzLmRhdGFjYW1wLmNvbS9ibG9nX2Fzc2V0cy90ZWFtc19kZi5jc3ZcIikgXG50ZWFtc19kZiA9IHBkLkRhdGFGcmFtZSh0ZWFtcylcbmNvbHMgPSBbJ3llYXJJRCcsJ2xnSUQnLCd0ZWFtSUQnLCdmcmFuY2hJRCcsJ2RpdklEJywnUmFuaycsJ0cnLCdHaG9tZScsJ1cnLFxuJ0wnLCdEaXZXaW4nLCdXQ1dpbicsJ0xnV2luJywnV1NXaW4nLCdSJywnQUInLCdIJywnMkInLCczQicsJ0hSJywnQkInLCdTTycsJ1NCJyxcbidDUycsJ0hCUCcsJ1NGJywnUkEnLCdFUicsJ0VSQScsJ0NHJywnU0hPJywnU1YnLCdJUG91dHMnLCdIQScsJ0hSQScsJ0JCQScsXG4nU09BJywnRScsJ0RQJywnRlAnLCduYW1lJywncGFyaycsJ2F0dGVuZGFuY2UnLCdCUEYnLCdQUEYnLCd0ZWFtSURCUicsJ3RlYW1JRGxhaG1hbjQ1JywndGVhbUlEcmV0cm8nLCdmcmFuY2hJRCcsJ2ZyYW5jaE5hbWUnLCdhY3RpdmUnLCdOQWFzc29jJ11cbnRlYW1zX2RmLmNvbHVtbnMgPSBjb2xzXG5kcm9wX2NvbHMgPSBbJ2xnSUQnLCdmcmFuY2hJRCcsJ2RpdklEJywnUmFuaycsJ0dob21lJywnTCcsJ0RpdldpbicsJ1dDV2luJywnTGdXaW4nLCdXU1dpbicsJ1NGJywnbmFtZScsJ3BhcmsnLCdhdHRlbmRhbmNlJywnQlBGJywnUFBGJywndGVhbUlEQlInLCd0ZWFtSURsYWhtYW40NScsJ3RlYW1JRHJldHJvJywnZnJhbmNoSUQnLCdmcmFuY2hOYW1lJywnYWN0aXZlJywnTkFhc3NvYyddXG5kZiA9IHRlYW1zX2RmLmRyb3AoZHJvcF9jb2xzLCBheGlzPTEpXG5wcmludChkZi5pc251bGwoKS5zdW0oYXhpcz0wKS50b2xpc3QoKSkiLCJzYW1wbGUiOiIjIEVsaW1pbmF0aW5nIGNvbHVtbnMgd2l0aCBudWxsIHZhbHVlc1xuZGYgPSBkZi5kcm9wKFsnQ1MnLCdIQlAnXSwgYXhpcz0xKVxuXG4jIEZpbGxpbmcgbnVsbCB2YWx1ZXNcbmRmWydTTyddID0gZGZbJ1NPJ10uZmlsbG5hKGRmWydTTyddLm1lZGlhbigpKVxuZGZbJ0RQJ10gPSBkZlsnRFAnXS5maWxsbmEoZGZbJ0RQJ10ubWVkaWFuKCkpXG5cbiMgUHJpbnQgb3V0IG51bGwgdmFsdWVzIG9mIGFsbCBjb2x1bW5zIG9mIGBkZmBcbnByaW50KGRmLmlzbnVsbCgpLnN1bShheGlzPTApLnRvbGlzdCgpKSIsInNvbHV0aW9uIjoiIyBFbGltaW5hdGluZyBjb2x1bW5zIHdpdGggbnVsbCB2YWx1ZXNcbmRmID0gZGYuZHJvcChbJ0NTJywnSEJQJ10sIGF4aXM9MSlcblxuIyBGaWxsaW5nIG51bGwgdmFsdWVzXG5kZlsnU08nXSA9IGRmWydTTyddLmZpbGxuYShkZlsnU08nXS5tZWRpYW4oKSlcbmRmWydEUCddID0gZGZbJ0RQJ10uZmlsbG5hKGRmWydEUCddLm1lZGlhbigpKVxuXG4jIFByaW50IG91dCBudWxsIHZhbHVlcyBvZiBhbGwgY29sdW1ucyBvZiBgZGZgXG5wcmludChkZi5pc251bGwoKS5zdW0oYXhpcz0wKS50b2xpc3QoKSkiLCJzY3QiOiJFeCgpLnRlc3RfZGF0YV9mcmFtZShcImRmXCIsIGNvbHVtbnM9Wyd5ZWFySUQnLC andGVhbUlEJywgJ0cnLCAnVycsICdSJywgJ0FCJywgJ0gnLCAnMkInLCAnM0InLCAnSFInLFxuICAgICAgICdCQicsICdTTycsICdTQicsICdSQScsICdFUicsICdFUkEnLCAnQ0cnLCAnU0hPJywgJ1NWJywgJ0lQb3V0cycsXG4gICAgICAgJ0hBJywgJ0hSQScsICdCQkEnLCAnU09BJywgJ0UnLCAnRFAnLCAnRlAnXSlcbkV4KCkudGVzdF9mdW5jdGlvbihcInByaW50XCIpIn0=

Explorando e visualizando os dados

Agora que você limpou os dados, dá para explorar um pouco. Algumas visualizações simples já ajudam a entender melhor o conjunto. O matplotlib é uma ótima biblioteca para visualização.

Importe matplotlib.pyplot e renomeie como plt para agilizar. Se você estiver em um notebook Jupyter, use o magic %matplotlib inline.

Comece plotando um histograma da coluna alvo para ver a distribuição de vitórias.

# import the pyplot module from matplotlibimport matplotlib.pyplot as plt# matplotlib plots inline  %matplotlib inline# Plotting distribution of winsplt.hist(df['W'])plt.xlabel('Wins')plt.title('Distribution of Wins')plt.show()

distribution graph

Observe que, se você não estiver usando um Jupyter notebook, precisa usar plt.show() para exibir os gráficos.

Imprima a média de vitórias (W) por ano. Você pode usar o método mean().

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKSIsInNhbXBsZSI6InByaW50KGRmWydfJ10uX19fX19fKSIsInNvbHV0aW9uIjoicHJpbnQoZGZbJ1cnXS5tZWFuKCkpIiwic2N0IjoiRXgoKS50ZXN0X2Z1bmN0aW9uKFwicHJpbnRcIikifQ==

Ao explorar, pode ser útil criar faixas (bins) para a coluna alvo, mas não inclua nenhuma feature gerada a partir da coluna alvo quando for treinar o modelo. Incluir no treino uma coluna de rótulos derivada do alvo seria como dar as respostas da prova para o modelo.

Para criar seus rótulos de vitórias, crie uma função assign_win_bins que recebe um inteiro (vitórias) e retorna um inteiro de 1 a 5 conforme o valor.

Depois, crie a coluna win_bins aplicando apply() sobre a coluna de vitórias e passando a função assign_win_bins().

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKSIsInNhbXBsZSI6IiMgQ3JlYXRpbmcgYmlucyBmb3IgdGhlIHdpbiBjb2x1bW5cbmRlZiBhc3NpZ25fd2luX2JpbnMoXyk6XG4gICAgaWYgVyA8IDUwOlxuICAgICAgICByZXR1cm4gMVxuICAgIGlmIFcgPj0gNTAgYW5kIFcgPD0gNjk6XG4gICAgICAgIHJldHVybiAyXG4gICAgaWYgVyA+PSA3MCBhbmQgVyA8PSA4OTpcbiAgICAgICAgcmV0dXJuIDNcbiAgICBpZiBXID49IDkwIGFuZCBXIDw9IDEwOTpcbiAgICAgICAgcmV0dXJuIDRcbiAgICBpZiBXID49IDExMDpcbiAgICAgICAgcmV0dXJuIDVcbiAgICAgICAgXG4jIEFwcGx5IGBhc3NpZ25fd2luX2JpbnNgIHRvIGBkZlsnVyddYCAgICBcbmRmWyd3aW5fYmlucyddID0gZGZbJ18nXS5hcHBseShfX19fX19fX19fX19fXykiLCJzb2x1dGlvbiI6IiMgQ3JlYXRpbmcgYmlucyBmb3IgdGhlIHdpbiBjb2x1bW5cbmRlZiBhc3NpZ25fd2luX2JpbnMoVyk6XG4gICAgaWYgVyA8IDUwOlxuICAgICAgICByZXR1cm4gMVxuICAgIGlmIFcgPj0gNTAgYW5kIFcgPD0gNjk6XG4gICAgICAgIHJldHVybiAyXG4gICAgaWYgVyA+PSA3MCBhbmQgVyA8PSA4OTpcbiAgICAgICAgcmV0dXJuIDNcbiAgICBpZiBXID49IDkwIGFuZCBXIDw9IDEwOTpcbiAgICAgICAgcmV0dXJuIDRcbiAgICBpZiBXID49IDExMDpcbiAgICAgICAgcmV0dXJuIDVcbiAgICBcbmRmWyd3aW5fYmlucyddID0gZGZbJ1cnXS5hcHBseShhc3NpZ25fd2luX2JpbnMpIiwic2N0IjoiRXgoKS50ZXN0X2Z1bmN0aW9uX2RlZmluaXRpb24oXCJhc3NpZ25fd2luX2JpbnNcIilcbkV4KCkudGVzdF9vYmplY3QoXCJkZlwiKSJ9

Agora vamos fazer um gráfico de dispersão com o ano no eixo x e vitórias no eixo y, colorindo pela coluna win_bins.

# Plotting scatter graph of Year vs. Winsplt.scatter(df['yearID'], df['W'], c=df['win_bins'])plt.title('Wins Scatter Plot')plt.xlabel('Year')plt.ylabel('Wins')plt.show()

scikit-learn project

Como dá para ver no gráfico, há poucas temporadas antes de 1900 e o jogo era bem diferente. Por isso, faz sentido eliminar essas linhas do conjunto.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKVxuZGVmIGFzc2lnbl93aW5fYmlucyhXKTpcbiAgICBpZiBXIDwgNTA6XG4gICAgICAgIHJldHVybiAxXG4gICAgaWYgVyA+PSA1MCBhbmQgVyA8PSA2OTpcbiAgICAgICAgcmV0dXJuIDJcbiAgICBpZiBXID49IDcwIGFuZCBXIDw9IDg5OlxuICAgICAgICByZXR1cm4gM1xuICAgIGlmIFcgPj0gOTAgYW5kIFcgPD0gMTA5OlxuICAgICAgICByZXR1cm4gNFxuICAgIGlmIFcgPj0gMTEwOlxuICAgICAgICByZXR1cm4gNVxuZGZbJ3dpbl9iaW5zJ10gPSBkZlsnVyddLmFwcGx5KGFzc2lnbl93aW5fYmlucylcbmRmID0gZGZbZGZbJ3llYXJJRCddID4gMTkwMF0iLCJzYW1wbGUiOiIjIEZpbHRlciBmb3Igcm93cyB3aGVyZSAneWVhcklEJyBpcyBncmVhdGVyIHRoYW4gMTkwMFxuZGYgPSBkZltfX19fX19fX19fX19fX19fX19fXSIsInNvbHV0aW9uIjoiIyBGaWx0ZXIgZm9yIHJvd3Mgd2hlcmUgJ3llYXJJRCcgaXMgZ3JlYXRlciB0aGFuIDE5MDBcbmRmID0gZGZbZGZbJ3llYXJJRCddID4gMTkwMF0iLCJzY3QiOiJFeCgpLnRlc3Rfb2JqZWN0KFwiZGZcIikifQ==

Ao lidar com dados contínuos e criar modelos lineares, valores inteiros como o ano podem trazer ruído. É improvável que “1950” tenha um relacionamento linear simples com o resto dos dados como o modelo inferiria.

Você pode evitar isso criando novas variáveis que rotulem os dados com base no yearID.

Quem acompanha beisebol sabe que, conforme a MLB evoluiu, surgiram “eras” em que a média de corridas por jogo aumentou ou diminuiu bastante. A “dead ball era” do início dos anos 1900 foi de poucos pontos; a “steroid era” na virada do século XXI teve muitas corridas.

Vamos fazer um gráfico que indique o nível de pontuação em cada ano.

Comece criando os dicionários runs_per_year e games_per_year. Percorra o dataframe com iterrows(). Preencha runs_per_year com anos como chaves e o total de corridas anotadas no ano. Preencha games_per_year com anos e o total de jogos disputados naquele ano.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKVxuZGVmIGFzc2lnbl93aW5fYmlucyhXKTpcbiAgICBpZiBXIDwgNTA6XG4gICAgICAgIHJldHVybiAxXG4gICAgaWYgVyA+PSA1MCBhbmQgVyA8PSA2OTpcbiAgICAgICAgcmV0dXJuIDJcbiAgICBpZiBXID49IDcwIGFuZCBXIDw9IDg5OlxuICAgICAgICByZXR1cm4gM1xuICAgIGlmIFcgPj0gOTAgYW5kIFcgPD0gMTA5OlxuICAgICAgICByZXR1cm4gNFxuICAgIGlmIFcgPj0gMTEwOlxuICAgICAgICByZXR1cm4gNVxuZGZbJ3dpbl9iaW5zJ10gPSBkZlsnVyddLmFwcGx5KGFzc2lnbl93aW5fYmlucylcbmRmID0gZGZbZGZbJ3llYXJJRCddID4gMTkwMF0iLCJzYW1wbGUiOiIjIENyZWF0ZSBydW5zIHBlciB5ZWFyIGFuZCBnYW1lcyBwZXIgeWVhciBkaWN0aW9uYXJpZXNcbnJ1bnNfcGVyX3llYXIgPSB7fVxuZ2FtZXNfcGVyX3llYXIgPSB7fVxuXG5mb3IgaSwgcm93IGluIGRmLml0ZXJyb3dzKCk6XG4gICAgeWVhciA9IHJvd1sneWVhcklEJ11cbiAgICBydW5zID0gcm93WydSJ11cbiAgICBnYW1lcyA9IHJvd1snRyddXG4gICAgaWYgeWVhciBpbiBydW5zX3Blcl95ZWFyOlxuICAgICAgICBydW5zX3Blcl95ZWFyW3llYXJdID0gcnVuc19wZXJfeWVhclt5ZWFyXSArIHJ1bnNcbiAgICAgICAgZ2FtZXNfcGVyX3llYXJbeWVhcl0gPSBnYW1lc19wZXJfeWVhclt5ZWFyXSArIGdhbWVzXG4gICAgZWxzZTpcbiAgICAgICAgcnVuc19wZXJfeWVhclt5ZWFyXSA9IHJ1bnNcbiAgICAgICAgZ2FtZXNfcGVyX3llYXJbeWVhcl0gPSBnYW1lc1xuICAgICAgICBcbnByaW50KHJ1bnNfcGVyX3llYXIpXG5wcmludChnYW1lc19wZXJfeWVhcikifQ==

Depois, crie o dicionário mlb_runs_per_game. Percorra games_per_year com items(). Preencha mlb_runs_per_game com anos como chaves e o número de corridas por jogo (na liga toda) como valor.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKVxuZGVmIGFzc2lnbl93aW5fYmlucyhXKTpcbiAgICBpZiBXIDwgNTA6XG4gICAgICAgIHJldHVybiAxXG4gICAgaWYgVyA+PSA1MCBhbmQgVyA8PSA2OTpcbiAgICAgICAgcmV0dXJuIDJcbiAgICBpZiBXID49IDcwIGFuZCBXIDw9IDg5OlxuICAgICAgICByZXR1cm4gM1xuICAgIGlmIFcgPj0gOTAgYW5kIFcgPD0gMTA5OlxuICAgICAgICByZXR1cm4gNFxuICAgIGlmIFcgPj0gMTEwOlxuICAgICAgICByZXR1cm4gNVxuZGZbJ3dpbl9iaW5zJ10gPSBkZlsnVyddLmFwcGx5KGFzc2lnbl93aW5fYmlucylcbmRmID0gZGZbZGZbJ3llYXJJRCddID4gMTkwMF1cbnJ1bnNfcGVyX3llYXIgPSB7fVxuZ2FtZXNfcGVyX3llYXIgPSB7fVxuZm9yIGksIHJvdyBpbiBkZi5pdGVycm93cygpOlxuICAgIHllYXIgPSByb3dbJ3llYXJJRCddXG4gICAgcnVucyA9IHJvd1snUiddXG4gICAgZ2FtZXMgPSByb3dbJ0cnXVxuICAgIGlmIHllYXIgaW4gcnVuc19wZXJfeWVhcjpcbiAgICAgICAgcnVuc19wZXJfeWVhclt5ZWFyXSA9IHJ1bnNfcGVyX3llYXJbeWVhcl0gKyBydW5zXG4gICAgICAgIGdhbWVzX3Blcl95ZWFyW3llYXJdID0gZ2FtZXNfcGVyX3llYXJbeWVhcl0gKyBnYW1lc1xuICAgIGVsc2U6XG4gICAgICAgIHJ1bnNfcGVyX3llYXJbeWVhcl0gPSBydW5zXG4gICAgICAgIGdhbWVzX3Blcl95ZWFyW3llYXJdID0gZ2FtZXMiLCJzYW1wbGUiOiIjIENyZWF0ZSBNTEIgcnVucyBwZXIgZ2FtZSAocGVyIHllYXIpIGRpY3Rpb25hcnlcbm1sYl9ydW5zX3Blcl9nYW1lID0ge31cbmZvciBrLCB2IGluIGdhbWVzX3Blcl95ZWFyLml0ZW1zKCk6XG4gICAgeWVhciA9IGtcbiAgICBnYW1lcyA9IHZcbiAgICBydW5zID0gcnVuc19wZXJfeWVhclt5ZWFyXVxuICAgIG1sYl9ydW5zX3Blcl9nYW1lW3llYXJdID0gcnVucyAvIGdhbWVzXG4gICAgXG5wcmludChtbGJfcnVuc19wZXJfZ2FtZSkifQ==

Por fim, crie o gráfico a partir de mlb_runs_per_game, com anos no eixo x e corridas por jogo no eixo y.

# Create lists from mlb_runs_per_game dictionarylists = sorted(mlb_runs_per_game.items())x, y = zip(*lists)# Create line plot of Year vs. MLB runs per Gameplt.plot(x, y)plt.title('MLB Yearly Runs per Game')plt.xlabel('Year')plt.ylabel('MLB Runs per Game')plt.show()

baseball analytics scikit-learn

Adicionando novas features

Agora que você entendeu melhor as tendências de pontuação, pode criar novas variáveis que indiquem a “era” à qual cada linha pertence com base no yearID. Vamos seguir a mesma lógica da criação de win_bins.

Desta vez, vamos criar colunas dummies, uma por era. Você pode usar get_dummies().

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKVxuZGVmIGFzc2lnbl93aW5fYmlucyhXKTpcbiAgICBpZiBXIDwgNTA6XG4gICAgICAgIHJldHVybiAxXG4gICAgaWYgVyA+PSA1MCBhbmQgVyA8PSA2OTpcbiAgICAgICAgcmV0dXJuIDJcbiAgICBpZiBXID49IDcwIGFuZCBXIDw9IDg5OlxuICAgICAgICByZXR1cm4gM1xuICAgIGlmIFcgPj0gOTAgYW5kIFcgPD0gMTA5OlxuICAgICAgICByZXR1cm4gNFxuICAgIGlmIFcgPj0gMTEwOlxuICAgICAgICByZXR1cm4gNVxuZGZbJ3dpbl9iaW5zJ10gPSBkZlsnVyddLmFwcGx5KGFzc2lnbl93aW5fYmlucylcbmRmID0gZGZbZGZbJ3llYXJJRCddID4gMTkwMF1cbnJ1bnNfcGVyX3llYXIgPSB7fVxuZ2FtZXNfcGVyX3llYXIgPSB7fVxuZm9yIGksIHJvdyBpbiBkZi5pdGVycm93cygpOlxuICAgIHllYXIgPSByb3dbJ3llYXJJRCddXG4gICAgcnVucyA9IHJvd1snUiddXG4gICAgZ2FtZXMgPSByb3dbJ0cnXVxuICAgIGlmIHllYXIgaW4gcnVuc19wZXJfeWVhcjpcbiAgICAgICAgcnVuc19wZXJfeWVhclt5ZWFyXSA9IHJ1bnNfcGVyX3llYXJbeWVhcl0gKyBydW5zXG4gICAgICAgIGdhbWVzX3Blcl95ZWFyW3llYXJdID0gZ2FtZXNfcGVyX3llYXJbeWVhcl0gKyBnYW1lc1xuICAgIGVsc2U6XG4gICAgICAgIHJ1bnNfcGVyX3llYXJbeWVhcl0gPSBydW5zXG4gICAgICAgIGdhbWVzX3Blcl95ZWFyW3llYXJdID0gZ2FtZXNcbm1sYl9ydW5zX3Blcl9nYW1lID0ge31cbmZvciBrLCB2IGluIGdhbWVzX3Blcl95ZWFyLml0ZW1zKCk6XG4gICAgeWVhciA9IGtcbiAgICBnYW1lcyA9IHZcbiAgICBydW5zID0gcnVuc19wZXJfeWVhclt5ZWFyXVxuICAgIG1sYl9ydW5zX3Blcl9nYW1lW3llYXJdID0gcnVucyAvIGdhbWVzIiwic2FtcGxlIjoiIyBDcmVhdGluZyBcInllYXJfbGFiZWxcIiBjb2x1bW4sIHdoaWNoIHdpbGwgZ2l2ZSB5b3VyIGFsZ29yaXRobSBpbmZvcm1hdGlvbiBhYm91dCBob3cgY2VydGFpbiB5ZWFycyBhcmUgcmVsYXRlZCBcbiMgKERlYWQgYmFsbCBlcmFzLCBMaXZlIGJhbGwvU3Rlcm9pZCBFcmFzKVxuXG5kZWYgYXNzaWduX2xhYmVsKF9fX18pOlxuICAgIGlmIHllYXIgPCAxOTIwOlxuICAgICAgICByZXR1cm4gMVxuICAgIGVsaWYgeWVhciA+PSAxOTIwIGFuZCB5ZWFyIDw9IDE5NDE6XG4gICAgICAgIHJldHVybiAyXG4gICAgZWxpZiB5ZWFyID49IDE5NDIgYW5kIHllYXIgPD0gMTk0NTpcbiAgICAgICAgcmV0dXJuIDNcbiAgICBlbGlmIHllYXIgPj0gMTk0NiBhbmQgeWVhciA8PSAxOTYyOlxuICAgICAgICByZXR1cm4gNFxuICAgIGVsaWYgeWVhciA+PSAxOTYzIGFuZCB5ZWFyIDw9IDE5NzY6XG4gICAgICAgIHJldHVybiA1XG4gICAgZWxpZiB5ZWFyID49IDE5NzcgYW5kIHllYXIgPD0gMTk5MjpcbiAgICAgICAgcmV0dXJuIDZcbiAgICBlbGlmIHllYXIgPj0gMTk5MyBhbmQgeWVhciA8PSAyMDA5OlxuICAgICAgICByZXR1cm4gN1xuICAgIGVsaWYgeWVhciA+PSAyMDAxOlxuICAgICAgICByZXR1cm4gOFxuICAgICAgICBcbiMgQWRkIGB5ZWFyX2xhYmVsYCBjb2x1bW4gdG8gYGRmYCAgICBcbmRmWyd5ZWFyX2xhYmVsJ10gPSBkZlsneWVhcklEJ10uYXBwbHkoX19fX19fX19fX18pXG5cbmR1bW15X2RmID0gcGQuZ2V0X2R1bW1pZXMoZGZbJ3llYXJfbGFiZWwnXSwgcHJlZml4PSdlcmEnKVxuXG4jIENvbmNhdGVuYXRlIGBkZmAgYW5kIGBkdW1teV9kZmBcbmRmID0gcGQuY29uY2F0KFtkZiwgZHVtbXlfZGZdLCBheGlzPTEpXG5cbnByaW50KGRmLmhlYWQoKSkiLCJzb2x1dGlvbiI6IiMgQ3JlYXRpbmcgXCJ5ZWFyX2xhYmVsXCIgY29sdW1uLCB3aGljaCB3aWxsIGdpdmUgeW91ciBhbGdvcml0aG0gaW5mb3JtYXRpb24gYWJvdXQgaG93IGNlcnRhaW4geWVhcnMgYXJlIHJlbGF0ZWQgXG4jIChEZWFkIGJhbGwgZXJhcywgTGl2ZSBiYWxsL1N0ZXJvaWQgRXJhcylcblxuZGVmIGFzc2lnbl9sYWJlbCh5ZWFyKTpcbiAgICBpZiB5ZWFyIDwgMTkyMDpcbiAgICAgICAgcmV0dXJuIDFcbiAgICBlbGlmIHllYXIgPj0gMTkyMCBhbmQgeWVhciA8PSAxOTQxOlxuICAgICAgICByZXR1cm4gMlxuICAgIGVsaWYgeWVhciA+PSAxOTQyIGFuZCB5ZWFyIDw9IDE5NDU6XG4gICAgICAgIHJldHVybiAzXG4gICAgZWxpZiB5ZWFyID49IDE5NDYgYW5kIHllYXIgPD0gMTk2MjpcbiAgICAgICAgcmV0dXJuIDRcbiAgICBlbGlmIHllYXIgPj0gMTk2MyBhbmQgeWVhciA8PSAxOTc2OlxuICAgICAgICByZXR1cm4gNVxuICAgIGVsaWYgeWVhciA+PSAxOTc3IGFuZCB5ZWFyIDw9IDE5OTI6XG4gICAgICAgIHJldHVybiA2XG4gICAgZWxpZiB5ZWFyID49IDE5OTMgYW5kIHllYXIgPD0gMjAwOTpcbiAgICAgICAgcmV0dXJuIDdcbiAgICBlbGlmIHllYXIgPj0gMjAxMDpcbiAgICAgICAgcmV0dXJuIDhcbiAgICAgICAgXG4jIEFkZCBgeWVhcl9sYWJlbGAgY29sdW1uIHRvIGBkZmAgICAgXG5kZlsneWVhcl9sYWJlbCddID0gZGZbJ3llYXJJRCddLmFwcGx5KGFzc2lnbl9sYWJlbClcblxuZHVtbXlfZGYgPSBwZC5nZXRfZHVtbWllcyhkZlsneWVhcl9sYWJlbCddLCBwcmVmaXg9J2VyYScpXG5cbiMgQ29uY2F0ZW5hdGUgYGRmYCBhbmQgYGR1bW15X2RmYFxuZGYgPSBwZC5jb25jYXQoW2RmLCBkdW1teV9kZl0sIGF4aXM9MSlcblxucHJpbnQoZGYuaGVhZCgpKSIsInNjdCI6IkV4KCkudGVzdF9mdW5jdGlvbl9kZWZpbml0aW9uKFwiYXNzaWduX2xhYmVsXCIpXG5FeCgpLnRlc3RfZGF0YV9mcmFtZShcImRmXCIpXG5FeCgpLnRlc3RfZGF0YV9mcmFtZShcImR1bW15X2RmXCIpXG5FeCgpLmNoZWNrX29iamVjdChcImRmXCIpLmhhc19lcXVhbF9rZXkoXCJ5ZWFyX2xhYmVsXCIpXG5FeCgpLnRlc3RfZnVuY3Rpb24oXCJwcmludFwiKSJ9

Como você já calculou as corridas por jogo da MLB por ano, adicione essa informação ao conjunto.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKVxuZGVmIGFzc2lnbl93aW5fYmlucyhXKTpcbiAgICBpZiBXIDwgNTA6XG4gICAgICAgIHJldHVybiAxXG4gICAgaWYgVyA+PSA1MCBhbmQgVyA8PSA2OTpcbiAgICAgICAgcmV0dXJuIDJcbiAgICBpZiBXID49IDcwIGFuZCBXIDw9IDg5OlxuICAgICAgICByZXR1cm4gM1xuICAgIGlmIFcgPj0gOTAgYW5kIFcgPD0gMTA5OlxuICAgICAgICByZXR1cm4gNFxuICAgIGlmIFcgPj0gMTEwOlxuICAgICAgICByZXR1cm4gNVxuZGZbJ3dpbl9iaW5zJ10gPSBkZlsnVyddLmFwcGx5KGFzc2lnbl93aW5fYmlucylcbmRmID0gZGZbZGZbJ3llYXJJRCddID4gMTkwMF1cbnJ1bnNfcGVyX3llYXIgPSB7fVxuZ2FtZXNfcGVyX3llYXIgPSB7fVxuZm9yIGksIHJvdyBpbiBkZi5pdGVycm93cygpOlxuICAgIHllYXIgPSByb3dbJ3llYXJJRCddXG4gICAgcnVucyA9IHJvd1snUiddXG4gICAgZ2FtZXMgPSByb3dbJ0cnXVxuICAgIGlmIHllYXIgaW4gcnVuc19wZXJfeWVhcjpcbiAgICAgICAgcnVuc19wZXJfeWVhclt5ZWFyXSA9IHJ1bnNfcGVyX3llYXJbeWVhcl0gKyBydW5zXG4gICAgICAgIGdhbWVzX3Blcl95ZWFyW3llYXJdID0gZ2FtZXNfcGVyX3llYXJbeWVhcl0gKyBnYW1lc1xuICAgIGVsc2U6XG4gICAgICAgIHJ1bnNfcGVyX3llYXJbeWVhcl0gPSBydW5zXG4gICAgICAgIGdhbWVzX3Blcl95ZWFyW3llYXJdID0gZ2FtZXNcbm1sYl9ydW5zX3Blcl9nYW1lID0ge31cbmZvciBrLCB2IGluIGdhbWVzX3Blcl95ZWFyLml0ZW1zKCk6XG4gICAgeWVhciA9IGtcbiAgICBnYW1lcyA9IHZcbiAgICBydW5zID0gcnVuc19wZXJfeWVhclt5ZWFyXVxuICAgIG1sYl9ydW5zX3Blcl9nYW1lW3llYXJdID0gcnVucyAvIGdhbWVzXG5kZWYgYXNzaWduX2xhYmVsKHllYXIpOlxuICAgIGlmIHllYXIgPCAxOTIwOlxuICAgICAgICByZXR1cm4gMVxuICAgIGVsaWYgeWVhciA+PSAxOTIwIGFuZCB5ZWFyIDw9IDE5NDE6XG4gICAgICAgIHJldHVybiAyXG4gICAgZWxpZiB5ZWFyID49IDE5NDIgYW5kIHllYXIgPD0gMTk0NTpcbiAgICAgICAgcmV0dXJuIDNcbiAgICBlbGlmIHllYXIgPj0gMTk0NiBhbmQgeWVhciA8PSAxOTYyOlxuICAgICAgICByZXR1cm4gNFxuICAgIGVsaWYgeWVhciA+PSAxOTYzIGFuZCB5ZWFyIDw9IDE5NzY6XG4gICAgICAgIHJldHVybiA1XG4gICAgZWxpZiB5ZWFyID49IDE5NzcgYW5kIHllYXIgPD0gMTk5MjpcbiAgICAgICAgcmV0dXJuIDZcbiAgICBlbGlmIHllYXIgPj0gMTk5MyBhbmQgeWVhciA8PSAyMDA5OlxuICAgICAgICByZXR1cm4gN1xuICAgIGVsaWYgeWVhciA+PSAyMDEwOlxuICAgICAgICByZXR1cm4gOFxuICAgIFxuZGZbJ3llYXJfbGFiZWwnXSA9IGRmWyd5ZWFySUQnXS5hcHBseShhc3NpZ25fbGFiZWwpXG5kdW1teV9kZiA9IHBkLmdldF9kdW1taWVzKGRmWyd5ZWFyX2xhYmVsJ10sIHByZWZpeD0nZXJhJylcblxuZGYgPSBwZC5jb25jYXQoW2RmLCBkdW1teV9kZl0sIGF4aXM9MSkiLCJzYW1wbGUiOiIjIENyZWF0ZSBjb2x1bW4gZm9yIE1MQiBydW5zIHBlciBnYW1lIGZyb20gdGhlIG1sYl9ydW5zX3Blcl9nYW1lIGRpY3Rpb25hcnlcbmRlZiBhc3NpZ25fbWxiX3JwZyh5ZWFyKTpcbiAgICByZXR1cm4gbWxiX3J1bnNfcGVyX2dhbWVbeWVhcl1cblxuZGZbJ21sYl9ycGcnXSA9IGRmWyd5ZWFySUQnXS5hcHBseShhc3NpZ25fbWxiX3JwZykiLCJzb2x1dGlvbiI6IiMgQ3JlYXRlIGNvbHVtbiBmb3IgTUxCIHJ1bnMgcGVyIGdhbWUgZnJvbSB0aGUgbWxiX3J1bnNfcGVyX2dhbWUgZGljdGlvbmFyeVxuZGVmIGFzc2lnbl9tbGJfcnBnKHllYXIpOlxuICAgIHJldHVybiBtbGJfcnVuc19wZXJfZ2FtZVt5ZWFyXVxuXG5kZlsnbWxiX3JwZyddID0gZGZbJ3llYXJJRCddLmFwcGx5KGFzc2lnbl9tbGJfcnBnKSIsInNjdCI6IkV4KCkudGVzdF9mdW5jdGlvbl9kZWZpbml0aW9uKFwiYXNzaWduX21sYl9ycGdcIilcbkV4KCkudGVzdF9vYmplY3QoXCJkZlwiKSJ9

Agora, converta os anos em décadas criando colunas dummies por década. Depois, remova as colunas que não precisa mais.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKVxuZGVmIGFzc2lnbl93aW5fYmlucyhXKTpcbiAgICBpZiBXIDwgNTA6XG4gICAgICAgIHJldHVybiAxXG4gICAgaWYgVyA+PSA1MCBhbmQgVyA8PSA2OTpcbiAgICAgICAgcmV0dXJuIDJcbiAgICBpZiBXID49IDcwIGFuZCBXIDw9IDg5OlxuICAgICAgICByZXR1cm4gM1xuICAgIGlmIFcgPj0gOTAgYW5kIFcgPD0gMTA5OlxuICAgICAgICByZXR1cm4gNFxuICAgIGlmIFcgPj0gMTEwOlxuICAgICAgICByZXR1cm4gNVxuZGZbJ3dpbl9iaW5zJ10gPSBkZlsnVyddLmFwcGx5KGFzc2lnbl93aW5fYmlucylcbmRmID0gZGZbZGZbJ3llYXJJRCddID4gMTkwMF1cbnJ1bnNfcGVyX3llYXIgPSB7fVxuZ2FtZXNfcGVyX3llYXIgPSB7fVxuZm9yIGksIHJvdyBpbiBkZi5pdGVycm93cygpOlxuICAgIHllYXIgPSByb3dbJ3llYXJJRCddXG4gICAgcnVucyA9IHJvd1snUiddXG4gICAgZ2FtZXMgPSByb3dbJ0cnXVxuICAgIGlmIHllYXIgaW4gcnVuc19wZXJfeWVhcjpcbiAgICAgICAgcnVuc19wZXJfeWVhclt5ZWFyXSA9IHJ1bnNfcGVyX3llYXJbeWVhcl0gKyBydW5zXG4gICAgICAgIGdhbWVzX3Blcl95ZWFyW3llYXJdID0gZ2FtZXNfcGVyX3llYXJbeWVhcl0gKyBnYW1lc1xuICAgIGVsc2U6XG4gICAgICAgIHJ1bnNfcGVyX3llYXJbeWVhcl0gPSBydW5zXG4gICAgICAgIGdhbWVzX3Blcl95ZWFyW3llYXJdID0gZ2FtZXNcbm1sYl9ydW5zX3Blcl9nYW1lID0ge31cbmZvciBrLCB2IGluIGdhbWVzX3Blcl95ZWFyLml0ZW1zKCk6XG4gICAgeWVhciA9IGtcbiAgICBnYW1lcyA9IHZcbiAgICBydW5zID0gcnVuc19wZXJfeWVhclt5ZWFyXVxuICAgIG1sYl9ydW5zX3Blcl9nYW1lW3llYXJdID0gcnVucyAvIGdhbWVzXG5kZWYgYXNzaWduX2xhYmVsKHllYXIpOlxuICAgIGlmIHllYXIgPCAxOTIwOlxuICAgICAgICByZXR1cm4gMVxuICAgIGVsaWYgeWVhciA+PSAxOTIwIGFuZCB5ZWFyIDw9IDE5NDE6XG4gICAgICAgIHJldHVybiAyXG4gICAgZWxpZiB5ZWFyID49IDE5NDIgYW5kIHllYXIgPD0gMTk0NTpcbiAgICAgICAgcmV0dXJuIDNcbiAgICBlbGlmIHllYXIgPj0gMTk0NiBhbmQgeWVhciA8PSAxOTYyOlxuICAgICAgICByZXR1cm4gNFxuICAgIGVsaWYgeWVhciA+PSAxOTYzIGFuZCB5ZWFyIDw9IDE5NzY6XG4gICAgICAgIHJldHVybiA1XG4gICAgZWxpZiB5ZWFyID49IDE5NzcgYW5kIHllYXIgPD0gMTk5MjpcbiAgICAgICAgcmV0dXJuIDZcbiAgICBlbGlmIHllYXIgPj0gMTk5MyBhbmQgeWVhciA8PSAyMDA5OlxuICAgICAgICByZXR1cm4gN1xuICAgIGVsaWYgeWVhciA+PSAyMDEwOlxuICAgICAgICByZXR1cm4gOFxuZGZbJ3llYXJfbGFiZWwnXSA9IGRmWyd5ZWFySUQnXS5hcHBseShhc3NpZ25fbGFiZWwpXG5kdW1teV9kZiA9IHBkLmdldF9kdW1taWVzKGRmWyd5ZWFyX2xhYmVsJ10sIHByZWZpeD0nZXJhJylcbmRmID0gcGQuY29uY2F0KFtkZiwgZHVtbXlfZGZdLCBheGlzPTEpIiwic2FtcGxlIjoiIyBDb252ZXJ0IHllYXJzIGludG8gZGVjYWRlIGJpbnMgYW5kIGNyZWF0aW5nIGR1bW15IHZhcmlhYmxlc1xuZGVmIGFzc2lnbl9kZWNhZGUoeWVhcik6XG4gICAgaWYgeWVhciA8IDE5MjA6XG4gICAgICAgIHJldHVybiAxOTEwXG4gICAgZWxpZiB5ZWFyID49IDE5MjAgYW5kIHllYXIgPD0gMTkyOTpcbiAgICAgICAgcmV0dXJuIDE5MjBcbiAgICBlbGlmIHllYXIgPj0gMTkzMCBhbmQgeWVhciA8PSAxOTM5OlxuICAgICAgICByZXR1cm4gMTkzMFxuICAgIGVsaWYgeWVhciA+PSAxOTQwIGFuZCB5ZWFyIDw9IDE5NDk6XG4gICAgICAgIHJldHVybiAxOTQwXG4gICAgZWxpZiB5ZWFyID49IDE5NTAgYW5kIHllYXIgPD0gMTk1OTpcbiAgICAgICAgcmV0dXJuIDE5NTBcbiAgICBlbGlmIHllYXIgPj0gMTk2MCBhbmQgeWVhciA8PSAxOTY5OlxuICAgICAgICByZXR1cm4gMTk2MFxuICAgIGVsaWYgeWVhciA+PSAxOTcwIGFuZCB5ZWFyIDw9IDE5Nzk6XG4gICAgICAgIHJldHVybiAxOTcwXG4gICAgZWxpZiB5ZWFyID49IDE5ODAgYW5kIHllYXIgPD0gMTk4OTpcbiAgICAgICAgcmV0dXJuIDE5ODBcbiAgICBlbGlmIHllYXIgPj0gMTk5MCBhbmQgeWVhciA8PSAxOTk5OlxuICAgICAgICByZXR1cm4gMTk5MFxuICAgIGVsaWYgeWVhciA+PSAyMDAwIGFuZCB5ZWFyIDw9IDIwMDk6XG4gICAgICAgIHJldHVybiAyMDAwXG4gICAgZWxpZiB5ZWFyID49IDIwMTA6XG4gICAgICAgIHJldHVybiAyMDEwXG4gICAgXG5kZlsnZGVjYWRlX2xhYmVsJ10gPSBkZlsneWVhcklEJ10uYXBwbHkoYXNzaWduX2RlY2FkZSlcbmRlY2FkZV9kZiA9IHBkLmdldF9kdW1taWVzKGRmWydkZWNhZGVfbGFiZWwnXSwgcHJlZml4PSdkZWNhZGUnKVxuZGYgPSBwZC5jb25jYXQoW2RmLCBkZWNhZGVfZGZdLCBheGlzPTEpXG5cbiMgRHJvcCB1bm5lY2Vzc2FyeSBjb2x1bW5zXG5kZiA9IGRmLmRyb3AoWyd5ZWFySUQnLCd5ZWFyX2xhYmVsJywnZGVjYWRlX2xhYmVsJ10sIGF4aXM9MSkifQ==

Em beisebol, o que decide é quantas corridas você marca e quantas permite. Você pode aumentar bastante a acurácia criando colunas que são razões de outras colunas. Corridas por jogo e corridas sofridas por jogo serão ótimas features para adicionar.

Com o Pandas, isso é simples: crie uma nova coluna dividindo R por G para obter R_per_game.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKVxuZGVmIGFzc2lnbl93aW5fYmlucyhXKTpcbiAgICBpZiBXIDwgNTA6XG4gICAgICAgIHJldHVybiAxXG4gICAgaWYgVyA+PSA1MCBhbmQgVyA8PSA2OTpcbiAgICAgICAgcmV0dXJuIDJcbiAgICBpZiBXID49IDcwIGFuZCBXIDw9IDg5OlxuICAgICAgICByZXR1cm4gM1xuICAgIGlmIFcgPj0gOTAgYW5kIFcgPD0gMTA5OlxuICAgICAgICByZXR1cm4gNFxuICAgIGlmIFcgPj0gMTEwOlxuICAgICAgICByZXR1cm4gNVxuZGZbJ3dpbl9iaW5zJ10gPSBkZlsnVyddLmFwcGx5KGFzc2lnbl93aW5fYmlucylcbmRmID0gZGZbZGZbJ3llYXJJRCddID4gMTkwMF1cbnJ1bnNfcGVyX3llYXIgPSB7fVxuZ2FtZXNfcGVyX3llYXIgPSB7fVxuZm9yIGksIHJvdyBpbiBkZi5pdGVycm93cygpOlxuICAgIHllYXIgPSByb3dbJ3llYXJJRCddXG4gICAgcnVucyA9IHJvd1snUiddXG4gICAgZ2FtZXMgPSByb3dbJ0cnXVxuICAgIGlmIHllYXIgaW4gcnVuc19wZXJfeWVhcjpcbiAgICAgICAgcnVuc19wZXJfeWVhclt5ZWFyXSA9IHJ1bnNfcGVyX3llYXJbeWVhcl0gKyBydW5zXG4gICAgICAgIGdhbWVzX3Blcl95ZWFyW3llYXJdID0gZ2FtZXNfcGVyX3llYXJbeWVhcl0gKyBnYW1lc1xuICAgIGVsc2U6XG4gICAgICAgIHJ1bnNfcGVyX3llYXJbeWVhcl0gPSBydW5zXG4gICAgICAgIGdhbWVzX3Blcl95ZWFyW3llYXJdID0gZ2FtZXNcbm1sYl9ydW5zX3Blcl9nYW1lID0ge31cbmZvciBrLCB2IGluIGdhbWVzX3Blcl95ZWFyLml0ZW1zKCk6XG4gICAgeWVhciA9IGtcbiAgICBnYW1lcyA9IHZcbiAgICBydW5zID0gcnVuc19wZXJfeWVhclt5ZWFyXVxuICAgIG1sYl9ydW5zX3Blcl9nYW1lW3llYXJdID0gcnVucyAvIGdhbWVzXG5kZWYgYXNzaWduX2xhYmVsKHllYXIpOlxuICAgIGlmIHllYXIgPCAxOTIwOlxuICAgICAgICByZXR1cm4gMVxuICAgIGVsaWYgeWVhciA+PSAxOTIwIGFuZCB5ZWFyIDw9IDE5NDE6XG4gICAgICAgIHJldHVybiAyXG4gICAgZWxpZiB5ZWFyID49IDE5NDIgYW5kIHllYXIgPD0gMTk0NTpcbiAgICAgICAgcmV0dXJuIDNcbiAgICBlbGlmIHllYXIgPj0gMTk0NiBhbmQgeWVhciA8PSAxOTYyOlxuICAgICAgICByZXR1cm4gNFxuICAgIGVsaWYgeWVhciA+PSAxOTYzIGFuZCB5ZWFyIDw9IDE5NzY6XG4gICAgICAgIHJldHVybiA1XG4gICAgZWxpZiB5ZWFyID49IDE5NzcgYW5kIHllYXIgPD0gMTk5MjpcbiAgICAgICAgcmV0dXJuIDZcbiAgICBlbGlmIHllYXIgPj0gMTk5MyBhbmQgeWVhciA8PSAyMDA5OlxuICAgICAgICByZXR1cm4gN1xuICAgIGVsaWYgeWVhciA+PSAyMDEwOlxuICAgICAgICByZXR1cm4gOFxuZGZbJ3llYXJfbGFiZWwnXSA9IGRmWyd5ZWFySUQnXS5hcHBseShhc3NpZ25fbGFiZWwpXG5kdW1teV9kZiA9IHBkLmdldF9kdW1taWVzKGRmWyd5ZWFyX2xhYmVsJ10sIHByZWZpeD0nZXJhJylcbmRmID0gcGQuY29uY2F0KFtkZiwgZHVtbXlfZGZdLCBheGlzPTEpXG5kZWYgYXNzaWduX2RlY2FkZSh5ZWFyKTpcbiAgICBpZiB5ZWFyIDwgMTkyMDpcbiAgICAgICAgcmV0dXJuIDE5MTBcbiAgICBlbGlmIHllYXIgPj0gMTkyMCBhbmQgeWVhciA8PSAxOTI5OlxuICAgICAgICByZXR1cm4gMTkyMFxuICAgIGVsaWYgeWVhciA+PSAxOTMwIGFuZCB5ZWFyIDw9IDE5Mzk6XG4gICAgICAgIHJldHVybiAxOTMwXG4gICAgZWxpZiB5ZWFyID49IDE5NDAgYW5kIHllYXIgPD0gMTk0OTpcbiAgICAgICAgcmV0dXJuIDE5NDBcbiAgICBlbGlmIHllYXIgPj0gMTk1MCBhbmQgeWVhciA8PSAxOTU5OlxuICAgICAgICByZXR1cm4gMTk1MFxuICAgIGVsaWYgeWVhciA+PSAxOTYwIGFuZCB5ZWFyIDw9IDE5Njk6XG4gICAgICAgIHJldHVybiAxOTYwXG4gICAgZWxpZiB5ZWFyID49IDE5NzAgYW5kIHllYXIgPD0gMTk3OTpcbiAgICAgICAgcmV0dXJuIDE5NzBcbiAgICBlbGlmIHllYXIgPj0gMTk4MCBhbmQgeWVhciA8PSAxOTg5OlxuICAgICAgICByZXR1cm4gMTk4MFxuICAgIGVsaWYgeWVhciA+PSAxOTkwIGFuZCB5ZWFyIDw9IDE5OTk6XG4gICAgICAgIHJldHVybiAxOTkwXG4gICAgZWxpZiB5ZWFyID49IDIwMDAgYW5kIHllYXIgPD0gMjAwOTpcbiAgICAgICAgcmV0dXJuIDIwMDBcbiAgICBlbGlmIHllYXIgPj0gMjAxMDpcbiAgICAgICAgcmV0dXJuIDIwMTBcbmRmWydkZWNhZGVfbGFiZWwnXSA9IGRmWyd5ZWFySUQnXS5hcHBseShhc3NpZ25fZGVjYWRlKVxuZGVjYWRlX2RmID0gcGQuZ2V0X2R1bW1pZXMoZGZbJ2RlY2FkZV9sYWJlbCddLCBwcmVmaXg9J2RlY2FkZScpXG5kZiA9IHBkLmNvbmNhdChbZGYsIGRlY2FkZV9kZl0sIGF4aXM9MSlcbmRmID0gZGYuZHJvcChbJ3llYXJJRCcsJ3llYXJfbGFiZWwnLCdkZWNhZGVfbGFiZWwnXSwgYXhpcz0xKSIsInNhbXBsZSI6IiMgQ3JlYXRlIG5ldyBmZWF0dXJlcyBmb3IgUnVucyBwZXIgR2FtZSBhbmQgUnVucyBBbGxvd2VkIHBlciBHYW1lXG5kZlsnUl9wZXJfZ2FtZSddID0gZGZbJ1InXSAvIGRmWydHJ11cbmRmWydSQV9wZXJfZ2FtZSddID0gZGZbJ1JBJ10gLyBkZlsnRyddIn0=

Agora veja como essas duas novas variáveis se relacionam com a coluna de vitórias fazendo dois gráficos de dispersão. Coloque corridas por jogo no eixo x de um gráfico e corridas sofridas por jogo no eixo x do outro. Em ambos, use W no eixo y.

# Create scatter plots for runs per game vs. wins and runs allowed per game vs. winsfig = plt.figure(figsize=(12, 6))ax1 = fig.add_subplot(1,2,1)ax2 = fig.add_subplot(1,2,2)ax1.scatter(df['R_per_game'], df['W'], c='blue')ax1.set_title('Runs per Game vs. Wins')ax1.set_ylabel('Wins')ax1.set_xlabel('Runs per Game')ax2.scatter(df['RA_per_game'], df['W'], c='red')ax2.set_title('Runs Allowed per Game vs. Wins')ax2.set_xlabel('Runs Allowed per Game')plt.show()

clusters

Antes de partir para modelos de machine learning, é útil ver como cada variável se correlaciona com o alvo. O Pandas facilita isso com corr().

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zX3dob2xlLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKSIsInNhbXBsZSI6ImRmLmNvcnIoKVsnVyddIn0=

Outra feature que você pode adicionar são rótulos derivados de um algoritmo de clusterização K-means do sklearn. K-means é um algoritmo simples que particiona os dados em k centróides indicados. Cada ponto é atribuído ao cluster cujo centróide tem a menor distância euclidiana a ele.

Saiba mais sobre K-means aqui.

Primeiro, crie um DataFrame sem a variável alvo:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zX3dob2xlLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKSIsInNhbXBsZSI6ImF0dHJpYnV0ZXMgPSBbJ0cnLCdSJywnQUInLCdIJywnMkInLCczQicsJ0hSJywnQkInLCdTTycsJ1NCJywnUkEnLCdFUicsJ0VSQScsJ0NHJyxcbidTSE8nLCdTVicsJ0lQb3V0cycsJ0hBJywnSFJBJywnQkJBJywnU09BJywnRScsJ0RQJywnRlAnLCdlcmFfMScsJ2VyYV8yJywnZXJhXzMnLCdlcmFfNCcsJ2VyYV81JywnZXJhXzYnLCdlcmFfNycsJ2VyYV84JywnZGVjYWRlXzE5MTAnLCdkZWNhZGVfMTkyMCcsJ2RlY2FkZV8xOTMwJywnZGVjYWRlXzE5NDAnLCdkZWNhZGVfMTk1MCcsJ2RlY2FkZV8xOTYwJywnZGVjYWRlXzE5NzAnLCdkZWNhZGVfMTk4MCcsJ2RlY2FkZV8xOTkwJywnZGVjYWRlXzIwMDAnLCdkZWNhZGVfMjAxMCcsJ1JfcGVyX2dhbWUnLCdSQV9wZXJfZ2FtZScsJ21sYl9ycGcnXVxuXG5kYXRhX2F0dHJpYnV0ZXMgPSBkZlthdHRyaWJ1dGVzXVxuXG4jIFByaW50IHRoZSBmaXJzdCByb3dzIG9mIGBkZmBcbnByaW50KGRmLmhlYWQoKSkiLCJzb2x1dGlvbiI6ImF0dHJpYnV0ZXMgPSBbJ0cnLCdSJywnQUInLCdIJywnMkInLCczQicsJ0hSJywnQkInLCdTTycsJ1NCJywnUkEnLCdFUicsJ0VSQScsJ0NHJyxcbidTSE8nLCdTVicsJ0lQb3V0cycsJ0hBJywnSFJBJywnQkJBJywnU09BJywnRScsJ0RQJywnRlAnLCdlcmFfMScsJ2VyYV8yJywnZXJhXzMnLCdlcmFfNCcsJ2VyYV81JywnZXJhXzYnLCdlcmFfNycsJ2VyYV84JywnZGVjYWRlXzE5MTAnLCdkZWNhZGVfMTkyMCcsJ2RlY2FkZV8xOTMwJywnZGVjYWRlXzE5NDAnLCdkZWNhZGVfMTk1MCcsJ2RlY2FkZV8xOTYwJywnZGVjYWRlXzE5NzAnLCdkZWNhZGVfMTk4MCcsJ2RlY2FkZV8xOTkwJywnZGVjYWRlXzIwMDAnLCdkZWNhZGVfMjAxMCcsJ1JfcGVyX2dhbWUnLCdSQV9wZXJfZ2FtZScsJ21sYl9ycGcnXVxuXG5kYXRhX2F0dHJpYnV0ZXMgPSBkZlthdHRyaWJ1dGVzXVxuXG4jIFByaW50IHRoZSBmaXJzdCByb3dzIG9mIGBkZmBcbnByaW50KGRmLmhlYWQoKSkiLCJzY3QiOiJFeCgpLnRlc3Rfb2JqZWN0KFwiYXR0cmlidXRlc1wiKVxuRXgoKS50ZXN0X29iamVjdChcImRhdGFfYXR0cmlidXRlc1wiKVxuRXgoKS50ZXN0X2Z1bmN0aW9uKFwicHJpbnRcIikifQ==

Um ponto a definir antes de usar K-means é a quantidade de clusters. Você pode ter uma noção melhor usando a função silhouette_score() do sklearn. Ela retorna o coeficiente de silhueta médio. Quanto maior, melhor — a medida tende a cair conforme você aumenta o número de clusters.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zX3dob2xlLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKVxuYXR0cmlidXRlcyA9IFsnRycsJ1InLCdBQicsJ0gnLCcyQicsJzNCJywnSFInLCdCQicsJ1NPJywnU0InLCdSQScsJ0VSJywnRVJBJywnQ0cnLFxuJ1NITycsJ1NWJywnSVBvdXRzJywnSEEnLCdIUkEnLCdCQkEnLCdTT0EnLCdFJywnRFAnLCdGUCcsJ2VyYV8xJywnZXJhXzInLCdlcmFfMycsJ2VyYV80JywnZXJhXzUnLCdlcmFfNicsJ2VyYV83JywnZXJhXzgnLCdkZWNhZGVfMTkxMCcsJ2RlY2FkZV8xOTIwJywnZGVjYWRlXzE5MzAnLCdkZWNhZGVfMTk0MCcsJ2RlY2FkZV8xOTUwJywnZGVjYWRlXzE5NjAnLCdkZWNhZGVfMTk3MCcsJ2RlY2FkZV8xOTgwJywnZGVjYWRlXzE5OTAnLCdkZWNhZGVfMjAwMCcsJ2RlY2FkZV8yMDEwJywnUl9wZXJfZ2FtZScsJ1JBX3Blcl9nYW1lJywnbWxiX3JwZyddXG5kYXRhX2F0dHJpYnV0ZXMgPSBkZlthdHRyaWJ1dGVzXSIsInNhbXBsZSI6IiMgSW1wb3J0IG5lY2Vzc2FyeSBtb2R1bGVzIGZyb20gYHNrbGVhcm5gIFxuZnJvbSBza2xlYXJuLmNsdXN0ZXIgaW1wb3J0IEtNZWFuc1xuZnJvbSBza2xlYXJuIGltcG9ydCBtZXRyaWNzXG5cbiMgQ3JlYXRlIHNpbGhvdWV0dGUgc2NvcmUgZGljdGlvbmFyeVxuc19zY29yZV9kaWN0ID0ge31cbmZvciBpIGluIHJhbmdlKDIsMTEpOlxuICAgIGttID0gS01lYW5zKG5fY2x1c3RlcnM9aSwgcmFuZG9tX3N0YXRlPTEpXG4gICAgbCA9IGttLmZpdF9wcmVkaWN0KGRhdGFfYXR0cmlidXRlcylcbiAgICBzX3MgPSBtZXRyaWNzLnNpbGhvdWV0dGVfc2NvcmUoZGF0YV9hdHRyaWJ1dGVzLCBsKVxuICAgIHNfc2NvcmVfZGljdFtpXSA9IFtzX3NdXG5cbiMgUHJpbnQgb3V0IGBzX3Njb3JlX2RpY3RgXG5wcmludChzX3Njb3JlX2RpY3QpIiwic29sdXRpb24iOiIjIEltcG9ydCBuZWNlc3NhcnkgbW9kdWxlcyBmcm9tIGBza2xlYXJuYCBcbmZyb20gc2tsZWFybi5jbHVzdGVyIGltcG9ydCBLTWVhbnNcbmZyb20gc2tsZWFybiBpbXBvcnQgbWV0cmljc1xuXG4jIENyZWF0ZSBzaWxob3VldHRlIHNjb3JlIGRpY3Rpb25hcnlcbnNfc2NvcmVfZGljdCA9IHt9XG5mb3IgaSBpbiByYW5nZSgyLDExKTpcbiAgICBrbSA9IEtNZWFucyhuX2NsdXN0ZXJzPWksIHJhbmRvbV9zdGF0ZT0xKVxuICAgIGwgPSBrbS5maXRfcHJlZGljdChkYXRhX2F0dHJpYnV0ZXMpXG4gICAgc19zID0gbWV0cmljcy5zaWxob3VldHRlX3Njb3JlKGRhdGFfYXR0cmlidXRlcywgbClcbiAgICBzX3Njb3JlX2RpY3RbaV0gPSBbc19zXVxuXG4jIFByaW50IG91dCBgc19zY29yZV9kaWN0YFxucHJpbnQoc19zY29yZV9kaWN0KSIsInNjdCI6IkV4KCkudGVzdF9pbXBvcnQoXCJza2xlYXJuLmNsdXN0ZXIuS01lYW5zXCIpXG5FeCgpLnRlc3RfaW1wb3J0KFwic2tsZWFybi5tZXRyaWNzXCIpXG5FeCgpLnRlc3Rfb2JqZWN0KFwic19zY29yZV9kaWN0XCIpXG4jIGZvciBsb29wIHRlc3RcbkV4KCkudGVzdF9mdW5jdGlvbihcInByaW50XCIpIn0=

Agora você pode inicializar o modelo. Defina 6 clusters e random state como 1. Calcule as distâncias euclidianas de cada ponto com fit_transform() e visualize os clusters com um scatter plot.

# Create K-means model and determine euclidian distances for each data pointkmeans_model = KMeans(n_clusters=6, random_state=1)distances = kmeans_model.fit_transform(data_attributes)# Create scatter plot using labels from K-means model as colorlabels = kmeans_model.labels_plt.scatter(distances[:,0], distances[:,1], c=labels)plt.title('Kmeans Clusters')plt.show()

clusters

Agora adicione os rótulos dos clusters ao conjunto como uma nova coluna. Também inclua a string “labels” na lista attributes para uso posterior.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZnJvbSBza2xlYXJuLmNsdXN0ZXIgaW1wb3J0IEtNZWFuc1xuZGZfdGVhbXMgPSBwZC5yZWFkXFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zX3dob2xlLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKVxuYXR0cmlidXRlcyA9IFsnRycsJ1InLCdBQicsJ0gnLCcyQicsJzNCJywnSFInLCdCQicsJ1NPJywnU0InLCdSQScsJ0VSJywnRVJBJywnQ0cnLFxuJ1NITycsJ1NWJywnSVBvdXRzJywnSEEnLCdIUkEnLCdCQkEnLCdTT0EnLCdFJywnRFAnLCdGUCcsJ2VyYV8xJywnZXJhXzInLCdlcmFfMycsJ2VyYV80JywnZXJhXzUnLCdlcmFfNicsJ2VyYV83JywnZXJhXzgnLCdkZWNhZGVfMTkxMCcsJ2RlY2FkZV8xOTIwJywnZGVjYWRlXzE5MzAnLCdkZWNhZGVfMTk0MCcsJ2RlY2FkZV8xOTUwJywnZGVjYWRlXzE5NjAnLCdkZWNhZGVfMTk3MCcsJ2RlY2FkZV8xOTgwJywnZGVjYWRlXzE5OTAnLCdkZWNhZGVfMjAwMCcsJ2RlY2FkZV8yMDEwJywnUl9wZXJfZ2FtZScsJ1JBX3Blcl9nYW1lJywnbWxiX3JwZyddXG5kYXRhX2F0dHJpYnV0ZXMgPSBkZlthdHRyaWJ1dGVzXVxua21lYW5zX21vZGVsID0gS01lYW5zKG5fY2x1c3RlcnM9NiwgcmFuZG9tX3N0YXRlPTEpXG5kaXN0YW5jZXMgPSBrbWVhbnNfbW9kZWwuZml0X3RyYW5zZm9ybShkYXRhX2F0dHJpYnV0ZXMpXG5sYWJlbHMgPSBrbWVhbnNfbW9kZWwubGFiZWxzXyIsInNhbXBsZSI6IiMgQWRkIGxhYmVscyBmcm9tIEstbWVhbnMgbW9kZWwgdG8gYGRmYCBEYXRhRnJhbWUgYW5kIGF0dHJpYnV0ZXMgbGlzdFxuZGZbJ2xhYmVscyddID0gbGFiZWxzXG5hdHRyaWJ1dGVzLmFwcGVuZCgnbGFiZWxzJylcblxuIyBQcmludCB0aGUgZmlyc3Qgcm93cyBvZiBgZGZgXG5wcmludChfX19fX19fX18pIiwic29sdXRpb24iOiIjIEFkZCBsYWJlbHMgZnJvbSBLLW1lYW5zIG1vZGVsIHRvIGBkZmAgRGF0YUZyYW1lIGFuZCBhdHRyaWJ1dGVzIGxpc3RcbmRmWydsYWJlbHMnXSA9IGxhYmVsc1xuYXR0cmlidXRlcy5hcHBlbmQoJ2xhYmVscycpXG5cbiMgUHJpbnQgdGhlIGZpcnN0IHJvd3Mgb2YgYGRmYFxucHJpbnQoZGYuaGVhZCgpKSIsInNjdCI6IkV4KCkudGVzdF9vYmplY3QoXCJkZlwiKVxuRXgoKS50ZXN0X29iamVjdChcImF0dHJpYnV0ZXNcIilcbkV4KCkudGVzdF9mdW5jdGlvbihcInByaW50XCIpIn0=

Antes de construir o modelo, separe os dados em treino e teste. Se você treinar e testar no mesmo conjunto, o modelo pode decorar os dados e superajustar, o que degrada o desempenho em dados novos.

Sem estresse: há várias formas de fazer cross-validation.

Aqui, vamos amostrar aleatoriamente 75% para train e usar os 25% restantes como test. Crie a lista numeric_cols com todas as colunas usadas no modelo. Depois, crie o DataFrame data a partir de df com essas colunas. Em seguida, gere os conjuntos train e test amostrando o DataFrame data.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZnJvbSBza2xlYXJuLmNsdXN0ZXIgaW1wb3J0IEtNZWFuc1xuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zX3dob2xlLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKVxuYXR0cmlidXRlcyA9IFsnRycsJ1InLCdBQicsJ0gnLCcyQicsJzNCJywnSFInLCdCQicsJ1NPJywnU0InLCdSQScsJ0VSJywnRVJBJywnQ0cnLFxuJ1NITycsJ1NWJywnSVBvdXRzJywnSEEnLCdIUkEnLCdCQkEnLCdTT0EnLCdFJywnRFAnLCdGUCcsJ2VyYV8xJywnZXJhXzInLCdlcmFfMycsJ2VyYV80JywnZXJhXzUnLCdlcmFfNicsJ2VyYV83JywnZXJhXzgnLCdkZWNhZGVfMTkxMCcsJ2RlY2FkZV8xOTIwJywnZGVjYWRlXzE5MzAnLCdkZWNhZGVfMTk0MCcsJ2RlY2FkZV8xOTUwJywnZGVjYWRlXzE5NjAnLCdkZWNhZGVfMTk3MCcsJ2RlY2FkZV8xOTgwJywnZGVjYWRlXzE5OTAnLCdkZWNhZGVfMjAwMCcsJ2RlY2FkZV8yMDEwJywnUl9wZXJfZ2FtZScsJ1JBX3Blcl9nYW1lJywnbWxiX3JwZyddXG5kYXRhX2F0dHJpYnV0ZXMgPSBkZlthdHRyaWJ1dGVzXVxua21lYW5zX21vZGVsID0gS01lYW5zKG5fY2x1c3RlcnM9NiwgcmFuZG9tX3N0YXRlPTEpXG5kaXN0YW5jZXMgPSBrbWVhbnNfbW9kZWwuZml0X3RyYW5zZm9ybShkYXRhX2F0dHJpYnV0ZXMpXG5sYWJlbHMgPSBrbWVhbnNfbW9kZWwubGFiZWxzX1xuZGZbJ2xhYmVscyddID0gbGFiZWxzXG5hdHRyaWJ1dGVzLmFwcGVuZCgnbGFiZWxzJykiLCJzYW1wbGUiOiIjIENyZWF0ZSBuZXcgRGF0YUZyYW1lIHVzaW5nIG9ubHkgdmFyaWFibGVzIHRvIGJlIGluY2x1ZGVkIGluIG1vZGVsc1xubnVtZXJpY19jb2xzID0gWydHJywnUicsJ0FCJywnSCcsJzJCJywnM0InLCdIUicsJ0JCJywnU08nLCdTQicsJ1JBJywnRVInLCdFUkEnLCdDRycsJ1NITycsJ1NWJywnSVBvdXRzJywnSEEnLCdIUkEnLCdCQkEnLCdTT0EnLCdFJywnRFAnLCdGUCcsJ2VyYV8xJywnZXJhXzInLCdlcmFfMycsJ2VyYV80JywnZXJhXzUnLCdlcmFfNicsJ2VyYV83JywnZXJhXzgnLCdkZWNhZGVfMTkxMCcsJ2RlY2FkZV8xOTIwJywnZGVjYWRlXzE5MzAnLCdkZWNhZGVfMTk0MCcsJ2RlY2FkZV8xOTUwJywnZGVjYWRlXzE5NjAnLCdkZWNhZGVfMTk3MCcsJ2RlY2FkZV8xOTgwJywnZGVjYWRlXzE5OTAnLCdkZWNhZGVfMjAwMCcsJ2RlY2FkZV8yMDEwJywnUl9wZXJfZ2FtZScsJ1JBX3Blcl9nYW1lJywnbWxiX3JwZycsJ2xhYmVscycsJ1cnXVxuZGF0YSA9IGRmW251bWVyaWNfY29sc11cbnByaW50KGRhdGEuaGVhZCgpKVxuXG4jIFNwbGl0IGRhdGEgRGF0YUZyYW1lIGludG8gdHJhaW4gYW5kIHRlc3Qgc2V0c1xudHJhaW4gPSBkYXRhLnNhbXBsZShmcmFjPTAuNzUsIHJhbmRvbV9zdGF0ZT0xKVxudGVzdCA9IGRhdGEubG9jW35kYXRhLmluZGV4LmlzaW4odHJhaW4uaW5kZXgpXVxuXG54X3RyYWluID0gdHJhaW5bYXR0cmlidXRlc11cbnlfdHJhaW4gPSB0cmFpblsnVyddXG54X3Rlc3QgPSB0ZXN0W2F0dHJpYnV0ZXNdXG55X3Rlc3QgPSB0ZXN0WydXJ10iLCJzb2x1dGlvbiI6IiMgQ3JlYXRlIG5ldyBEYXRhRnJhbWUgdXNpbmcgb25seSB2YXJpYWJsZXMgdG8gYmUgaW5jbHVkZWQgaW4gbW9kZWxzXG5udW1lcmljX2NvbHMgPSBbJ0cnLCdSJywnQUInLCdIJywnMkInLCczQicsJ0hSJywnQkInLCdTTycsJ1NCJywnUkEnLCdFUicsJ0VSQScsJ0NHJywnU0hPJywnU1YnLCdJUG91dHMnLCdIQScsJ0hSQScsJ0JCQScsJ1NPQScsJ0UnLCdEUCcsJ0ZQJywnZXJhXzEnLCdlcmFfMicsJ2VyYV8zJywnZXJhXzQnLCdlcmFfNScsJ2VyYV82JywnZXJhXzcnLCdlcmFfOCcsJ2RlY2FkZV8xOTEwJywnZGVjYWRlXzE5MjAnLCdkZWNhZGVfMTkzMCcsJ2RlY2FkZV8xOTQwJywnZGVjYWRlXzE5NTAnLCdkZWNhZGVfMTk2MCcsJ2RlY2FkZV8xOTcwJywnZGVjYWRlXzE5ODAnLCdkZWNhZGVfMTk5MCcsJ2RlY2FkZV8yMDAwJywnZGVjYWRlXzIwMTAnLCdSX3Blcl9nYW1lJywnUkFfcGVyX2dhbWUnLCdtbGJfcnBnJywnbGFiZWxzJywnVyddXG5kYXRhID0gZGZbbnVtZXJpY19jb2xzXVxucHJpbnQoZGF0YS5oZWFkKCkpXG5cbiMgU3BsaXQgZGF0YSBEYXRhRnJhbWUgaW50byB0cmFpbiBhbmQgdGVzdCBzZXRzXG50cmFpbiA9IGRhdGEuc2FtcGxlKGZyYWM9MC43NSwgcmFuZG9tX3N0YXRlPTEpXG50ZXN0ID0gZGF0YS5sb2NbfmRhdGEuaW5kZXguaXNpbih0cmFpbi5pbmRleCldXG5cbnhfdHJhaW4gPSB0cmFpblthdHRyaWJ1dGVzXVxueV90cmFpbiA9IHRyYWluWydXJ11cbnhfdGVzdCA9IHRlc3RbYXR0cmlidXRlc11cbnlfdGVzdCA9IHRlc3RbJ1cnXSIsInNjdCI6IkV4KCkudGVzdF9vYmplY3QoXCJudW1lcmljX2NvbHNcIilcbkV4KCkudGVzdF9vYmplY3QoXCJkYXRhXCIpXG5FeCgpLnRlc3RfZnVuY3Rpb24oXCJwcmludFwiKVxuRXgoKS50ZXN0X29iamVjdChcInRyYWluXCIpXG5FeCgpLnRlc3Rfb2JqZWN0KFwidGVzdFwiKVxuRXgoKS50ZXN0X29iamVjdChcInhfdHJhaW4gXCIpXG5FeCgpLnRlc3Rfb2JqZWN0KFwieV90cmFpblwiKVxuRXgoKS50ZXN0X29iamVjdChcInhfdGVzdFwiKVxuRXgoKS50ZXN0X29iamVjdChcInlfdGVzdFwiKSJ9

Escolhendo métrica de erro e modelo

A métrica que usaremos para avaliar o modelo é o Mean Absolute Error (MAE). Ela mede o quão próximas as previsões ficam dos resultados. Neste caso, indica o valor absoluto médio pelo qual sua previsão errou o alvo.

Ou seja, se em média suas previsões erram por 5 vitórias, sua métrica será 5.

O primeiro modelo será uma regressão linear. Você pode importar LinearRegression e mean_absolute_error de sklearn.linear_model e sklearn.metrics, respectivamente, criar o modelo lr, ajustar, prever e calcular o MAE.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZnJvbSBza2xlYXJuLmNsdXN0ZXIgaW1wb3J0IEtNZWFuc1xuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zX3dob2xlLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKVxuYXR0cmlidXRlcyA9IFsnRycsJ1InLCdBQicsJ0gnLCcyQicsJzNCJywnSFInLCdCQicsJ1NPJywnU0InLCdSQScsJ0VSJywnRVJBJywnQ0cnLFxuJ1NITycsJ1NWJywnSVBvdXRzJywnSEEnLCdIUkEnLCdCQkEnLCdTT0EnLCdFJywnRFAnLCdGUCcsJ2VyYV8xJywnZXJhXzInLCdlcmFfMycsJ2VyYV80JywnZXJhXzUnLCdlcmFfNicsJ2VyYV83JywnZXJhXzgnLCdkZWNhZGVfMTkxMCcsJ2RlY2FkZV8xOTIwJywnZGVjYWRlXzE5MzAnLCdkZWNhZGVfMTk0MCcsJ2RlY2FkZV8xOTUwJywnZGVjYWRlXzE5NjAnLCdkZWNhZGVfMTk3MCcsJ2RlY2FkZV8xOTgwJywnZGVjYWRlXzE5OTAnLCdkZWNhZGVfMjAwMCcsJ2RlY2FkZV8yMDEwJywnUl9wZXJfZ2FtZScsJ1JBX3Blcl9nYW1lJywnbWxiX3JwZyddXG5kYXRhX2F0dHJpYnV0ZXMgPSBkZlthdHRyaWJ1dGVzXVxua21lYW5zX21vZGVsID0gS01lYW5zKG5fY2x1c3RlcnM9NiwgcmFuZG9tX3N0YXRlPTEpXG5kaXN0YW5jZXMgPSBrbWVhbnNfbW9kZWwuZml0X3RyYW5zZm9ybShkYXRhX2F0dHJpYnV0ZXMpXG5sYWJlbHMgPSBrbWVhbnNfbW9kZWwubGFiZWxzX1xuZGZbJ2xhYmVscyddID0gbGFiZWxzXG5hdHRyaWJ1dGVzLmFwcGVuZCgnbGFiZWxzJylcbm51bWVyaWNfY29scyA9IFsnRycsJ1InLCdBQicsJ0gnLCcyQicsJzNCJywnSFInLCdCQicsJ1NPJywnU0InLCdSQScsJ0VSJywnRVJBJywnQ0cnLCdTSE8nLCdTVicsJ0lQb3V0cycsJ0hBJywnSFJBJywnQkJBJywnU09BJywnRScsJ0RQJywnRlAnLCdlcmFfMScsJ2VyYV8yJywnZXJhXzMnLCdlcmFfNCcsJ2VyYV81JywnZXJhXzYnLCdlcmFfNycsJ2VyYV84JywnZGVjYWRlXzE5MTAnLCdkZWNhZGVfMTkyMCcsJ2RlY2FkZV8xOTMwJywnZGVjYWRlXzE5NDAnLCdkZWNhZGVfMTk1MCcsJ2RlY2FkZV8xOTYwJywnZGVjYWRlXzE5NzAnLCdkZWNhZGVfMTk4MCcsJ2RlY2FkZV8xOTkwJywnZGVjYWRlXzIwMDAnLCdkZWNhZGVfMjAxMCcsJ1JfcGVyX2dhbWUnLCdSQV9wZXJfZ2FtZScsJ21sYl9ycGcnLCdsYWJlbHMnLCdXJ11cbmRhdGEgPSBkZltudW1lcmljX2NvbHNdXG50cmFpbiA9IGRhdGEuc2FtcGxlKGZyYWM9MC43NSwgcmFuZG9tX3N0YXRlPTEpXG50ZXN0ID0gZGF0YS5sb2NbfmRhdGEuaW5kZXguaXNpbih0cmFpbi5pbmRleCldXG54X3RyYWluID0gdHJhaW5bYXR0cmlidXRlc11cbnlfdHJhaW4gPSB0cmFpblsnVyddXG54X3Rlc3QgPSB0ZXN0W2F0dHJpYnV0ZXNdXG55X3Rlc3QgPSB0ZXN0WydXJ10iLCJzYW1wbGUiOiIjIEltcG9ydCBgTGluZWFyUmVncmVzc2lvbmAgZnJvbSBgc2tsZWFybi5saW5lYXJfbW9kZWxgXG5mcm9tIHNrbGVhcm4ubGluZWFyX21vZGVsIGltcG9ydCBfX19fX19fX19fX19fX19fX19fXG5cbiMgSW1wb3J0IGBtZWFuX2Fic29sdXRlX2Vycm9yYCBmcm9tIGBza2xlYXJuLm1ldHJpY3NgXG5mcm9tIHNrbGVhcm4ubWV0cmljcyBpbXBvcnQgbWVhbl9hYnNvbHV0ZV9lcnJvclxuXG4jIENyZWF0ZSBMaW5lYXIgUmVncmVzc2lvbiBtb2RlbCwgZml0IG1vZGVsLCBhbmQgbWFrZSBwcmVkaWN0aW9uc1xubHIgPSBMaW5lYXJSZWdyZXNzaW9uKG5vcm1hbGl6ZT1UcnVlKVxubHIuZml0KHhfdHJhaW4sIHlfdHJhaW4pXG5wcmVkaWN0aW9ucyA9IGxyLnByZWRpY3QoeF90ZXN0KVxuXG4jIERldGVybWluZSBtZWFuIGFic29sdXRlIGVycm9yXG5tYWUgPSBtZWFuX2Fic29sdXRlX2Vycm9yKHlfdGVzdCwgcHJlZGljdGlvbnMpXG5cbiMgUHJpbnQgYG1hZWBcbnByaW50KF9fXykiLCJzb2x1dGlvbiI6IiMgSW1wb3J0IGBMaW5lYXJSZWdyZXNzaW9uYCBmcm9tIGBza2xlYXJuLmxpbmVhcl9tb2RlbGBcbmZyb20gc2tsZWFybi5saW5lYXJfbW9kZWwgaW1wb3J0IExpbmVhclJlZ3Jlc3Npb25cblxuIyBJbXBvcnQgYG1lYW5fYWJzb2x1dGVfZXJyb3JgIGZyb20gYHNrbGVhcm4ubWV0cmljc2BcbmZyb20gc2tsZWFybi5tZXRyaWNzIGltcG9ydCBtZWFuX2Fic29sdXRlX2Vycm9yXG5cbiMgQ3JlYXRlIExpbmVhciBSZWdyZXNzaW9uIG1vZGVsLCBmaXQgbW9kZWwsIGFuZCBtYWtlIHByZWRpY3Rpb25zXG5sciA9IExpbmVhclJlZ3Jlc3Npb25ob3JtYWxpemU9VHJ1ZSlcbnByZWRpY3Rpb25zID0gbHIucHJlZGljdCh4X3Rlc3QpXG5cbiMgRGV0ZXJtaW5lIG1lYW4gYWJzb2x1dGUgZXJyb3Jcbm1hZSA9IG1lYW5fYWJzb2x1dGVfZXJyb3IoeV90ZXN0LCBwcmVkaWN0aW9ucylcblxuIyBQcmludCBgbWFlYFxucHJpbnQobWFlKSIsInNjdCI6IkV4KCkudGVzdF9pbXBvcnQoXCJza2xlYXJuLmxpbmVhcl9tb2RlbC5MaW5lYXJSZWdyZXNzaW9uXCIpXG5FeCgpLnRlc3RfaW1wb3J0KFwic2tsZWFybi5tZXRyaWNzLm1lYW5fYWJzb2x1dGVfZXJyb3JcIilcbkV4KCkudGVzdF9mdW5jdGlvbihcImxyLmZpdFwiKVxuRXgoKS50ZXN0X29iamVjdChcInByZWRpY3Rpb25zXCIpXG5FeCgpLnRlc3Rfb2JqZWN0KFwibWFlXCIpXG5FeCgpLnRlc3RfZnVuY3Rpb24oXCJwcmludFwiKSJ9

Se você recall from above, the average number of wins was about 79 wins. On average, the model is off by only 2.687 wins.

Now try a Ridge regression model. Import RidgeCV from sklearn.linear_model and create model rrm. The RidgeCV model allows you to set the alpha parameter, which is a complexity parameter that controls the amount of shrinkage (read more here). The model will use cross-validation to deterime which of the alpha parameters you provide is ideal.

Again, fit your model, make predictions and determine the mean absolute error.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZnJvbSBza2xlYXJuLmNsdXN0ZXIgaW1wb3J0IEtNZWFuc1xuZnJvbSBza2xlYXJuLm1ldHJpY3MgaW1wb3J0IG1lYW5fYWJzb2x1dGVfZXJyb3JcbmRmX3RlYW1zID0gcGQucmVhZF9jc3YoXCJodHRwczovL3MzLmFtYXpvbmF3cy5jb20vYXNzZXRzLmRhdGFjYW1wLmNvbS9ibG9nX2Fzc2V0cy9kZl90ZWFtc193aG9sZS5jc3ZcIiwgaGVhZGVyPTApXG5kZiA9IHBkLkRhdGFGcmFtZShkZl90ZWFtcylcbmF0dHJpYnV0ZXMgPSBbJ0cnLCdSJywnQUInLCdIJywnMkInLCczQicsJ0hSJywnQkInLCdTTycsJ1NCJywnUkEnLCdFUicsJ0VSQScsJ0NHJyxcbidTSE8nLCdTVicsJ0lQb3V0cycsJ0hBJywnSFJBJywnQkJBJywnU09BJywnRScsJ0RQJywnRlAnLCdlcmFfMScsJ2VyYV8yJywnZXJhXzMnLCdlcmFfNCcsJ2VyYV81JywnZXJhXzYnLCdlcmFfNycsJ2VyYV84JywnZGVjYWRlXzE5MTAnLCdkZWNhZGVfMTkyMCcsJ2RlY2FkZV8xOTMwJywnZGVjYWRlXzE5NDAnLCdkZWNhZGVfMTk1MCcsJ2RlY2FkZV8xOTYwJywnZGVjYWRlXzE5NzAnLCdkZWNhZGVfMTk4MCcsJ2RlY2FkZV8xOTkwJywnZGVjYWRlXzIwMDAnLCdkZWNhZGVfMjAxMCcsJ1JfcGVyX2dhbWUnLCdSQV9wZXJfZ2FtZScsJ21sYl9ycGcnXVxuZGF0YV9hdHRyaWJ1dGVzID0gZGZbYXR0cmlidXRlc11cbmttZWFuc19tb2RlbCA9IEtNZWFucyhuX2NsdXN0ZXJzPTYsIHJhbmRvbV9zdGF0ZT0xKVxuZGlzdGFuY2VzID0ga21lYW5zX21vZGVsLmZpdF90cmFuc2Zvcm0oZGF0YV9hdHRyaWJ1dGVzKVxubGFiZWxzID0ga21lYW5zX21vZGVsLmxhYmVsc19cbmRmWydsYWJlbHMnXSA9IGxhYmVsc1xuYXR0cmlidXRlcy5hcHBlbmQoJ2xhYmVscycpXG5udW1lcmljX2NvbHMgPSBbJ0cnLCdSJywnQUInLCdIJywnMkInLCczQicsJ0hSJywnQkInLCdTTycsJ1NCJywnUkEnLCdFUicsJ0VSQScsJ0NHJywnU0hPJywnU1YnLCdJUG91dHMnLCdIQScsJ0hSQScsJ0JCQScsJ1NPQScsJ0UnLCdEUCcsJ0ZQJywnZXJhXzEnLCdlcmFfMicsJ2VyYV8zJywnZXJhXzQnLCdlcmFfNScsJ2VyYV82JywnZXJhXzcnLCdlcmFfOCcsJ2RlY2FkZV8xOTEwJywnZGVjYWRlXzE5MjAnLCdkZWNhZGVfMTkzMCcsJ2RlY2FkZV8xOTQwJywnZGVjYWRlXzE5NTAnLCdkZWNhZGVfMTk2MCcsJ2RlY2FkZV8xOTcwJywnZGVjYWRlXzE5ODAnLCdkZWNhZGVfMTk5MCcsJ2RlY2FkZV8yMDAwJywnZGVjYWRlXzIwMTAnLCdSX3Blcl9nYW1lJywnUkFfcGVyX2dhbWUnLCdtbGJfcnBnJywnbGFiZWxzJywnVyddXG5kYXRhID0gZGZbbnVtZXJpY19jb2xzXVxudHJhaW4gPSBkYXRhLnNhbXBsZShmcmFjPTAuNzUsIHJhbmRvbV9zdGF0ZT0xKVxudGVzdCA9IGRhdGEubG9jW35kYXRhLmluZGV4LmlzaW4odHJhaW4uaW5kZXgpXVxueF90cmFpbiA9IHRyYWluW2F0dHJpYnV0ZXNdXG55X3RyYWluID0gdHJhaW5bJ1cnXVxueF90ZXN0ID0gdGVzdFthdHRyaWJ1dGVzXVxueV90ZXN0ID0gdGVzdFsnVyddIiwic2FtcGxlIjoiIyBJbXBvcnQgYFJpZGdlQ1ZgIGZyb20gYHNrbGVhcm4ubGluZWFyX21vZGVsYFxuZnJvbSBza2xlYXJuLmxpbmVhcl9tb2RlbCBpbXBvcnQgX19fX19fX1xuXG4jIENyZWF0ZSBSaWRnZSBMaW5lYXIgUmVncmVzc2lvbiBtb2RlbCwgZml0IG1vZGVsLCBhbmQgbWFrZSBwcmVkaWN0aW9uc1xucnJtID0gUmlkZ2VDVihhbHBoYXM9KDAuMDEsIDAuMSwgMS4wLCAxMC4wKSwgbm9ybWFsaXplPVRydWUpXG5ycm0uZml0KHhfdHJhaW4sIHlfdHJhaW4pXG5wcmVkaWN0aW9uc19ycm0gPSBycm0ucHJlZGljdCh4X3Rlc3QpXG5cbiMgRGV0ZXJtaW5lIG1lYW4gYWJzb2x1dGUgZXJyb3Jcbm1hZV9ycm0gPSBtZWFuX2Fic29sdXRlX2Vycm9yKHlfdGVzdCwgcHJlZGljdGlvbnNfcnJtKVxucHJpbnQoX19fX19fX18pIiwic29sdXRpb24iOiIjIEltcG9ydCBgUmlkZ2VDVmAgZnJvbSBgc2tsZWFybi5saW5lYXJfbW9kZWxgXG5mcm9tIHNrbGVhcm4ubGluZWFyX21vZGVsIGltcG9ydCBSaWRnZUNWXG5cbiMgQ3JlYXRlIFJpZGdlIExpbmVhciBSZWdyZXNzaW9uIG1vZGVsLCBmaXQgbW9kZWwsIGFuZCBtYWtlIHByZWRpY3Rpb25zXG5ycm0gPSBSaWRnZUNWKGFscGhhcz0oMC4wMSwgMC4xLCAxLjAsIDEwLjApLCBub3JtYWxpemU9VHJ1ZSlcbnJybS5maXQoeF90cmFpbiwgeV90cmFpbilcbnByZWRpY3Rpb25zX3JybSA9IHJybS5wcmVkaWN0KHhfdGVzdClcblxuIyBEZXRlcm1pbmUgbWVhbiBhYnNvbHV0ZSBlcnJvclxubWFlX3JybSA9IG1lYW5fYWJzb2x1dGVfZXJyb3IoeV90ZXN0LCBwcmVkaWN0aW9uc19ycm0pXG5wcmludChtYWVfcnJtKSIsInNjdCI6IkV4KCkudGVzdF9pbXBvcnQoXCJza2xlYXJuLmxpbmVhcl9tb2RlbC5SaWRnZUNWXCIpXG5FeCgpLnRlc3RfZnVuY3Rpb24oXCJycm0uZml0XCIpXG5FeCgpLnRlc3Rfb2JqZWN0KFwicHJlZGljdGlvbnNfcnJtXCIpXG5FeCgpLnRlc3RfZnVuY3Rpb24oXCJwcmludFwiKSJ9

This model performed slightly better, and is off by 2.673 wins, on average.

Sports Analytics & Scikit-Learn

This concludes the first part of this tutorial series in which you have seen how you can use scikit-Learn to analyze sports data. You imported the data from an SQLite database, cleaned it up, explored aspects of it visually, and engineered several new features. You learned how to create a K-means clustering model, a couple different Linear Regression models, and how to test your predictions with the mean absolute error metric.

In the second part, you’ll see how to use classification models to predict which players make it into the MLB Hall of Fame.

Tópicos
Python
Ciência de dados
Aprendizado de máquina

Python Courses

Curso

Introdução ao Python

4 h
7M
Domine os fundamentos da análise de dados com Python em quatro horas e explore pacotes populares.
Ver detalhesRight Arrow
Iniciar Curso
Ver maisRight Arrow