Ir al contenido principal

Tutorial de Scikit-Learn: analítica de béisbol (parte 1)

Un tutorial de scikit-learn para predecir las victorias por temporada en la MLB modelando los datos con KMeans y modelos de regresión lineal.
Actualizado 17 sept 2026  · 14 min leer

Explorar con IA

ChatGPTClaudePerplexity

El lenguaje de programación Python es una gran opción para ciencia de datos y analítica predictiva, ya que cuenta con múltiples paquetes que cubren la mayoría de tus necesidades de análisis. Para machine learning en Python, Scikit-learn (sklearn) es una excelente alternativa y se basa en NumPy, SciPy y Matplotlib (arrays N-dimensionales, computación científica y visualización de datos, respectivamente).

En este tutorial verás cómo cargar datos fácilmente desde una base de datos con sqlite3, cómo explorar y mejorar la calidad de tus datos con pandas y matplotlib, y cómo usar después Scikit-Learn para extraer conclusiones útiles de tu dataset.

Si quieres hacer un curso de machine learning, echa un vistazo al curso Supervised Learning with scikit-learn de DataCamp.

Parte 1: predecir las victorias por temporada de los equipos MLB

En este proyecto probarás varios modelos de machine learning de sklearn para predecir el número de partidos que gana en una temporada un equipo de Major League Baseball, a partir de sus estadísticas y otras variables de ese año. Si fuera un jugador (y lo soy), podría crear un modelo con datos históricos de temporadas previas para pronosticar la siguiente. Dada la naturaleza de series temporales de los datos, podrías generar indicadores como la media de victorias por año en los últimos cinco años, entre otros factores, para construir un modelo muy preciso. Sin embargo, eso queda fuera de este tutorial y trataremos cada fila como independiente. Cada fila del dataset corresponde a un equipo en un año concreto.

Sean Lahman recopiló estos datos en su web y aquí se transformaron a una base de datos sqlite.

Importar datos

Leerás los datos consultando una base de datos sqlite con el paquete sqlite3 y convirtiéndolos en un DataFrame con pandas. Filtrarás los datos para incluir solo equipos modernos activos y temporadas con 150 o más partidos jugados.

Primero, descarga el archivo "lahman2016.sqlite" (aquí). Luego, carga Pandas y asígnale el alias pd por comodidad. Quizá recuerdes que pd es el alias habitual de Pandas. Por último, carga sqlite3 y conecta con la base de datos así:

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

A continuación, escribe una consulta, ejecútala y recupera los 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()

Consejo: si quieres aprender más sobre cómo usar SQL con Python, plantéate hacer el curso Introduction to Databases in Python de DataCamp.

Con pandas, convierte los resultados en un DataFrame e imprime las 5 primeras filas con el método head():

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuVGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL3RlYW1zX2RmLmNzdlwiKSIsInNhbXBsZSI6IiMgQ29udmVydCBgVGVhbXNgIHRvIERhdGFGcmFtZVxudGVhbXNfZGYgPSBwZC5EYXRhRnJhbWUoX19fX18pXG5cbiMgUHJpbnQgb3V0IGZpcnN0IDUgcm93c1xucHJpbnQoX19fX19fX19fX19fX19fKSIsInNvbHV0aW9uIjoiIyBDb252ZXJ0IHJlc3VsdHMgdG8gRGF0YUZyYW1lXG50ZWFtc19kZiA9IHBkLkRhdGFGcmFtZShUZWFtcylcblxuIyBQcmludCBvdXQgZmlyc3QgNSByb3dzXG5wcmludCh0ZWFtc19kZi5oZWFkKCkpIiwic2N0IjoiRXgoKS50ZXN0X29iamVjdChcInRlYW1zX2RmXCIpXG5FeCgpLnRlc3RfZnVuY3Rpb24oXCJwcmludFwiKSJ9

Cada columna contiene datos de un equipo y un año específicos. A continuación verás algunas de las variables más importantes. Puedes consultar la lista completa de variables aquí.

  • yearID - Año
  • teamID - Equipo
  • franchID - Franquicia (enlaza con la tabla TeamsFranchise)
  • G - Partidos jugados
  • W - Victorias
  • LgWin - Campeón de liga (Y o N)
  • WSWin - Ganador de la World Series (Y o N)
  • R - Carreras anotadas
  • AB - Turnos de bateo
  • H - Hits de los bateadores
  • HR - Home runs de los bateadores
  • BB - Bases por bolas de los bateadores
  • SO - Strikeouts de los bateadores
  • SB - Bases robadas
  • CS - Cazado robando
  • HBP - Golpeados por lanzamiento
  • SF - Flies de sacrificio
  • RA - Carreras permitidas al rival
  • ER - Carreras limpias permitidas
  • ERA - Promedio de carreras limpias
  • CG - Partidos completos
  • SHO - Blanqueadas
  • SV - Salvamentos
  • IPOuts - Outs lanzados (innings lanzados x 3)
  • HA - Hits permitidos
  • HRA - Home runs permitidos
  • BBA - Bases por bolas permitidas
  • SOA - Strikeouts de los lanzadores
  • E - Errores
  • DP - Dobles matanzas
  • FP - Porcentaje de fildeo
  • name - Nombre completo del equipo

Si no estás familiarizado con el béisbol, aquí tienes una explicación rápida de cómo funciona el juego, incluyendo algunas de las variables anteriores.

El béisbol se juega entre dos equipos (que identificarás en los datos por name o teamID) de nueve jugadores. Los equipos se turnan para batear y defender. El equipo al bate intenta anotar carreras golpeando la pelota que lanza el pitcher del equipo a la defensiva y corriendo en sentido antihorario por cuatro bases: primera, segunda, tercera y home. El equipo a la defensiva intenta evitar carreras eliminando a bateadores o corredores de varias formas, y se anota una carrera (R) cuando un jugador recorre todas las bases y vuelve al home. Un bateador que llega a salvo a base intentará avanzar en turnos posteriores de sus compañeros, ya sea con un hit (H), una base robada (SB) u otros medios.

baseball

Los equipos cambian entre bateo y defensa cada vez que el equipo defensor consigue tres outs. Un turno de bateo para ambos equipos, empezando por el visitante, constituye una entrada (inning). Un partido tiene nueve entradas, y gana el que más carreras tiene al final. El béisbol no tiene reloj; aunque la mayoría de partidos acaban en la novena entrada, si hay empate se juegan entradas extra hasta que un equipo acabe una entrada con ventaja.

Para una explicación detallada del juego, consulta el reglamento oficial de las Major Leagues.

Limpiar y preparar los datos

Como ves arriba, el DataFrame no tiene cabeceras de columna. Puedes añadirlas pasando una lista con tus nombres al atributo columns de pandas.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxudGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL3RlYW1zX2RmLmNzdlwiKVxudGVhbXNfZGYgPSBwZC5EYXRhRnJhbWUodGVhbXMpIiwic2FtcGxlIjoiIyBBZGRpbmcgY29sdW1uIG5hbWVzIHRvIGRhdGFmcmFtZVxuY29scyA9IFsneWVhcklEJywnbGdJRCcsJ3RlYW1JRCcsJ2ZyYW5jaElEJywnZGl2SUQnLCdSYW5rJywnRycsJ0dob21lJywnVycsJ0wnLCdEaXZXaW4nLCdXQ1dpbicsJ0xnV2luJywnV1NXaW4nLCdSJywnQUInLCdIJywnMkInLCczQicsJ0hSJywnQkInLCdTTycsJ1NCJywnQ1MnLCdIQlAnLCdTRicsJ1JBJywnRVInLCdFUkEnLCdDRycsJ1NITycsJ1NWJywnSVBvdXRzJywnSEEnLCdIUkEnLCdCQkEnLCdTT0EnLCdFJywnRFAnLCdGUCcsJ25hbWUnLCdwYXJrJywnYXR0ZW5kYW5jZScsJ0JQRicsJ1BQRicsJ3RlYW1JREJSJywndGVhbUlEbGFobWFuNDUnLCd0ZWFtSURyZXRybycsJ2ZyYW5jaElEJywnZnJhbmNoTmFtZScsJ2FjdGl2ZScsJ05BYXNzb2MnXVxudGVhbXNfZGYuY29sdW1ucyA9IF9fX19cblxuIyBQcmludCB0aGUgZmlyc3Qgcm93cyBvZiBgdGVhbXNfZGZgXG5wcmludChfX19fX19fX19fX19fXylcblxuIyBQcmludCB0aGUgbGVuZ3RoIG9mIGB0ZWFtc19kZmBcbnByaW50KGxlbihfX19fX19fXykpIiwic29sdXRpb24iOiIjIEFkZGluZyBjb2x1bW4gbmFtZXMgdG8gZGF0YWZyYW1lXG5jb2xzID0gWyd5ZWFySUQnLCdsZ0lEJywndGVhbUlEJywnZnJhbmNoSUQnLCdkaXZJRCcsJ1JhbmsnLCdHJywnR2hvbWUnLCdXJywnTCcsJ0RpdldpbicsJ1dDV2luJywnTGdXaW4nLCdXU1dpbicsJ1InLCdBQicsJ0gnLCcyQicsJzNCJywnSFInLCdCQicsJ1NPJywnU0InLCdDUycsJ0hCUCcsJ1NGJywnUkEnLCdFUicsJ0VSQScsJ0NHJywnU0hPJywnU1YnLCdJUG91dHMnLCdIQScsJ0hSQScsJ0JCQScsJ1NPQScsJ0UnLCdEUCcsJ0ZQJywnbmFtZScsJ3BhcmsnLCdhdHRlbmRhbmNlJywnQlBGJywnUFBGJywndGVhbUlEQlInLCd0ZWFtSURsYWhtYW40NScsJ3RlYW1JRHJldHJvJywnZnJhbmNoSUQnLCdmcmFuY2hOYW1lJywnYWN0aXZlJywnTkFhc3NvYyddXG50ZWFtc19kZi5jb2x1bW5zID0gY29sc1xuXG4jIFByaW50IHRoZSBmaXJzdCByb3dzIG9mIGB0ZWFtc19kZmBcbnByaW50KHRlYW1zX2RmLmhlYWQoKSlcblxuIyBQcmludCB0aGUgbGVuZ3RoIG9mIGB0ZWFtc19kZmBcbnByaW50KGxlbih0ZWFtc19kZikpIiwic2N0IjoiRXgoKS5jaGVja19vYmplY3QoXCJjb2xzXCIpLmlzX2luc3RhbmNlKGxpc3QpXG5FeCgpLnRlc3RfZGF0YV9mcmFtZShcInRlYW1zX2RmXCIsIGNvbHVtbnM9Wyd5ZWFySUQnLCdsZ0lEJywndGVhbUlEJywnZnJhbmNoSUQnLCdkaXZJRCcsJ1JhbmsnLCdHJywnR2hvbWUnLCdXJywnTCcsJ0RpdldpbicsJ1dDV2luJywnTGdXaW4nLCdXU1dpbicsJ1InLCdBQicsJ0gnLCcyQicsJzNCJywnSFInLCdCQicsJ1NPJywnU0InLCdDUycsJ0hCUCcsJ1NGJywnUkEnLCdFUicsJ0VSQScsJ0NHJywnU0hPJywnU1YnLCdJUG91dHMnLCdIQScsJ0hSQScsJ0JCQScsJ1NPQScsJ0UnLCdEUCcsJ0ZQJywnbmFtZScsJ3BhcmsnLCdhdHRlbmRhbmNlJywnQlBGJywnUFBGJywndGVhbUlEQlInLCd0ZWFtSURsYWhtYW40NScsJ3RlYW1JRHJldHJvJywnZnJhbmNoSUQnLCdmcmFuY2hOYW1lJywnYWN0aXZlJywnTkFhc3NvYyddLCB1bmRlZmluZWRfY29sc19tc2c9XCJEaWQgeW91IGFzc2lnbiBgY29sc2AgdG8gYHRlYW1zX2RmLmNvbHVtbnNgP1wiKVxuRXgoKS50ZXN0X2Z1bmN0aW9uKFwidGVhbXNfZGYuaGVhZFwiLCBub3RfY2FsbGVkX21zZz1cIkRpZCB5b3UgcHJpbnQgb3V0IGB0ZWFtc19kZi5oZWFkKClgP1wiKVxuRXgoKS5jaGVja19mdW5jdGlvbihcInByaW50XCIsIGluZGV4PTApXG5FeCgpLnRlc3RfZnVuY3Rpb24oXCJsZW5cIilcbkV4KCkudGVzdF9mdW5jdGlvbihcInByaW50XCIsIGluZGV4PTEpIn0=

La función len() te dirá cuántas filas tienes: 2.287 no es un número enorme, así que esperemos que no haya demasiados nulos.

Antes de evaluar la calidad de los datos, eliminemos primero las columnas innecesarias o derivadas de la variable objetivo (Wins). Aquí es donde el conocimiento del dominio empieza a ser clave: de poco sirve saber mucho de código o estadística si no conoces los datos con los que trabajas. Ser fan del béisbol de toda la vida me ayudó mucho en este proyecto.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZCBcbnRlYW1zID0gcGQucmVhZF9jc3YoXCJodHRwczovL3MzLmFtYXpvbmF3cy5jb20vYXNzZXRzLmRhdGFjYW1wLmNvbS9ibG9nX2Fzc2V0cy90ZWFtc19kZi5jc3ZcIikgXG50ZWFtc19kZiA9IHBkLkRhdGFGcmFtZSh0ZWFtcylcbmNvbHMgPSBbJ3llYXJJRCcsJ2xnSUQnLCd0ZWFtSUQnLCdmcmFuY2hJRCcsJ2RpdklEJywnUmFuaycsJ0cnLCdHaG9tZScsJ1cnLFxuJ0wnLCdEaXZXaW4nLCdXQ1dpbicsJ0xnV2luJywnV1NXaW4nLCdSJywnQUInLCdIJywnMkInLCczQicsJ0hSJywnQkInLCdTTycsJ1NCJyxcbidDUycsJ0hCUCcsJ1NGJywnUkEnLCdFUicsJ0VSQScsJ0NHJywnU0hPJywnU1YnLCdJUG91dHMnLCdIQScsJ0hSQScsJ0JCQScsXG4nU09BJywnRScsJ0RQJywnRlAnLCduYW1lJywncGFyaycsJ2F0dGVuZGFuY2UnLCdCUEYnLCdQUEYnLCd0ZWFtSURCUicsJ3RlYW1JRGxhaG1hbjQ1JywndGVhbUlEcmV0cm8nLCdmcmFuY2hJRCcsJ2ZyYW5jaE5hbWUnLCdhY3RpdmUnLCdOQWFzc29jJ11cbnRlYW1zX2RmLmNvbHVtbnMgPSBjb2xzIiwic2FtcGxlIjoiIyBEcm9wcGluZyB5b3VyIHVubmVjZXNhcnkgY29sdW1uIHZhcmlhYmxlcy5cbmRyb3BfY29scyA9IFsnbGdJRCcsJ2ZyYW5jaElEJywnZGl2SUQnLCdSYW5rJywnR2hvbWUnLCdMJywnRGl2V2luJywnV0NXaW4nLCdMZ1dpbicsJ1dTV2luJywnU0YnLCduYW1lJywncGFyaycsJ2F0dGVuZGFuY2UnLCdCUEYnLCdQUEYnLCd0ZWFtSURCUicsJ3RlYW1JRGxhaG1hbjQ1JywndGVhbUlEcmV0cm8nLCdmcmFuY2hJRCcsJ2ZyYW5jaE5hbWUnLCdhY3RpdmUnLCdOQWFzc29jJ11cblxuZGYgPSB0ZWFtc19kZi5kcm9wKGRyb3BfY29scywgYXhpcz0xKVxuXG4jIFByaW50IG91dCBmaXJzdCByb3dzIG9mIGBkZmBcbnByaW50KF9fX19fX19fXykiLCJzb2x1dGlvbiI6IiMgRHJvcHBpbmcgeW91ciB1bm5lY2VzYXJ5IGNvbHVtbiB2YXJpYWJsZXMuXG5kcm9wX2NvbHMgPSBbJ2xnSUQnLCdmcmFuY2hJRCcsJ2RpdklEJywnUmFuaycsJ0dob21lJywnTCcsJ0RpdldpbicsJ1dDV2luJywnTGdXaW4nLCdXU1dpbicsJ1NGJywnbmFtZScsJ3BhcmsnLCdhdHRlbmRhbmNlJywnQlBGJywnUFBGJywndGVhbUlEQlInLCd0ZWFtSURsYWhtYW40NScsJ3RlYW1JRHJldHJvJywnZnJhbmNoSUQnLCdmcmFuY2hOYW1lJywnYWN0aXZlJywnTkFhc3NvYyddXG5cbmRmID0gdGVhbXNfZGYuZHJvcChkcm9wX2NvbHMsIGF4aXM9MSlcblxuIyBQcmludCBvdXQgZmlyc3Qgcm93cyBvZiBgZGZgXG5wcmludChkZi5oZWFkKCkpIiwic2N0IjoiRXgoKS50ZXN0X29iamVjdChcImRyb3BfY29sc1wiKVxuRXgoKS50ZXN0X29iamVjdChcImRmXCIpXG5FeCgpLnRlc3RfZnVuY3Rpb24oXCJwcmludFwiKSJ9

Como has leído, los valores nulos afectan a la calidad de los datos y pueden causar problemas a los algoritmos de machine learning.

Por eso, lo siguiente será tratarlos. Hay varias formas de eliminar nulos, pero es mejor empezar mostrando el recuento de nulos por columna para decidir cómo gestionarlos.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZCBcbnRlYW1zID0gcGQucmVhZF9jc3YoXCJodHRwczovL3MzLmFtYXpvbmF3cy5jb20vYXNzZXRzLmRhdGFjYW1wLmNvbS9ibG9nX2Fzc2V0cy90ZWFtc19kZi5jc3ZcIikgXG50ZWFtc19kZiA9IHBkLkRhdGFGcmFtZSh0ZWFtcylcbmNvbHMgPSBbJ3llYXJJRCcsJ2xnSUQnLCd0ZWFtSUQnLCdmcmFuY2hJRCcsJ2RpdklEJywnUmFuaycsJ0cnLCdHaG9tZScsJ1cnLFxuJ0wnLCdEaXZXaW4nLCdXQ1dpbicsJ0xnV2luJywnV1NXaW4nLCdSJywnQUInLCdIJywnMkInLCczQicsJ0hSJywnQkInLCdTTycsJ1NCJyxcbidDUycsJ0hCUCcsJ1NGJywnUkEnLCdFUicsJ0VSQScsJ0NHJywnU0hPJywnU1YnLCdJUG91dHMnLCdIQScsJ0hSQScsJ0JCQScsXG4nU09BJywnRScsJ0RQJywnRlAnLCduYW1lJywncGFyaycsJ2F0dGVuZGFuY2UnLCdCUEYnLCdQUEYnLCd0ZWFtSURCUicsJ3RlYW1JRGxhaG1hbjQ1JywndGVhbUlEcmV0cm8nLCdmcmFuY2hJRCcsJ2ZyYW5jaE5hbWUnLCdhY3RpdmUnLCdOQWFzc29jJ11cbnRlYW1zX2RmLmNvbHVtbnMgPSBjb2xzXG5kcm9wX2NvbHMgPSBbJ2xnSUQnLCdmcmFuY2hJRCcsJ2RpdklEJywnUmFuaycsJ0dob21lJywnTCcsJ0RpdldpbicsJ1dDV2luJywnTGdXaW4nLCdXU1dpbicsJ1NGJywnbmFtZScsJ3BhcmsnLCdhdHRlbmRhbmNlJywnQlBGJywnUFBGJywndGVhbUlEQlInLCd0ZWFtSURsYWhtYW40NScsJ3RlYW1JRHJldHJvJywnZnJhbmNoSUQnLCdmcmFuY2hOYW1lJywnYWN0aXZlJywnTkFhc3NvYyddXG5kZiA9IHRlYW1zX2RmLmRyb3AoZHJvcF9jb2xzLCBheGlzPTEpIiwic2FtcGxlIjoiIyBQcmludCBvdXQgbnVsbCB2YWx1ZXMgb2YgYWxsIGNvbHVtbnMgb2YgYGRmYFxucHJpbnQoX19fX19fX19fLnN1bShheGlzPTApLnRvbGlzdCgpKSIsInNvbHV0aW9uIjoiIyBQcmludCBvdXQgbnVsbCB2YWx1ZXMgb2YgYWxsIGNvbHVtbnMgb2YgYGRmYFxucHJpbnQoZGYuaXNudWxsKCkuc3VtKGF4aXM9MCkudG9saXN0KCkpIiwic2N0IjoiRXgoKS50ZXN0X2Z1bmN0aW9uKFwicHJpbnRcIikifQ==

Aquí surge una disyuntiva: necesitas datos limpios, pero tampoco te sobra muestra. Dos columnas tienen pocos nulos. Hay 110 nulos en SO (strikeouts) y 22 en DP (doble matanza). Otras dos columnas tienen muchos. Hay 419 nulos en CS (cazado robando) y 1.777 en HBP (golpeado por lanzamiento).

Si eliminas las filas con pocos nulos, pierdes algo más del cinco por ciento de los datos. Como quieres predecir victorias, las carreras anotadas y permitidas están muy correlacionadas con el objetivo; quieres que esas columnas sean muy precisas.

Los strikeouts (SO) y las dobles matanzas (DP) no son tan críticas.

Es mejor conservar las filas y rellenar los nulos con la mediana de cada columna con fillna(). Cazado robando (CS) y golpeado por lanzamiento (HBP) tampoco son variables importantes y, con tantos nulos, conviene eliminarlas por completo.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZCBcbnRlYW1zID0gcGQucmVhZF9jc3YoXCJodHRwczovL3MzLmFtYXpvbmF3cy5jb20vYXNzZXRzLmRhdGFjYW1wLmNvbS9ibG9nX2Fzc2V0cy90ZWFtc19kZi5jc3ZcIikgXG50ZWFtc19kZiA9IHBkLkRhdGFGcmFtZSh0ZWFtcylcbmNvbHMgPSBbJ3llYXJJRCcsJ2xnSUQnLCd0ZWFtSUQnLCdmcmFuY2hJRCcsJ2RpdklEJywnUmFuaycsJ0cnLCdHaG9tZScsJ1cnLFxuJ0wnLCdEaXZXaW4nLCdXQ1dpbicsJ0xnV2luJywnV1NXaW4nLCdSJywnQUInLCdIJywnMkInLCczQicsJ0hSJywnQkInLCdTTycsJ1NCJyxcbidDUycsJ0hCUCcsJ1NGJywnUkEnLCdFUicsJ0VSQScsJ0NHJywnU0hPJywnU1YnLCdJUG91dHMnLCdIQScsJ0hSQScsJ0JCQScsXG4nU09BJywnRScsJ0RQJywnRlAnLCduYW1lJywncGFyaycsJ2F0dGVuZGFuY2UnLCdCUEYnLCdQUEYnLCd0ZWFtSURCUicsJ3RlYW1JRGxhaG1hbjQ1JywndGVhbUlEcmV0cm8nLCdmcmFuY2hJRCcsJ2ZyYW5jaE5hbWUnLCdhY3RpdmUnLCdOQWFzc29jJ11cbnRlYW1zX2RmLmNvbHVtbnMgPSBjb2xzXG5kcm9wX2NvbHMgPSBbJ2xnSUQnLCdmcmFuY2hJRCcsJ2RpdklEJywnUmFuaycsJ0dob21lJywnTCcsJ0RpdldpbicsJ1dDV2luJywnTGdXaW4nLCdXU1dpbicsJ1NGJywnbmFtZScsJ3BhcmsnLCdhdHRlbmRhbmNlJywnQlBGJywnUFBGJywndGVhbUlEQlInLCd0ZWFtSURsYWhtYW40NScsJ3RlYW1JRHJldHJvJywnZnJhbmNoSUQnLCdmcmFuY2hOYW1lJywnYWN0aXZlJywnTkFhc3NvYyddXG5kZiA9IHRlYW1zX2RmLmRyb3AoZHJvcF9jb2xzLCBheGlzPTEpXG5wcmludChkZi5pc251bGwoKS5zdW0oYXhpcz0wKS50b2xpc3QoKSkiLCJzYW1wbGUiOiIjIEVsaW1pbmF0aW5nIGNvbHVtbnMgd2l0aCBudWxsIHZhbHVlc1xuZGYgPSBkZi5kcm9wKFsnQ1MnLCdIQlAnXSwgYXhpcz0xKVxuXG4jIEZpbGxpbmcgbnVsbCB2YWx1ZXNcbmRmWydTTyddID0gZGZbJ1NPJ10uZmlsbG5hKGRmWydTTyddLm1lZGlhbigpKVxuZGZbJ0RQJ10gPSBkZlsnRFAnXS5maWxsbmEoZGZbJ0RQJ10ubWVkaWFuKCkpXG5cbiMgUHJpbnQgb3V0IG51bGwgdmFsdWVzIG9mIGFsbCBjb2x1bW5zIG9mIGBkZmBcbnByaW50KGRmLmlzbnVsbCgpLnN1bShheGlzPTApLnRvbGlzdCgpKSIsInNvbHV0aW9uIjoiIyBFbGltaW5hdGluZyBjb2x1bW5zIHdpdGggbnVsbCB2YWx1ZXNcbmRmID0gZGYuZHJvcChbJ0NTJywnSEJQJ10sIGF4aXM9MSlcblxuIyBGaWxsaW5nIG51bGwgdmFsdWVzXG5kZlsnU08nXSA9IGRmWydTTyddLmZpbGxuYShkZlsnU08nXS5tZWRpYW4oKSlcbmRmWydEUCddID0gZGZbJ0RQJ10uZmlsbG5hKGRmWydEUCddLm1lZGlhbigpKVxuXG4jIFByaW50IG91dCBudWxsIHZhbHVlcyBvZiBhbGwgY29sdW1ucyBvZiBgZGZgXG5wcmludChkZi5pc251bGwoKS5zdW0oYXhpcz0wKS50b2xpc3QoKSkiLCJzY3QiOiJFeCgpLnRlc3RfZGF0YV9mcmFtZShcImRmXCIsIGNvbHVtbnM9Wyd5ZWFySUQnLC andGVhbUlEJywgJ0cnLCAnVycsICdSJywgJ0FCJywgJ0gnLCAnMkInLCAnM0InLCAnSFInLFxuICAgICAgICdCQicsICdTTycsICdTQicsICdSQScsICdFUicsICdFUkEnLCAnQ0cnLCAnU0hPJywgJ1NWJywgJ0lQb3V0cycsXG4gICAgICAgJ0hBJywgJ0hSQScsICdCQkEnLCAnU09BJywgJ0UnLCAnRFAnLCAnRlAnXSlcbkV4KCkudGVzdF9mdW5jdGlvbihcInByaW50XCIpIn0=

Explorar y visualizar los datos

Ahora que has limpiado los datos, puedes explorarlos. Unas cuantas visualizaciones sencillas te ayudarán a entender mejor el conjunto. matplotlib es una librería excelente para visualizar datos.

Importa matplotlib.pyplot y renómbralo como plt para abreviar. Si trabajas en un cuaderno Jupyter, usa el magic %matplotlib inline.

Empieza representando un histograma de la columna objetivo para ver la distribución de victorias.

# 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

Ten en cuenta que si no usas Jupyter, debes llamar a plt.show() para mostrar los gráficos.

Imprime la media de victorias (W) por año. Puedes usar el método mean().

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKSIsInNhbXBsZSI6InByaW50KGRmWydfJ10uX19fX19fKSIsInNvbHV0aW9uIjoicHJpbnQoZGZbJ1cnXS5tZWFuKCkpIiwic2N0IjoiRXgoKS50ZXN0X2Z1bmN0aW9uKFwicHJpbnRcIikifQ==

Puede ser útil crear rangos para la columna objetivo al explorar los datos, pero asegúrate de no incluir ninguna característica generada a partir de la columna objetivo cuando entrenes el modelo. Incluir en el train etiquetas derivadas del objetivo sería como darle las respuestas al modelo.

Para crear las etiquetas de victorias, define una función assign_win_bins que reciba un entero (victorias) y devuelva un entero de 1 a 5 según el valor de entrada.

Después crea una nueva columna win_bins aplicando assign_win_bins() sobre la columna de victorias con apply().

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKSIsInNhbXBsZSI6IiMgQ3JlYXRpbmcgYmlucyBmb3IgdGhlIHdpbiBjb2x1bW5cbmRlZiBhc3NpZ25fd2luX2JpbnMoXyk6XG4gICAgaWYgVyA8IDUwOlxuICAgICAgICByZXR1cm4gMVxuICAgIGlmIFcgPj0gNTAgYW5kIFcgPD0gNjk6XG4gICAgICAgIHJldHVybiAyXG4gICAgaWYgVyA+PSA3MCBhbmQgVyA8PSA4OTpcbiAgICAgICAgcmV0dXJuIDNcbiAgICBpZiBXID49IDkwIGFuZCBXIDw9IDEwOTpcbiAgICAgICAgcmV0dXJuIDRcbiAgICBpZiBXID49IDExMDpcbiAgICAgICAgcmV0dXJuIDVcbiAgICAgICAgXG4jIEFwcGx5IGBhc3NpZ25fd2luX2JpbnNgIHRvIGBkZlsnVyddYCAgICBcbmRmWyd3aW5fYmlucyddID0gZGZbJ18nXS5hcHBseShfX19fX19fX19fX19fXykiLCJzb2x1dGlvbiI6IiMgQ3JlYXRpbmcgYmlucyBmb3IgdGhlIHdpbiBjb2x1bW5cbmRlZiBhc3NpZ25fd2luX2JpbnMoVyk6XG4gICAgaWYgVyA8IDUwOlxuICAgICAgICByZXR1cm4gMVxuICAgIGlmIFcgPj0gNTAgYW5kIFcgPD0gNjk6XG4gICAgICAgIHJldHVybiAyXG4gICAgaWYgVyA+PSA3MCBhbmQgVyA8PSA4OTpcbiAgICAgICAgcmV0dXJuIDNcbiAgICBpZiBXID49IDkwIGFuZCBXIDw9IDEwOTpcbiAgICAgICAgcmV0dXJuIDRcbiAgICBpZiBXID49IDExMDpcbiAgICAgICAgcmV0dXJuIDVcbiAgICBcbmRmWyd3aW5fYmlucyddID0gZGZbJ1cnXS5hcHBseShhc3NpZ25fd2luX2JpbnMpIiwic2N0IjoiRXgoKS50ZXN0X2Z1bmN0aW9uX2RlZmluaXRpb24oXCJhc3NpZ25fd2luX2JpbnNcIilcbkV4KCkudGVzdF9vYmplY3QoXCJkZlwiKSJ9

Ahora hagamos un diagrama de dispersión con el año en el eje x y las victorias en el eje y, coloreando por 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 ves en el gráfico, hay muy pocas temporadas anteriores a 1900 y el juego era muy distinto entonces. Tiene sentido eliminar esas filas del conjunto.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKVxuZGVmIGFzc2lnbl93aW5fYmlucyhXKTpcbiAgICBpZiBXIDwgNTA6XG4gICAgICAgIHJldHVybiAxXG4gICAgaWYgVyA+PSA1MCBhbmQgVyA8PSA2OTpcbiAgICAgICAgcmV0dXJuIDJcbiAgICBpZiBXID49IDcwIGFuZCBXIDw9IDg5OlxuICAgICAgICByZXR1cm4gM1xuICAgIGlmIFcgPj0gOTAgYW5kIFcgPD0gMTA5OlxuICAgICAgICByZXR1cm4gNFxuICAgIGlmIFcgPj0gMTEwOlxuICAgICAgICByZXR1cm4gNVxuZGZbJ3dpbl9iaW5zJ10gPSBkZlsnVyddLmFwcGx5KGFzc2lnbl93aW5fYmlucykiLCJzYW1wbGUiOiIjIEZpbHRlciBmb3Igcm93cyB3aGVyZSAneWVhcklEJyBpcyBncmVhdGVyIHRoYW4gMTkwMFxuZGYgPSBkZltfX19fX19fX19fX19fX19fX19fXSIsInNvbHV0aW9uIjoiIyBGaWx0ZXIgZm9yIHJvd3Mgd2hlcmUgJ3llYXJJRCcgaXMgZ3JlYXRlciB0aGFuIDE5MDBcbmRmID0gZGZbZGZbJ3llYXJJRCddID4gMTkwMF0iLCJzY3QiOiJFeCgpLnRlc3Rfb2JqZWN0KFwiZGZcIikifQ

Con datos continuos y modelos lineales, valores enteros como el año pueden dar problemas. Es poco probable que 1950 tenga la relación con el resto de variables que el modelo infiere.

Puedes evitarlo creando nuevas variables que etiqueten los datos según el valor de yearID.

Quien siga el béisbol sabe que, a lo largo de la MLB, han surgido épocas con más o menos carreras por partido. La dead ball era de principios del siglo XX es un ejemplo de era de baja anotación, y la era de los esteroides a comienzos del XXI, de alta anotación.

Hagamos un gráfico que muestre cuánta anotación hubo cada año.

Empieza creando los diccionarios runs_per_year y games_per_year. Recorre el DataFrame con iterrows(). Rellena runs_per_year con años como claves y el total de carreras de ese año como valores. Rellena games_per_year con años como claves y el total de partidos jugados ese año como valores.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKVxuZGVmIGFzc2lnbl93aW5fYmlucyhXKTpcbiAgICBpZiBXIDwgNTA6XG4gICAgICAgIHJldHVybiAxXG4gICAgaWYgVyA+PSA1MCBhbmQgVyA8PSA2OTpcbiAgICAgICAgcmV0dXJuIDJcbiAgICBpZiBXID49IDcwIGFuZCBXIDw9IDg5OlxuICAgICAgICByZXR1cm4gM1xuICAgIGlmIFcgPj0gOTAgYW5kIFcgPD0gMTA5OlxuICAgICAgICByZXR1cm4gNFxuICAgIGlmIFcgPj0gMTEwOlxuICAgICAgICByZXR1cm4gNVxuZGZbJ3dpbl9iaW5zJ10gPSBkZlsnVyddLmFwcGx5KGFzc2lnbl93aW5fYmlucylcbmRmID0gZGZbZGZbJ3llYXJJRCddID4gMTkwMF0iLCJzYW1wbGUiOiIjIENyZWF0ZSBydW5zIHBlciB5ZWFyIGFuZCBnYW1lcyBwZXIgeWVhciBkaWN0aW9uYXJpZXNcbnJ1bnNfcGVyX3llYXIgPSB7fVxuZ2FtZXNfcGVyX3llYXIgPSB7fVxuXG5mb3IgaSwgcm93IGluIGRmLml0ZXJyb3dzKCk6XG4gICAgeWVhciA9IHJvd1sneWVhcklEJ11cbiAgICBydW5zID0gcm93WydSJ11cbiAgICBnYW1lcyA9IHJvd1snRyddXG4gICAgaWYgeWVhciBpbiBydW5zX3Blcl95ZWFyOlxuICAgICAgICBydW5zX3Blcl95ZWFyW3llYXJdID0gcnVuc19wZXJfeWVhclt5ZWFyXSArIHJ1bnNcbiAgICAgICAgZ2FtZXNfcGVyX3llYXJbeWVhcl0gPSBnYW1lc19wZXJfeWVhclt5ZWFyXSArIGdhbWVzXG4gICAgZWxzZTpcbiAgICAgICAgcnVuc19wZXJfeWVhclt5ZWFyXSA9IHJ1bnNcbiAgICAgICAgZ2FtZXNfcGVyX3llYXJbeWVhcl0gPSBnYW1lc1xuICAgICAgICBcbnByaW50KHJ1bnNfcGVyX3llYXIpXG5wcmludChnYW1lc19wZXJfeWVhcikifQ==

Ahora, crea un diccionario mlb_runs_per_game. Itera por games_per_year con items(). Rellena mlb_runs_per_game con años como claves y el número de carreras por partido de toda la liga como valores.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKVxuZGVmIGFzc2lnbl93aW5fYmlucyhXKTpcbiAgICBpZiBXIDwgNTA6XG4gICAgICAgIHJldHVybiAxXG4gICAgaWYgVyA+PSA1MCBhbmQgVyA8PSA2OTpcbiAgICAgICAgcmV0dXJuIDJcbiAgICBpZiBXID49IDcwIGFuZCBXIDw9IDg5OlxuICAgICAgICByZXR1cm4gM1xuICAgIGlmIFcgPj0gOTAgYW5kIFcgPD0gMTA5OlxuICAgICAgICByZXR1cm4gNFxuICAgIGlmIFcgPj0gMTEwOlxuICAgICAgICByZXR1cm4gNVxuZGZbJ3dpbl9iaW5zJ10gPSBkZlsnVyddLmFwcGx5KGFzc2lnbl93aW5fYmlucylcbmRmID0gZGZbZGZbJ3llYXJJRCddID4gMTkwMF1cbnJ1bnNfcGVyX3llYXIgPSB7fVxuZ2FtZXNfcGVyX3llYXIgPSB7fVxuZm9yIGksIHJvdyBpbiBkZi5pdGVycm93cygpOlxuICAgIHllYXIgPSByb3dbJ3llYXJJRCddXG4gICAgcnVucyA9IHJvd1snUiddXG4gICAgZ2FtZXMgPSByb3dbJ0cnXVxuICAgIGlmIHllYXIgaW4gcnVuc19wZXJfeWVhcjpcbiAgICAgICAgcnVuc19wZXJfeWVhclt5ZWFyXSA9IHJ1bnNfcGVyX3llYXJbeWVhcl0gKyBydW5zXG4gICAgICAgIGdhbWVzX3Blcl95ZWFyW3llYXJdID0gZ2FtZXNfcGVyX3llYXJbeWVhcl0gKyBnYW1lc1xuICAgIGVsc2U6XG4gICAgICAgIHJ1bnNfcGVyX3llYXJbeWVhcl0gPSBydW5zXG4gICAgICAgIGdhbWVzX3Blcl95ZWFyW3llYXJdID0gZ2FtZXMiLCJzYW1wbGUiOiIjIENyZWF0ZSBNTEIgcnVucyBwZXIgZ2FtZSAocGVyIHllYXIpIGRpY3Rpb25hcnlcbm1sYl9ydW5zX3Blcl9nYW1lID0ge31cbmZvciBrLCB2IGluIGdhbWVzX3Blcl95ZWFyLml0ZW1zKCk6XG4gICAgeWVhciA9IGtcbiAgICBnYW1lcyA9IHZcbiAgICBydW5zID0gcnVuc19wZXJfeWVhclt5ZWFyXVxuICAgIG1sYl9ydW5zX3Blcl9nYW1lW3llYXJdID0gcnVucyAvIGdhbWVzXG4gICAgXG5wcmludChtbGJfcnVuc19wZXJfZ2FtZSkifQ==

Por último, crea el gráfico a partir del diccionario mlb_runs_per_game, con los años en el eje x y las carreras por partido en el eje 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

Añadir nuevas características

Con una idea más clara de las tendencias de anotación, puedes crear variables que indiquen la era a la que pertenece cada fila en función de yearID. Seguirás el mismo proceso que cuando creaste win_bins.

Esta vez crearás variables dummy: una columna nueva por era. Puedes usar get_dummies() para ello.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKVxuZGVmIGFzc2lnbl93aW5fYmlucyhXKTpcbiAgICBpZiBXIDwgNTA6XG4gICAgICAgIHJldHVybiAxXG4gICAgaWYgVyA+PSA1MCBhbmQgVyA8PSA2OTpcbiAgICAgICAgcmV0dXJuIDJcbiAgICBpZiBXID49IDcwIGFuZCBXIDw9IDg5OlxuICAgICAgICByZXR1cm4gM1xuICAgIGlmIFcgPj0gOTAgYW5kIFcgPD0gMTA5OlxuICAgICAgICByZXR1cm4gNFxuICAgIGlmIFcgPj0gMTEwOlxuICAgICAgICByZXR1cm4gNVxuZGZbJ3dpbl9iaW5zJ10gPSBkZlsnVyddLmFwcGx5KGFzc2lnbl93aW5fYmlucylcbmRmID0gZGZbZGZbJ3llYXJJRCddID4gMTkwMF1cbnJ1bnNfcGVyX3llYXIgPSB7fVxuZ2FtZXNfcGVyX3llYXIgPSB7fVxuZm9yIGksIHJvdyBpbiBkZi5pdGVycm93cygpOlxuICAgIHllYXIgPSByb3dbJ3llYXJJRCddXG4gICAgcnVucyA9IHJvd1snUiddXG4gICAgZ2FtZXMgPSByb3dbJ0cnXVxuICAgIGlmIHllYXIgaW4gcnVuc19wZXJfeWVhcjpcbiAgICAgICAgcnVuc19wZXJfeWVhclt5ZWFyXSA9IHJ1bnNfcGVyX3llYXJbeWVhcl0gKyBydW5zXG4gICAgICAgIGdhbWVzX3Blcl95ZWFyW3llYXJdID0gZ2FtZXNfcGVyX3llYXJbeWVhcl0gKyBnYW1lc1xuICAgIGVsc2U6XG4gICAgICAgIHJ1bnNfcGVyX3llYXJbeWVhcl0gPSBydW5zXG4gICAgICAgIGdhbWVzX3Blcl95ZWFyW3llYXJdID0gZ2FtZXNcbm1sYl9ydW5zX3Blcl9nYW1lID0ge31cbmZvciBrLCB2IGluIGdhbWVzX3Blcl95ZWFyLml0ZW1zKCk6XG4gICAgeWVhciA9IGtcbiAgICBnYW1lcyA9IHZcbiAgICBydW5zID0gcnVuc19wZXJfeWVhclt5ZWFyXVxuICAgIG1sYl9ydW5zX3Blcl9nYW1lW3llYXJdID0gcnVucyAvIGdhbWVzIiwic2FtcGxlIjoiIyBDcmVhdGluZyBcInllYXJfbGFiZWxcIiBjb2x1bW4sIHdoaWNoIHdpbGwgZ2l2ZSB5b3VyIGFsZ29yaXRobSBpbmZvcm1hdGlvbiBhYm91dCBob3cgY2VydGFpbiB5ZWFycyBhcmUgcmVsYXRlZCBcbiMgKERlYWQgYmFsbCBlcmFzLCBMaXZlIGJhbGwvU3Rlcm9pZCBFcmFzKVxuXG5kZWYgYXNzaWduX2xhYmVsKF9fX18pOlxuICAgIGlmIHllYXIgPCAxOTIwOlxuICAgICAgICByZXR1cm4gMVxuICAgIGVsaWYgeWVhciA+PSAxOTIwIGFuZCB5ZWFyIDw9IDE5NDE6XG4gICAgICAgIHJldHVybiAyXG4gICAgZWxpZiB5ZWFyID49IDE5NDIgYW5kIHllYXIgPD0gMTk0NTpcbiAgICAgICAgcmV0dXJuIDNcbiAgICBlbGlmIHllYXIgPj0gMTk0NiBhbmQgeWVhciA8PSAxOTYyOlxuICAgICAgICByZXR1cm4gNFxuICAgIGVsaWYgeWVhciA+PSAxOTYzIGFuZCB5ZWFyIDw9IDE5NzY6XG4gICAgICAgIHJldHVybiA1XG4gICAgZWxpZiB5ZWFyID49IDE5NzcgYW5kIHllYXIgPD0gMTk5MjpcbiAgICAgICAgcmV0dXJuIDZcbiAgICBlbGlmIHllYXIgPj0gMTk5MyBhbmQgeWVhciA8PSAyMDA5OlxuICAgICAgICByZXR1cm4gN1xuICAgIGVsaWYgeWVhciA+PSAyMDAxMDpcbiAgICAgICAgcmV0dXJuIDhcbiAgICAgICAgXG4jIEFkZCBgeWVhcl9sYWJlbGAgY29sdW1uIHRvIGBkZmAgICAgXG5kZlsneWVhcl9sYWJlbCddID0gZGZbJ3llYXJJRCddLmFwcGx5KGFzc2lnbl9sYWJlbClcblxuZHVtbXlfZGYgPSBwZC5nZXRfZHVtbWllcyhkZlsneWVhcl9sYWJlbCddLCBwcmVmaXg9J2VyYScpXG5cbiMgQ29uY2F0ZW5hdGUgYGRmYCBhbmQgYGR1bW15X2RmYFxuZGYgPSBwZC5jb25jYXQoW2RmLCBkdW1teV9kZl0sIGF4aXM9MSlcblxucHJpbnQoZGYuaGVhZCgpKSIsInNvbHV0aW9uIjoiIyBDcmVhdGluZyBcInllYXJfbGFiZWxcIiBjb2x1bW4sIHdoaWNoIHdpbGwgZ2l2ZSB5b3VyIGFsZ29yaXRobSBpbmZvcm1hdGlvbiBhYm91dCBob3cgY2VydGFpbiB5ZWFycyBhcmUgcmVsYXRlZCBcbiMgKERlYWQgYmFsbCBlcmFzLCBMaXZlIGJhbGwvU3Rlcm9pZCBFcmFzKVxuXG5kZWYgYXNzaWduX2xhYmVsKHllYXIpOlxuICAgIGlmIHllYXIgPCAxOTIwOlxuICAgICAgICByZXR1cm4gMVxuICAgIGVsaWYgeWVhciA+PSAxOTIwIGFuZCB5ZWFyIDw9IDE5NDE6XG4gICAgICAgIHJldHVybiAyXG4gICAgZWxpZiB5ZWFyID49IDE5NDIgYW5kIHllYXIgPD0gMTk0NTpcbiAgICAgICAgcmV0dXJuIDNcbiAgICBlbGlmIHllYXIgPj0gMTk0NiBhbmQgeWVhciA8PSAxOTYyOlxuICAgICAgICByZXR1cm4gNFxuICAgIGVsaWYgeWVhciA+PSAxOTYzIGFuZCB5ZWFyIDw9IDE5NzY6XG4gICAgICAgIHJldHVybiA1XG4gICAgZWxpZiB5ZWFyID49IDE5NzcgYW5kIHllYXIgPD0gMTk5MjpcbiAgICAgICAgcmV0dXJuIDZcbiAgICBlbGlmIHllYXIgPj0gMTk5MyBhbmQgeWVhciA8PSAyMDA5OlxuICAgICAgICByZXR1cm4gN1xuICAgIGVsaWYgeWVhciA+PSAyMDEwOlxuICAgICAgICByZXR1cm4gOFxuICAgICAgICBcbiMgQWRkIGB5ZWFyX2xhYmVsYCBjb2x1bW4gdG8gYGRmYCAgICBcbmRmWyd5ZWFyX2xhYmVsJ10gPSBkZlsneWVhcklEJ10uYXBwbHkoX19fX19fX19fX18pXG5cbmR1bW15X2RmID0gcGQuZ2V0X2R1bW1pZXMoZGZbJ3llYXJfbGFiZWwnXSwgcHJlZml4PSdlcmEnKVxuXG4jIENvbmNhdGVuYXRlIGBkZmAgYW5kIGBkdW1teV9kZmBcbmRmID0gcGQuY29uY2F0KFtkZiwgZHVtbXlfZGZdLCBheGlzPTEpXG5cbnByaW50KGRmLmhlYWQoKSkiLCJzY3QiOiJFeCgpLnRlc3RfZHVuY3Rpb25fZGVmaW5pdGlvbihcImFzc2lnbl9sYWJlbFwiKVxuRXgoKS50ZXN0X2RhdGFfZnJhbWUoXCJkZlwiKVxuRXgoKS50ZXN0X2RhdGFfZnJhbWUoXCJkdW1teV9kZlwiKVxuRXgoKS5jaGVja19vYmplY3QoXCJkZlwiKS5oYXNfZXF1YWxfa2V5KFwieWVhcl9sYWJlbFwiKVxuRXgoKS50ZXN0X2Z1bmN0aW9uKFwicHJpbnRcIikifQ==

Ya que has calculado las carreras por partido de la MLB por año, añade esa información al conjunto.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKVxuZGVmIGFzc2lnbl93aW5fYmlucyhXKTpcbiAgICBpZiBXIDwgNTA6XG4gICAgICAgIHJldHVybiAxXG4gICAgaWYgVyA+PSA1MCBhbmQgVyA8PSA2OTpcbiAgICAgICAgcmV0dXJuIDJcbiAgICBpZiBXID49IDcwIGFuZCBXIDw9IDg5OlxuICAgICAgICByZXR1cm4gM1xuICAgIGlmIFcgPj0gOTAgYW5kIFcgPD0gMTA5OlxuICAgICAgICByZXR1cm4gNFxuICAgIGlmIFcgPj0gMTEwOlxuICAgICAgICByZXR1cm4gNVxuZGZbJ3dpbl9iaW5zJ10gPSBkZlsnVyddLmFwcGx5KGFzc2lnbl93aW5fYmlucylcbmRmID0gZGZbZGZbJ3llYXJJRCddID4gMTkwMF1cbnJ1bnNfcGVyX3llYXIgPSB7fVxuZ2FtZXNfcGVyX3llYXIgPSB7fVxuZm9yIGksIHJvdyBpbiBkZi5pdGVycm93cygpOlxuICAgIHllYXIgPSByb3dbJ3llYXJJRCddXG4gICAgcnVucyA9IHJvd1snUiddXG4gICAgZ2FtZXMgPSByb3dbJ0cnXVxuICAgIGlmIHllYXIgaW4gcnVuc19wZXJfeWVhcjpcbiAgICAgICAgcnVuc19wZXJfeWVhclt5ZWFyXSA9IHJ1bnNfcGVyX3llYXJbeWVhcl0gKyBydW5zXG4gICAgICAgIGdhbWVzX3Blcl95ZWFyW3llYXJdID0gZ2FtZXNfcGVyX3llYXJbeWVhcl0gKyBnYW1lc1xuICAgIGVsc2U6XG4gICAgICAgIHJ1bnNfcGVyX3llYXJbeWVhcl0gPSBydW5zXG4gICAgICAgIGdhbWVzX3Blcl95ZWFyW3llYXJdID0gZ2FtZXNcbm1sYl9ydW5zX3Blcl9nYW1lID0ge31cbmZvciBrLCB2IGluIGdhbWVzX3Blcl95ZWFyLml0ZW1zKCk6XG4gICAgeWVhciA9IGtcbiAgICBnYW1lcyA9IHZcbiAgICBydW5zID0gcnVuc19wZXJfeWVhclt5ZWFyXVxuICAgIG1sYl9ydW5zX3Blcl9nYW1lW3llYXJdID0gcnVucyAvIGdhbWVzXG5kZWYgYXNzaWduX2xhYmVsKHllYXIpOlxuICAgIGlmIHllYXIgPCAxOTIwOlxuICAgICAgICByZXR1cm4gMVxuICAgIGVsaWYgeWVhciA+PSAxOTIwIGFuZCB5ZWFyIDw9IDE5NDE6XG4gICAgICAgIHJldHVybiAyXG4gICAgZWxpZiB5ZWFyID49IDE5NDIgYW5kIHllYXIgPD0gMTk0NTpcbiAgICAgICAgcmV0dXJuIDNcbiAgICBlbGlmIHllYXIgPj0gMTk0NiBhbmQgeWVhciA8PSAxOTYyOlxuICAgICAgICByZXR1cm4gNFxuICAgIGVsaWYgeWVhciA+PSAxOTYzIGFuZCB5ZWFyIDw9IDE5NzY6XG4gICAgICAgIHJldHVybiA1XG4gICAgZWxpZiB5ZWFyID49IDE5NzcgYW5kIHllYXIgPD0gMTk5MjpcbiAgICAgICAgcmV0dXJuIDZcbiAgICBlbGlmIHllYXIgPj0gMTk5MyBhbmQgeWVhciA8PSAyMDA5OlxuICAgICAgICByZXR1cm4gN1xuICAgIGVsaWYgeWVhciA+PSAyMDEwOlxuICAgICAgICByZXR1cm4gOFxuICAgIFxuZGZbJ3llYXJfbGFiZWwnXSA9IGRmWyd5ZWFySUQnXS5hcHBseShhc3NpZ25fbGFiZWwpXG5kdW1teV9kZiA9IHBkLmdldF9kdW1taWVzKGRmWyd5ZWFyX2xhYmVsJ10sIHByZWZpeD0nZXJhJylcblxuZGYgPSBwZC5jb25jYXQoW2RmLCBkdW1teV9kZl0sIGF4aXM9MSkiLCJzYW1wbGUiOiIjIENyZWF0ZSBjb2x1bW4gZm9yIE1MQiBydW5zIHBlciBnYW1lIGZyb20gdGhlIG1sYl9ydW5zX3Blcl9nYW1lIGRpY3Rpb25hcnlcbmRlZiBhc3NpZ25fbWxiX3JwZyh5ZWFyKTpcbiAgICByZXR1cm4gbWxiX3J1bnNfcGVyX2dhbWVbeWVhcl1cblxuZGZbJ21sYl9ycGcnXSA9IGRmWyd5ZWFySUQnXS5hcHBseShhc3NpZ25fbWxiX3JwZykiLCJzb2x1dGlvbiI6IiMgQ3JlYXRlIGNvbHVtbiBmb3IgTUxCIHJ1bnMgcGVyIGdhbWUgZnJvbSB0aGUgbWxiX3J1bnNfcGVyX2dhbWUgZGljdGlvbmFyeVxuZGVmIGFzc2lnbl9tbGJfcnBnKHllYXIpOlxuICAgIHJldHVybiBtbGJfcnVuc19wZXJfZ2FtZVt5ZWFyXVxuXG5kZlsnbWxiX3JwZyddID0gZGZbJ3llYXJJRCddLmFwcGx5KGFzc2lnbl9tbGJfcnBnKSIsInNjdCI6IkV4KCkudGVzdF9mdW5jdGlvbl9kZWZpbml0aW9uKFwiYXNzaWduX21sYl9ycGdcIilcbkV4KCkudGVzdF9vYmplY3QoXCJkZlwiKSJ9

Ahora convertirás los años en décadas creando columnas dummy por década. Después puedes eliminar las columnas que ya no necesitas.

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

En el béisbol, la clave es cuántas carreras anotas y cuántas permites. Puedes aumentar bastante la precisión del modelo creando columnas que sean razones de otras. Las carreras por partido y las carreras permitidas por partido serán grandes aportes al dataset.

Pandas lo hace muy sencillo: crea una nueva columna dividiendo R entre G para obtener R_per_game.

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

Ahora examina cómo se relacionan estas nuevas variables con la columna objetivo de victorias con un par de gráficos de dispersión. Representa las carreras por partido en el eje x de un gráfico y las permitidas por partido en el del otro. En ambos, usa W en el eje 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 entrar en modelos de machine learning, es útil ver cómo se correlaciona cada variable con el objetivo. Pandas lo facilita con corr().

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zX3dob2xlLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKSIsInNhbXBsZSI6ImRmLmNvcnIoKVsnVyddIn0=

Otra característica que puedes añadir al dataset son etiquetas derivadas de un algoritmo de clustering K-means de sklearn. K-means es un algoritmo sencillo que particiona los datos en k centroides. Cada punto se asigna al clúster con menor distancia euclídea al centroide.

Puedes aprender más sobre K-means aquí.

Primero, crea un DataFrame que excluya la variable objetivo:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zX3dob2xlLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKSIsInNhbXBsZSI6ImF0dHJpYnV0ZXMgPSBbJ0cnLCdSJywnQUInLCdIJywnMkInLCczQicsJ0hSJywnQkInLCdTTycsJ1NCJywnUkEnLCdFUicsJ0VSQScsJ0NHJyxcbidTSE8nLCdTVicsJ0lQb3V0cycsJ0hBJywnSFJBJywnQkJBJywnU09BJywnRScsJ0RQJywnRlAnLCdlcmFfMScsJ2VyYV8yJywnZXJhXzMnLCdlcmFfNCcsJ2VyYV81JywnZXJhXzYnLCdlcmFfNycsJ2VyYV84JywnZGVjYWRlXzE5MTAnLCdkZWNhZGVfMTkyMCcsJ2RlY2FkZV8xOTMwJywnZGVjYWRlXzE5NDAnLCdkZWNhZGVfMTk1MCcsJ2RlY2FkZV8xOTYwJywnZGVjYWRlXzE5NzAnLCdkZWNhZGVfMTk4MCcsJ2RlY2FkZV8xOTkwJywnZGVjYWRlXzIwMDAnLCdkZWNhZGVfMjAxMCcsJ1JfcGVyX2dhbWUnLCdSQV9wZXJfZ2FtZScsJ21sYl9ycGcnXVxuXG5kYXRhX2F0dHJpYnV0ZXMgPSBkZlthdHRyaWJ1dGVzXVxuXG4jIFByaW50IHRoZSBmaXJzdCByb3dzIG9mIGBkZmBcbnByaW50KGRmLmhlYWQoKSkiLCJzb2x1dGlvbiI6ImF0dHJpYnV0ZXMgPSBbJ0cnLCdSJywnQUInLCdIJywnMkInLCczQicsJ0hSJywnQkInLCdTTycsJ1NCJywnUkEnLCdFUicsJ0VSQScsJ0NHJyxcbidTSE8nLCdTVicsJ0lQb3V0cycsJ0hBJywnSFJBJywnQkJBJywnU09BJywnRScsJ0RQJywnRlAnLCdlcmFfMScsJ2VyYV8yJywnZXJhXzMnLCdlcmFfNCcsJ2VyYV81JywnZXJhXzYnLCdlcmFfNycsJ2VyYV84JywnZGVjYWRlXzE5MTAnLCdkZWNhZGVfMTkyMCcsJ2RlY2FkZV8xOTMwJywnZGVjYWRlXzE5NDAnLCdkZWNhZGVfMTk1MCcsJ2RlY2FkZV8xOTYwJywnZGVjYWRlXzE5NzAnLCdkZWNhZGVfMTk4MCcsJ2RlY2FkZV8xOTkwJywnZGVjYWRlXzIwMDAnLCdkZWNhZGVfMjAxMCcsJ1JfcGVyX2dhbWUnLCdSQV9wZXJfZ2FtZScsJ21sYl9ycGcnXVxuXG5kYXRhX2F0dHJpYnV0ZXMgPSBkZlthdHRyaWJ1dGVzXVxuXG4jIFByaW50IHRoZSBmaXJzdCByb3dzIG9mIGBkZmBcbnByaW50KGRmLmhlYWQoKSkiLCJzY3QiOiJFeCgpLnRlc3Rfb2JqZWN0KFwiYXR0cmlidXRlc1wiKVxuRXgoKS50ZXN0X29iamVjdChcImRhdGFfYXR0cmlidXRlc1wiKVxuRXgoKS50ZXN0X2Z1bmN0aW9uKFwicHJpbnRcIikifQ==

Antes de usar K-means debes decidir cuántos clústeres quieres. Una forma de orientarte es la función silhouette_score() de sklearn. Devuelve el coeficiente medio de silueta; cuanto mayor, mejor, y suele disminuir al añadir más clústeres.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zX3dob2xlLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKVxuYXR0cmlidXRlcyA9IFsnRycsJ1InLCdBQicsJ0gnLCcyQicsJzNCJywnSFInLCdCQicsJ1NPJywnU0InLCdSQScsJ0VSJywnRVJBJywnQ0cnLFxuJ1NITycsJ1NWJywnSVBvdXRzJywnSEEnLCdIUkEnLCdCQkEnLCdTT0EnLCdFJywnRFAnLCdGUCcsJ2VyYV8xJywnZXJhXzInLCdlcmFfMycsJ2VyYV80JywnZXJhXzUnLCdlcmFfNicsJ2VyYV83JywnZXJhXzgnLCdkZWNhZGVfMTkxMCcsJ2RlY2FkZV8xOTIwJywnZGVjYWRlXzE5MzAnLCdkZWNhZGVfMTk0MCcsJ2RlY2FkZV8xOTUwJywnZGVjYWRlXzE5NjAnLCdkZWNhZGVfMTk3MCcsJ2RlY2FkZV8xOTgwJywnZGVjYWRlXzE5OTAnLCdkZWNhZGVfMjAwMCcsJ2RlY2FkZV8yMDEwJywnUl9wZXJfZ2FtZScsJ1JBX3Blcl9nYW1lJywnbWxiX3JwZyddXG5kYXRhX2F0dHJpYnV0ZXMgPSBkZlthdHRyaWJ1dGVzXSIsInNhbXBsZSI6IiMgSW1wb3J0IG5lY2Vzc2FyeSBtb2R1bGVzIGZyb20gYHNrbGVhcm5gIFxuZnJvbSBza2xlYXJuLmNsdXN0ZXIgaW1wb3J0IEtNZWFuc1xuZnJvbSBza2xlYXJuIGltcG9ydCBtZXRyaWNzXG5cbiMgQ3JlYXRlIHNpbGhvdWV0dGUgc2NvcmUgZGljdGlvbmFyeVxuc19zY29yZV9kaWN0ID0ge31cbmZvciBpIGluIHJhbmdlKDIsMTEpOlxuICAgIGttID0gS01lYW5zKG5fY2x1c3RlcnM9aSwgcmFuZG9tX3N0YXRlPTEpXG4gICAgbCA9IGttLmZpdF9wcmVkaWN0KGRhdGFfYXR0cmlidXRlcylcbiAgICBzX3MgPSBtZXRyaWNzLnNpbGhvdWV0dGVfc2NvcmUoZGF0YV9hdHRyaWJ1dGVzLCBsKVxuICAgIHNfc2NvcmVfZGljdFtpXSA9IFtzX3NdXG5cbiMgUHJpbnQgb3V0IGBzX3Njb3JlX2RpY3RgXG5wcmludChzX3Njb3JlX2RpY3QpIiwic29sdXRpb24iOiIjIEltcG9ydCBuZWNlc3NhcnkgbW9kdWxlcyBmcm9tIGBza2xlYXJuYCBcbmZyb20gc2tsZWFybi5jbHVzdGVyIGltcG9ydCBLTWVhbnNcbmZyb20gc2tsZWFybiBpbXBvcnQgbWV0cmljc1xuXG4jIENyZWF0ZSBzaWxob3VldHRlIHNjb3JlIGRpY3Rpb25hcnlcbnNfc2NvcmVfZGljdCA9IHt9XG5mb3IgaSBpbiByYW5nZSgyLDExKTpcbiAgICBrbSA9IEtNZWFucyhuX2NsdXN0ZXJzPWksIHJhbmRvbV9zdGF0ZT0xKVxuICAgIGwgPSBrbS5maXRfcHJlZGljdChkYXRhX2F0dHJpYnV0ZXMpXG4gICAgc19zID0gbWV0cmljcy5zaWxob3VldHRlX3Njb3JlKGRhdGFfYXR0cmlidXRlcywgbClcbiAgICBzX3Njb3JlX2RpY3RbaV0gPSBbc19zXVxuXG4jIFByaW50IG91dCBgc19zY29yZV9kaWN0YFxucHJpbnQoc19zY29yZV9kaWN0KSIsInNjdCI6IkV4KCkudGVzdF9pbXBvcnQoXCJza2xlYXJuLmNsdXN0ZXIuS01lYW5zXCIpXG5FeCgpLnRlc3RfaW1wb3J0KFwic2tsZWFybi5tZXRyaWNzXCIpXG5FeCgpLnRlc3Rfb2JqZWN0KFwic19zY29yZV9kaWN0XCIpXG4jIGZvciBsb29wIHRlc3RcbkV4KCkudGVzdF9mdW5jdGlvbihcInByaW50XCIpIn0=

Ahora inicializa el modelo. Fija 6 clústeres y random_state a 1. Calcula las distancias euclídeas de cada punto con fit_transform() y visualiza los clústeres con un scatter.

# 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

Añade ahora las etiquetas de tus clústeres al dataset como columna nueva. Añade también la cadena "labels" a la lista attributes para usarla más adelante.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZnJvbSBza2xlYXJuLmNsdXN0ZXIgaW1wb3J0IEtNZWFuc1xuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zX3dob2xlLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKVxuYXR0cmlidXRlcyA9IFsnRycsJ1InLCdBQicsJ0gnLCcyQicsJzNCJywnSFInLCdCQicsJ1NPJywnU0InLCdSQScsJ0VSJywnRVJBJywnQ0cnLFxuJ1NITycsJ1NWJywnSVBvdXRzJywnSEEnLCdIUkEnLCdCQkEnLCdTT0EnLCdFJywnRFAnLCdGUCcsJ2VyYV8xJywnZXJhXzInLCdlcmFfMycsJ2VyYV80JywnZXJhXzUnLCdlcmFfNicsJ2VyYV83JywnZXJhXzgnLCdkZWNhZGVfMTkxMCcsJ2RlY2FkZV8xOTIwJywnZGVjYWRlXzE5MzAnLCdkZWNhZGVfMTk0MCcsJ2RlY2FkZV8xOTUwJywnZGVjYWRlXzE5NjAnLCdkZWNhZGVfMTk3MCcsJ2RlY2FkZV8xOTgwJywnZGVjYWRlXzE5OTAnLCdkZWNhZGVfMjAwMCcsJ2RlY2FkZV8yMDEwJywnUl9wZXJfZ2FtZScsJ1JBX3Blcl9nYW1lJywnbWxiX3JwZyddXG5kYXRhX2F0dHJpYnV0ZXMgPSBkZlthdHRyaWJ1dGVzXVxua21lYW5zX21vZGVsID0gS01lYW5zKG5fY2x1c3RlcnM9NiwgcmFuZG9tX3N0YXRlPTEpXG5kaXN0YW5jZXMgPSBrbWVhbnNfbW9kZWwuZml0X3RyYW5zZm9ybShkYXRhX2F0dHJpYnV0ZXMpXG5sYWJlbHMgPSBrbWVhbnNfbW9kZWwubGFiZWxzX1xuZGZbJ2xhYmVscyddID0gbGFiZWxzXG5hdHRyaWJ1dGVzLmFwcGVuZCgnbGFiZWxzJylcblxuIyBQcmludCB0aGUgZmlyc3Qgcm93cyBvZiBgZGZgXG5wcmludChfX19fX19fX18pIiwic29sdXRpb24iOiIjIEFkZCBsYWJlbHMgZnJvbSBLLW1lYW5zIG1vZGVsIHRvIGBkZmAgRGF0YUZyYW1lIGFuZCBhdHRyaWJ1dGVzIGxpc3RcbmRmWydsYWJlbHMnXSA9IGxhYmVsc1xuYXR0cmlidXRlcy.hcHBlbmQoJ2xhYmVscycpXG5cbiMgUHJpbnQgdGhlIGZpcnN0IHJvd3Mgb2YgYGRmYFxucHJpbnQoZGYuaGVhZCgpKSIsInNjdCI6IkV4KCkudGVzdF9vYmplY3QoXCJkZlwiKVxuRXgoKS50ZXN0X29iamVjdChcImF0dHJpYnV0ZXNcIilcbkV4KCkudGVzdF9mdW5jdGlvbihcInByaW50XCIpIn0=

Antes de construir el modelo, divide los datos en train y test. Si entrenas y pruebas con los mismos datos, el modelo puede sobreajustarse: memoriza en lugar de aprender y rinde mal con datos nuevos.

No te preocupes: hay varias formas de validar.

En esta ocasión, toma una muestra aleatoria del 75 % como train y usa el 25 % restante como test. Crea una lista numeric_cols con todas las columnas que usarás. Después, crea un nuevo DataFrame data a partir de df con esas columnas. Por último, crea los conjuntos train y test muestreando data.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZnJvbSBza2xlYXJuLmNsdXN0ZXIgaW1wb3J0IEtNZWFuc1xuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zX3dob2xlLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKVxuYXR0cmlidXRlcyA9IFsnRycsJ1InLCdBQicsJ0gnLCcyQicsJzNCJywnSFInLCdCQicsJ1NPJywnU0InLCdSQScsJ0VSJywnRVJBJywnQ0cnLFxuJ1NITycsJ1NWJywnSVBvdXRzJywnSEEnLCdIUkEnLCdCQkEnLCdTT0EnLCdFJywnRFAnLCdGUCcsJ2VyYV8xJywnZXJhXzInLCdlcmFfMycsJ2VyYV80JywnZXJhXzUnLCdlcmFfNicsJ2VyYV83JywnZXJhXzgnLCdkZWNhZGVfMTkxMCcsJ2RlY2FkZV8xOTIwJywnZGVjYWRlXzE5MzAnLCdkZWNhZGVfMTk0MCcsJ2RlY2FkZV8xOTUwJywnZGVjYWRlXzE5NjAnLCdkZWNhZGVfMTk3MCcsJ2RlY2FkZV8xOTgwJywnZGVjYWRlXzE5OTAnLCdkZWNhZGVfMjAwMCcsJ2RlY2FkZV8yMDEwJywnUl9wZXJfZ2FtZScsJ1JBX3Blcl9nYW1lJywnbWxiX3JwZyddXG5kYXRhX2F0dHJpYnV0ZXMgPSBkZlthdHRyaWJ1dGVzXVxua21lYW5zX21vZGVsID0gS01lYW5zKG5fY2x1c3RlcnM9NiwgcmFuZG9tX3N0YXRlPTEpXG5kaXN0YW5jZXMgPSBrbWVhbnNfbW9kZWwuZml0X3RyYW5zZm9ybShkYXRhX2F0dHJpYnV0ZXMpXG5sYWJlbHMgPSBrbWVhbnNfbW9kZWwubGFiZWxzX1xuZGZbJ2xhYmVscyddID0gbGFiZWxzXG5hdHRyaWJ1dGVzLmFwcGVuZCgnbGFiZWxzJykiLCJzYW1wbGUiOiIjIENyZWF0ZSBuZXcgRGF0YUZyYW1lIHVzaW5nIG9ubHkgdmFyaWFibGVzIHRvIGJlIGluY2x1ZGVkIGluIG1vZGVsc1xubnVtZXJpY19jb2xzID0gWydHJywnUicsJ0FCJywnSCcsJzJCJywnM0InLCdIUicsJ0JCJywnU08nLCdTQicsJ1JBJywnRVInLCdFUkEnLCdDRycsJ1NITycsJ1NWJywnSVBvdXRzJywnSEEnLCdIUkEnLCdCQkEnLCdTT0EnLCdFJywnRFAnLCdGUCcsJ2VyYV8xJywnZXJhXzInLCdlcmFfMycsJ2VyYV80JywnZXJhXzUnLCdlcmFfNicsJ2VyYV83JywnZXJhXzgnLCdkZWNhZGVfMTkxMCcsJ2RlY2FkZV8xOTIwJywnZGVjYWRlXzE5MzAnLCdkZWNhZGVfMTk0MCcsJ2RlY2FkZV8xOTUwJywnZGVjYWRlXzE5NjAnLCdkZWNhZGVfMTk3MCcsJ2RlY2FkZV8xOTgwJywnZGVjYWRlXzE5OTAnLCdkZWNhZGVfMjAwMCcsJ2RlY2FkZV8yMDEwJywnUl9wZXJfZ2FtZScsJ1JBX3Blcl9nYW1lJywnbWxiX3JwZycsJ2xhYmVscycsJ1cnXVxuZGF0YSA9IGRmW251bWVyaWNfY29sc11cbnByaW50KGRhdGEuaGVhZCgpKVxuXG4jIFNwbGl0IGRhdGEgRGF0YUZyYW1lIGludG8gdHJhaW4gYW5kIHRlc3Qgc2V0c1xudHJhaW4gPSBkYXRhLnNhbXBsZShmcmFjPTAuNzUsIHJhbmRvbV9zdGF0ZT0xKVxudGVzdCA9IGRhdGEubG9jW35kYXRhLmluZGV4LmlzaW4odHJhaW4uaW5kZXgpXVxuXG54X3RyYWluID0gdHJhaW5bYXR0cmlidXRlc11cbnlfdHJhaW4gPSB0cmFpblsnVyddXG54X3Rlc3QgPSB0ZXN0W2F0dHJpYnV0ZXNdXG55X3Rlc3QgPSB0ZXN0WydXJ10iLCJzb2x1dGlvbiI6IiMgQ3JlYXRlIG5ldyBEYXRhRnJhbWUgdXNpbmcgb25seSB2YXJpYWJsZXMgdG8gYmUgaW5jbHVkZWQgaW4gbW9kZWxzXG5udW1lcmljX2NvbHMgPSBbJ0cnLCdSJywnQUInLCdIJywnMkInLCczQicsJ0hSJywnQkInLCdTTycsJ1NCJywnUkEnLCdFUicsJ0VSQScsJ0NHJywnU0hPJywnU1YnLCdJUG91dHMnLCdIQScsJ0hSQScsJ0JCQScsJ1NPQScsJ0UnLCdEUCcsJ0ZQJywnZXJhXzEnLCdlcmFfMicsJ2VyYV8zJywnZXJhXzQnLCdlcmFfNScsJ2VyYV82JywnZXJhXzcnLCdlcmFfOCcsJ2RlY2FkZV8xOTEwJywnZGVjYWRlXzE5MjAnLCdkZWNhZGVfMTkzMCcsJ2RlY2FkZV8xOTQwJywnZGVjYWRlXzE5NTAnLCdkZWNhZGVfMTk2MCcsJ2RlY2FkZV8xOTcwJywnZGVjYWRlXzE5ODAnLCdkZWNhZGVfMTk5MCcsJ2RlY2FkZV8yMDAwJywnZGVjYWRlXzIwMTAnLCdSX3Blcl9nYW1lJywnUkFfcGVyX2dhbWUnLCdtbGJfcnBnJywnbGFiZWxzJywnVyddXG5kYXRhID0gZGZbbnVtZXJpY19jb2xzXVxucHJpbnQoZGF0YS5oZWFkKCkpXG5cbiMgU3BsaXQgZGF0YSBEYXRhRnJhbWUgaW50byB0cmFpbiBhbmQgdGVzdCBzZXRzXG50cmFpbiA9IGRhdGEuc2FtcGxlKGZyYWM9MC43NSwgcmFuZG9tX3N0YXRlPTEpXG50ZXN0ID0gZGF0YS5sb2NbfmRhdGEuaW5kZXguaXNpbih0cmFpbi5pbmRleCldXG5cbnhfdHJhaW4gPSB0cmFpblthdHRyaWJ1dGVzXVxueV90cmFpbiA9IHRyYWluWydXJ11cbnhfdGVzdCA9IHRlc3RbYXR0cmlidXRlc11cbnlfdGVzdCA9IHRlc3RbJ1cnXSIsInNjdCI6IkV4KCkudGVzdF9vYmplY3QoXCJudW1lcmljX2NvbHNcIilcbkV4KCkudGVzdF9vYmplY3QoXCJkYXRhXCIpXG5FeCgpLnRlc3RfZnVuY3Rpb24oXCJwcmludFwiKVxuRXgoKS50ZXN0X29iamVjdChcInRyYWluXCIpXG5FeCgpLnRlc3Rfb2JqZWN0KFwidGVzdFwiKVxuRXgoKS50ZXN0X29iamVjdChcInhfdHJhaW5cIilcbkV4KCkudGVzdF9vYmplY3QoXCJ5X3RyYWluXCIpXG5FeCgpLnRlc3Rfb2JqZWN0KFwieF90ZXN0XCIpXG5FeCgpLnRlc3Rfb2JqZWN0KFwieV90ZXN0XCIpIn0=

Elegir métrica de error y modelo

La métrica que usarás para evaluar la precisión del modelo es el error absoluto medio (MAE). Mide cuán cerca están las predicciones de los resultados reales. En este caso, te da el valor medio absoluto en que tu predicción se ha desviado.

Es decir, si de media fallas por 5 victorias, la métrica valdrá 5.

El primer modelo será una regresión lineal. Importa LinearRegression y mean_absolute_error desde sklearn.linear_model y sklearn.metrics, respectivamente, crea el modelo lr, ajústalo, predice y calcula el MAE.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZnJvbSBza2xlYXJuLmNsdXN0ZXIgaW1wb3J0IEtNZWFuc1xuZGZfdGVhbXMgPSBwZC5yZWFkX2NzdihcImh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9hc3NldHMuZGF0YWNhbXAuY29tL2Jsb2dfYXNzZXRzL2RmX3RlYW1zX3dob2xlLmNzdlwiLCBoZWFkZXI9MClcbmRmID0gcGQuRGF0YUZyYW1lKGRmX3RlYW1zKVxuYXR0cmlidXRlcyA9IFsnRycsJ1InLCdBQicsJ0gnLCcyQicsJzNCJywnSFInLCdCQicsJ1NPJywnU0InLCdSQScsJ0VSJywnRVJBJywnQ0cnLFxuJ1NITycsJ1NWJywnSVBvdXRzJywnSEEnLCdIUkEnLCdCQkEnLCdTT0EnLCdFJywnRFAnLCdGUCcsJ2VyYV8xJywnZXJhXzInLCdlcmFfMycsJ2VyYV80JywnZXJhXzUnLCdlcmFfNicsJ2VyYV83JywnZXJhXzgnLCdkZWNhZGVfMTkxMCcsJ2RlY2FkZV8xOTIwJywnZGVjYWRlXzE5MzAnLCdkZWNhZGVfMTk0MCcsJ2RlY2FkZV8xOTUwJywnZGVjYWRlXzE5NjAnLCdkZWNhZGVfMTk3MCcsJ2RlY2FkZV8xOTgwJywnZGVjYWRlXzE5OTAnLCdkZWNhZGVfMjAwMCcsJ2RlY2FkZV8yMDEwJywnUl9wZXJfZ2FtZScsJ1JBX3Blcl9nYW1lJywnbWxiX3JwZyddXG5kYXRhX2F0dHJpYnV0ZXMgPSBkZlthdHRyaWJ1dGVzXVxua21lYW5zX21vZGVsID0gS01lYW5zKG5fY2x1c3RlcnM9NiwgcmFuZG9tX3N0YXRlPTEpXG5kaXN0YW5jZXMgPSBrbWVhbnNfbW9kZWwuZml0X3RyYW5zZm9ybShkYXRhX2F0dHJpYnV0ZXMpXG5sYWJlbHMgPSBrbWVhbnNfbW9kZWwubGFiZWxzX1xuZGZbJ2xhYmVscyddID0gbGFiZWxzXG5hdHRyaWJ1dGVzLmFwcGVuZCgnbGFiZWxzJylcbm51bWVyaWNfY29scyA9IFsnRycsJ1InLCdBQicsJ0gnLCcyQicsJzNCJywnSFInLCdCQicsJ1NPJywnU0InLCdSQScsJ0VSJywnRVJBJywnQ0cnLCdTSE8nLCdTVicsJ0lQb3V0cycsJ0hBJywnSFJBJywnQkJBJywnU09BJywnRScsJ0RQJywnRlAnLCdlcmFfMScsJ2VyYV8yJywnZXJhXzMnLCdlcmFfNCcsJ2VyYV81JywnZXJhXzYnLCdlcmFfNycsJ2VyYV84JywnZGVjYWRlXzE5MTAnLCdkZWNhZGVfMTkyMCcsJ2RlY2FkZV8xOTMwJywnZGVjYWRlXzE5NDAnLCdkZWNhZGVfMTk1MCcsJ2RlY2FkZV8xOTYwJywnZGVjYWRlXzE5NzAnLCdkZWNhZGVfMTk4MCcsJ2RlY2FkZV8xOTkwJywnZGVjYWRlXzIwMDAnLCdkZWNhZGVfMjAxMCcsJ1JfcGVyX2dhbWUnLCdSQV9wZXJfZ2FtZScsJ21sYl9ycGcnLCdsYWJlbHMnLCdXJ11cbmRhdGEgPSBkZltudW1lcmljX2NvbHNdXG50cmFpbiA9IGRhdGEuc2FtcGxlKGZyYWM9MC43NSwgcmFuZG9tX3N0YXRlPTEpXG50ZXN0ID0gZGF0YS5sb2NbfmRhdGEuaW5kZXguaXNpbih0cmFpbi5pbmRleCldXG54X3RyYWluID0gdHJhaW5bYXR0cmlidXRlc11cbnlfdHJhaW4gPSB0cmFpblsnVyddXG54X3Rlc3QgPSB0ZXN0W2F0dHJpYnV0ZXNdXG55X3Rlc3QgPSB0ZXN0WydXJ10iLCJzYW1wbGUiOiIjIEltcG9ydCBgTGluZWFyUmVncmVzc2lvbmAgZnJvbSBgc2tsZWFybi5saW5lYXJfbW9kZWxgXG5mcm9tIHNrbGVhcm4ubGluZWFyX21vZGVsIGltcG9ydCBfX19fX19fX19fX19fX19fX19fXG5cbiMgSW1wb3J0IGBtZWFuX2Fic29sdXRlX2Vycm9yYCBmcm9tIGBza2xlYXJuLm1ldHJpY3NgXG5mcm9tIHNrbGVhcm4ubWV0cmljcyBpbXBvcnQgbWVhbl9hYnNvbHV0ZV9lcnJvclxuXG4jIENyZWF0ZSBMaW5lYXIgUmVncmVzc2lvbiBtb2RlbCwgZml0IG1vZGVsLCBhbmQgbWFrZSBwcmVkaWN0aW9uc1xubHIgPSBMaW5lYXJSZWdyZXNzaW9uKG5vcm1hbGl6ZT1UcnVlKVxubHIuZml0KHhfdHJhaW4sIHlfdHJhaW4pXG5wcmVkaWN0aW9ucyA9IGxyLnByZWRpY3QoeF90ZXN0KVxuXG4jIERldGVybWluZSBtZWFuIGFic29sdXRlIGVycm9yXG5tYWUgPSBtZWFuX2Fic29sdXRlX2Vycm9yKHlfdGVzdCwgcHJlZGljdGlvbnMpXG5cbiMgUHJpbnQgYG1hZWBcbnByaW50KF9fXykiLCJzb2x1dGlvbiI6IiMgSW1wb3J0IGBMaW5lYXJSZWdyZXNzaW9uYCBmcm9tIGBza2xlYXJuLmxpbmVhcl9tb2RlbGBcbmZyb20gc2tsZWFybi5saW5lYXJfbW9kZWwgaW1wb3J0IExpbmVhclJlZ3Jlc3Npb25cblxuIyBJbXBvcnQgYG1lYW5fYWJzb2x1dGVfZXJyb3JgIGZyb20gYHNrbGVhcm4ubWV0cmljc2BcbmZyb20gc2tsZWFybi5tZXRyaWNzIGltcG9ydCBtZWFuX2Fic29sdXRlX2Vycm9yXG5cbiMgQ3JlYXRlIExpbmVhciBSZWdyZXNzaW9uIG1vZGVsLCBmaXQgbW9kZWwsIGFuZCBtYWtlIHByZWRpY3Rpb25zXG5sciA9IExpbmVhclJlZ3Jlc3Npb25obm9ybWFsaXplPVRydWUpXG5sci5maXQoeF90cmFpbiwgeV90cmFpbilcbnByZWRpY3Rpb25zID0gbHIucHJlZGljdCh4X3Rlc3QpXG5cbiMgRGV0ZXJtaW5lIG1lYW4gYWJzb2x1dGUgZXJyb3Jcbm1hZSA9IG1lYW5fYWJzb2x1dGVfZXJyb3IoeV90ZXN0LCBwcmVkaWN0aW9ucylcblxuIyBQcmludCBgbWFlYFxucHJpbnQobWFlKSIsInNjdCI6IkV4KCkudGVzdF9pbXBvcnQoXCJza2xlYXJuLmxpbmVhcl9tb2RlbC5MaW5lYXJSZWdyZXNzaW9uXCIpXG5FeCgpLnRlc3RfaW1wb3J0KFwic2tsZWFybi5tZXRyaWNzLm1lYW5fYWJzb2x1dGVfZXJyb3JcIilcbkV4KCkudGVzdF9mdW5jdGlvbihcImxyLmZpdFwiKVxuRXgoKS50ZXN0X29iamVjdChcInByZWRpY3Rpb25zXCIpXG5FeCgpLnRlc3Rfb2JqZWN0KFwibWFlXCIpXG5FeCgpLnRlc3RfZnVuY3Rpb24oXCJwcmludFwiKSJ9

Si recuerdas, la media de victorias era de unas 79. De media, el modelo falla por 2,687 victorias.

Ahora prueba un modelo de regresión Ridge. Importa RidgeCV desde sklearn.linear_model y crea el modelo rrm. El modelo RidgeCV permite fijar el parámetro alpha, un parámetro de complejidad que controla la cantidad de contracción (lee más aquí). El modelo usará validación cruzada para determinar cuál de los parámetros alpha que proporciones es el ideal.

De nuevo, ajusta el modelo, haz predicciones y calcula el error absoluto medio.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IHBhbmRhcyBhcyBwZFxuZnJvbSBza2xlYXJuLmNsdXN0ZXIgaW1wb3J0IEtNZWFuc1xuZnJvbSBza2xlYXJuLm1ldHJpY3MgaW1wb3J0IG1lYW5fYWJzb2x1dGVfZXJyb3JcbmRmX3RlYW1zID0gcGQucmVhZF9jc3YoXCJodHRwczovL3MzLmFtYXpvbmF3cy5jb20vYXNzZXRzLmRhdGFjYW1wLmNvbS9ibG9nX2Fzc2V0cy9kZl90ZWFtc193aG9sZS5jc3ZcIiwgaGVhZGVyPTApXG5kZiA9IHBkLkRhdGFGcmFtZShkZl90ZWFtcylcbmF0dHJpYnV0ZXMgPSBbJ0cnLCdSJywnQUInLCdIJywnMkInLCczQicsJ0hSJywnQkInLCdTTycsJ1NCJywnUkEnLCdFUicsJ0VSQScsJ0NHJyxcbidTSE8nLCdTVicsJ0lQb3V0cycsJ0hBJywnSFJBJywnQkJBJywnU09BJywnRScsJ0RQJywnRlAnLCdlcmFfMScsJ2VyYV8yJywnZXJhXzMnLCdlcmFfNCcsJ2VyYV81JywnZXJhXzYnLCdlcmFfNycsJ2VyYV84JywnZGVjYWRlXzE5MTAnLCdkZWNhZGVfMTkyMCcsJ2RlY2FkZV8xOTMwJywnZGVjYWRlXzE5NDAnLCdkZWNhZGVfMTk1MCcsJ2RlY2FkZV8xOTYwJywnZGVjYWRlXzE5NzAnLCdkZWNhZGVfMTk4MCcsJ2RlY2FkZV8xOTkwJywnZGVjYWRlXzIwMDAnLCdkZWNhZGVfMjAxMCcsJ1JfcGVyX2dhbWUnLCdSQV9wZXJfZ2FtZScsJ21sYl9ycGcnXVxuZGF0YV9hdHRyaWJ1dGVzID0gZGZbYXR0cmlidXRlc11cbmttZWFuc19tb2RlbCA9IEtNZWFucyhuX2NsdXN0ZXJzPTYsIHJhbmRvbV9zdGF0ZT0xKVxuZGlzdGFuY2VzID0ga21lYW5zX21vZGVsLmZpdF90cmFuc2Zvcm0oZGF0YV9hdHRyaWJ1dGVzKVxubGFiZWxzID0ga21lYW5zX21vZGVsLmxhYmVsc19cbmRmWydsYWJlbHMnXSA9IGxhYmVsc1xuYXR0cmlidXRlcy5hcHBlbmQoJ2xhYmVscycpXG5udW1lcmljX2NvbHMgPSBbJ0cnLCdSJywnQUInLCdIJywnMkInLCczQicsJ0hSJywnQkInLCdTTycsJ1NCJywnUkEnLCdFUicsJ0VSQScsJ0NHJywnU0hPJywnU1YnLCdJUG91dHMnLCdIQScsJ0hSQScsJ0JCQScsJ1NPQScsJ0UnLCdEUCcsJ0ZQJywnZXJhXzEnLCdlcmFfMicsJ2VyYV8zJywnZXJhXzQnLCdlcmFfNScsJ2VyYV82JywnZXJhXzcnLCdlcmFfOCcsJ2RlY2FkZV8xOTEwJywnZGVjYWRlXzE5MjAnLCdkZWNhZGVfMTkzMCcsJ2RlY2FkZV8xOTQwJywnZGVjYWRlXzE5NTAnLCdkZWNhZGVfMTk2MCcsJ2RlY2FkZV8xOTcwJywnZGVjYWRlXzE5ODAnLCdkZWNhZGVfMTk5MCcsJ2RlY2FkZV8yMDAwJywnZGVjYWRlXzIwMTAnLCdSX3Blcl9nYW1lJywnUkFfcGVyX2dhbWUnLCdtbGJfcnBnJywnbGFiZWxzJywnVyddXG5kYXRhID0gZGZbbnVtZXJpY19jb2xzXVxudHJhaW4gPSBkYXRhLnNhbXBsZShmcmFjPTAuNzUsIHJhbmRvbV9zdGF0ZT0xKVxudGVzdCA9IGRhdGEubG9jW35kYXRhLmluZGV4LmlzaW4odHJhaW4uaW5kZXgpXVxueF90cmFpbiA9IHRyYWluW2F0dHJpYnV0ZXNdXG55X3RyYWluID0gdHJhaW5bJ1cnXVxueF90ZXN0ID0gdGVzdFthdHRyaWJ1dGVzXVxueV90ZXN0ID0gdGVzdFsnVyddIiwic2FtcGxlIjoiIyBJbXBvcnQgYFJpZGdlQ1ZgIGZyb20gYHNrbGVhcm4ubGluZWFyX21vZGVsYFxuZnJvbSBza2xlYXJuLmxpbmVhcl9tb2RlbCBpbXBvcnQgX19fX19fX1xuXG4jIENyZWF0ZSBSaWRnZSBMaW5lYXIgUmVncmVzc2lvbiBtb2RlbCwgZml0IG1vZGVsLCBhbmQgbWFrZSBwcmVkaWN0aW9uc1xucnJtID0gUmlkZ2VDVihhbHBoYXM9KDAuMDEsIDAuMSwgMS4wLCAxMC4wKSwgbm9ybWFsaXplPVRydWUpXG5ycm0uZml0KHhfdHJhaW4sIHlfdHJhaW4pXG5wcmVkaWN0aW9uc19ycm0gPSBycm0ucHJlZGljdCh4X3Rlc3QpXG5cbiMgRGV0ZXJtaW5lIG1lYW4gYWJzb2x1dGUgZXJyb3Jcbm1hZV9ycm0gPSBtZWFuX2Fic29sdXRlX2Vycm9yKHlfdGVzdCwgcHJlZGljdGlvbnNfcnJtKVxucHJpbnQoX19fX19fX18pIiwic29sdXRpb24iOiIjIEltcG9ydCBgUmlkZ2VDVmAgZnJvbSBgc2tsZWFybi5saW5lYXJfbW9kZWxgXG5mcm9tIHNrbGVhcm4ubGluZWFyX21vZGVsIGltcG9ydCBSaWRnZUNWXG5cbiMgQ3JlYXRlIFJpZGdlIExpbmVhciBSZWdyZXNzaW9uIG1vZGVsLCBmaXQgbW9kZWwsIGFuZCBtYWtlIHByZWRpY3Rpb25zXG5ycm0gPSBSaWRnZUNWKGFscGhhcz0oMC4wMSwgMC4xLCAxLjAsIDEwLjApLCBub3JtYWxpemU9VHJ1ZSlcbnJybS5maXQoeF90cmFpbiwgeV90cmFpbilcbnByZWRpY3Rpb25zX3JybSA9IHJybS5wcmVkaWN0KHhfdGVzdClcblxuIyBEZXRlcm1pbmUgbWVhbiBhYnNvbHV0ZSBlcnJvclxubWFlX3JybSA9IG1lYW5fYWJzb2x1dGVfZXJyb3IoeV90ZXN0LCBwcmVkaWN0aW9uc19ycm0pXG5wcmludChtYWVfcnJtKSIsInNjdCI6IkV4KCkudGVzdF9pbXBvcnQoXCJza2xlYXJuLmxpbmVhcl9tb2RlbC5SaWRnZUNWXCIpXG5FeCgpLnRlc3RfZnVuY3Rpb24oXCJycm0uZml0XCIpXG5FeCgpLnRlc3Rfb2JqZWN0KFwicHJlZGljdGlvbnNfcnJtXCIpXG5FeCgpLnRlc3RfZnVuY3Rpb24oXCJwcmludFwiKSJ9

Este modelo funcionó un poco mejor, con un error medio de 2,673 victorias.

Analítica deportiva y Scikit-Learn

Aquí termina la primera parte de esta serie, donde has visto cómo usar Scikit-Learn para analizar datos deportivos. Importaste datos de una base de datos SQLite, los limpiaste, exploraste visualmente y creaste nuevas características. Aprendiste a crear un modelo de clustering K-means, varios modelos de regresión lineal y a probar tus predicciones con la métrica de error absoluto medio.

En la segunda parte, verás cómo usar modelos de clasificación para predecir qué jugadores entran en el Hall of Fame de la MLB.

Temas
Python
Ciencia de datos
Aprendizaje automático

Cursos de Python

Curso

Introducción a Python

4 h
7M
Domina los fundamentos del análisis de datos con Python en cuatro horas y descubre sus paquetes más usados.
Ver detallesRight Arrow
Iniciar Curso
Ver másRight Arrow
Relacionado
Clustering k-means

Tutorial

Introducción a k-Means Clustering con scikit-learn en Python

En este tutorial, aprenda a aplicar k-Means Clustering con scikit-learn en Python

Kevin Babitz

8 min

Tutorial

Tutorial sobre clasificación bayesiana ingenua con Scikit-learn

Aprende a crear y evaluar un clasificador Naive Bayes utilizando el paquete Scikit-learn de Python.
Abid Ali Awan's photo

Abid Ali Awan

13 min

Tutorial

Tutorial sobre máquinas de vectores de soporte con Scikit-learn

En este tutorial, aprenderás sobre las máquinas de vectores de soporte, uno de los algoritmos de machine learning supervisado más populares y utilizados.
Avinash Navlani's photo

Avinash Navlani

15 min

Tutorial

Tutorial de regresión lineal en R

En este tutorial aprenderás los fundamentos de un modelo estadístico muy popular: la regresión lineal.

Eladio Montero Porras

15 min

Tutorial

Aprendizaje automático de datos categóricos con el tutorial de Python

Aprenda los trucos más comunes para manejar datos categóricos y preprocesarlos para construir modelos de aprendizaje automático.
Moez Ali's photo

Moez Ali

14 min

Tutorial

Tutorial de clasificación mediante árboles de decisión en Python

En este tutorial, aprenderás sobre la clasificación mediante árboles de decisión, las medidas de selección de atributos y cómo crear y optimizar un clasificador de árboles de decisión utilizando el paquete Scikit-learn de Python.
Avinash Navlani's photo

Avinash Navlani

12 min

Ver MásVer Más