Manual básico de Scikit-learn

Introducción a Scikit-learn

Scikit-learn es una de las librerías más populares utilizadas en Python para el aprendizaje automático (machine learning). Fue desarrollada como parte del ecosistema científico de Python y se ha convertido en una herramienta fundamental para investigadores, analistas de datos y desarrolladores que buscan aplicar algoritmos de aprendizaje automático a problemas del mundo real.

¿Qué es Scikit-learn?

Scikit-learn es una librería de código abierto construida sobre otras librerías fundamentales de Python como NumPy, SciPy y matplotlib. Ofrece una amplia gama de herramientas para abordar la resolución de problemas mediante aprendizaje automático y análisis de datos. Incluye algoritmos de clasificación, regresión, clustering (agrupamiento), reducción de dimensionalidad, selección de modelos, y preprocesamiento de datos, tales como:

  1. Clasificación: Asignar etiquetas a datos de entrada.
    • Detección de spam: Clasificar correos electrónicos como spam o no spam.
    • Reconocimiento de imágenes: Identificar objetos en imágenes (por ejemplo, reconocimiento facial).
    • Diagnóstico médico: Clasificar si un paciente tiene o no una enfermedad basada en datos clínicos.
  2. Regresión: Predecir valores continuos.
    • Predicción de precios: Estimar el precio de viviendas en base a características como el tamaño y la ubicación.
    • Análisis de ventas: Predecir las ventas futuras basadas en datos históricos.
  3. Clustering (agrupamiento): Agrupar datos en categorías no etiquetadas.
    • Segmentación de clientes: Agrupar clientes en segmentos basados en su comportamiento de compra.
    • Compresión de datos: Reducción de la dimensionalidad de los datos para visualizar conjuntos complejos.
  4. Reducción de dimensionalidad: Reducir el número de características en un conjunto de datos para facilitar la visualización o mejorar la eficiencia de otros algoritmos.
    • Análisis de Componentes Principales (PCA): Simplificar datos de alta dimensión para exploración visual.
  5. Selección de modelos y optimización: Elegir el mejor modelo y ajustar los hiperparámetros para mejorar el rendimiento.

¿Por qué Scikit-learn es tan popular?

Scikit-learn es muy popular por varias razones que lo convierten en una herramienta esencial para cualquier persona involucrada en el análisis de datos o el desarrollo de modelos predictivos:

  1. Accesibilidad y simplicidad: Una de las principales ventajas de scikit-learn es su simplicidad, incluso para aquellos que son nuevos en el campo del aprendizaje automático. Gracias a su API consistente, es fácil aprender a usar un algoritmo y luego aplicar los conocimientos a otros sin necesidad de aprender nuevas sintaxis complejas.
  2. Versatilidad y flexibilidad: Puede utilizarse en la resolución de una amplia gama de problemas, desde algunos muy simples hasta otros extremadamente complejos. Esto hace que scikit-learn sea adecuado para aplicaciones en diversos campos, como la medicina, finanzas, marketing, y tecnología, entre otros.
  3. Eficiencia y rapidez: Scikit-learn está altamente optimizado para funcionar con grandes volúmenes de datos y realizar cálculos complejos rápidamente, lo que es crucial en entornos empresariales donde el tiempo es esencial.
  4. Facilita la experimentación y prototipado rápido: Scikit-learn permite a los usuarios probar rápidamente diferentes algoritmos y técnicas, ver sus resultados y ajustar modelos sin necesidad de un conocimiento profundo de la matemática detrás de cada algoritmo. Esto acelera el proceso de descubrimiento y la innovación.
  5. Compatibilidad con entornos de producción: Los modelos desarrollados con scikit-learn se pueden integrar fácilmente en aplicaciones en producción, lo que permite trasladar las ideas y prototipos desde el laboratorio de datos hasta el uso real en aplicaciones y servicios.
  6. Aprendizaje reforzado por la comunidad: La comunidad de scikit-learn no solo proporciona soporte continuo, sino que también contribuye con mejoras regulares, manteniendo la librería actualizada con las últimas investigaciones y avances en el campo del aprendizaje automático.
  7. Integración con herramientas de visualización: Aunque no es una librería de visualización, scikit-learn se integra bien con matplotlib y otras herramientas para crear gráficos que ayudan a interpretar los resultados de los modelos, lo cual es clave para la toma de decisiones basada en datos.

¿Qué nos aporta Scikit-learn?

  1. Amplia gama de algoritmos y funcionalidades: Incluye desde algoritmos básicos como la regresión lineal hasta técnicas avanzadas como bosques aleatorios y métodos de boosting, lo que permite abordar prácticamente cualquier problema con una sola librería.
  2. Preprocesamiento de datos: Herramientas para la limpieza, normalización, escalado y transformación de datos, permitiendo preparar los datos para el modelado de manera sencilla.
  3. Algoritmos específicos de aprendizaje automático: Scikit-learn incluye una gran variedad de algoritmos para tareas de clasificación, regresión y clustering, como Regresión Lineal, Máquinas de Soporte Vectorial (SVM), K-Means, Bosques Aleatorios, y muchos más.
  4. Interoperabilidad con el ecosistema de python: Scikit-learn se integra perfectamente con otras librerías como pandas (para manipulación de datos), NumPy (para cálculos numéricos), y matplotlib (para visualización de datos). Esto facilita la creación de flujos de trabajo completos y simplifica el desarrollo y la implementación de modelos.
  5. Evaluación y mejora continua: Ofrece herramientas robustas para evaluar la precisión y la validez de los modelos mediante métodos como la validación cruzada, matrices de confusión, y métricas de clasificación como precisión, recall y F1-score.
  6. Optimización de modelos: Herramientas como Grid Search y Random Search permiten ajustar los hiperparámetros de los modelos de manera efectiva, mejorando la precisión y el rendimiento del modelo sin necesidad de realizar ajustes manuales tediosos.
  7. Interfaz consistente: Todos los algoritmos comparten una interfaz coherente y simple, lo que facilita cambiar entre diferentes modelos con muy poco esfuerzo.
  8. Documentación actualizada: Scikit-learn cuenta con una documentación extensa, clara y llena de ejemplos prácticos. Además, tiene una gran comunidad de usuarios y desarrolladores, lo que facilita encontrar ayuda, tutoriales y soluciones a problemas comunes.

Instalación de Scikit-learn

Podemos instalar scikit-learn fácilmente utilizando el gestor de paquetes pip, que viene instalado con Python. Basta con abrir el terminal (o símbolo del sistema en Windows) y escribir el siguiente comando para instalar scikit-learn junto con sus dependencias:

pip install scikit-learn

Importar y comenzar a usar Scikit-learn

Scikit-learn se usa a través de sus módulos específicos, que se importan según las necesidades específicas de cada proyecto. Algunas de las funcionalidades más comunes son las siguientes:

  • Preprocesamiento de datos: Para escalar, normalizar y transformar datos.
  • Modelos de aprendizaje supervisado: Para tareas de regresión y clasificación.
  • Modelos de aprendizaje no supervisado: Para clustering y reducción de dimensionalidad.

Ejemplo de importación

# Importar módulos de preprocesamiento
from sklearn.preprocessing import StandardScaler, LabelEncoder

# Importar modelos de aprendizaje supervisado
from sklearn.linear_model import LinearRegression
from sklearn.svm import SVC

# Importar modelos de aprendizaje no supervisado
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA

# Importar funciones de evaluación
from sklearn.metrics import accuracy_score, confusion_matrix

Jupyter Notebook y Google Colab

Para una experiencia más interactiva y visual, se pueden usar entornos como Jupyter Notebook o Google Colab:

  • Google Colab: Es un entorno basado en web que no requiere instalación y ofrece GPU gratuita para acelerar el entrenamiento de modelos. Puedes acceder a él a través de Google Colab.
  • Jupyter Notebook: Puedes instalarlo con pip usando pip install jupyterlab y luego ejecutarlo con el comando jupyter notebook. Es ideal para experimentar con código y visualizar resultados en tiempo real.

Fundamentos de Scikit-learn

Scikit-learn facilita el trabajo con modelos predictivos y de aprendizaje automático proporcionando una serie de herramientas para:

  1. Cargar y preparar datos: scikit-learn no tiene herramientas propias para la carga de datos desde archivos como CSV, Excel o bases de datos, pero se complementa perfectamente con otras librerías como pandas y numpy que permiten manipular datos fácilmente. Por lo tanto, uno de los primeros pasos en cualquier proyecto de machine learning es cargar los datos con pandas.
  2. Preprocesamiento de datos: Este es un paso esencial. Los datos crudos generalmente no están listos para usarse en un modelo. Pueden tener valores faltantes, variables categóricas que necesitan ser convertidas en números, o los datos pueden necesitar ser escalados para mejorar la precisión del modelo. Scikit-learn tiene una variedad de transformadores para realizar estos ajustes.
  3. Entrenamiento de modelos: Una vez los datos están listos, puedes entrenar un modelo. Esto implica usar un algoritmo de aprendizaje automático para ajustar el modelo a tus datos. Algunos ejemplos de algoritmos son la regresión lineal para predicción de valores numéricos y las máquinas de soporte vectorial (SVM) para clasificación.
  4. Evaluación de modelos: Después de entrenar un modelo, es fundamental medir su rendimiento. Scikit-learn proporciona diversas métricas para evaluar la precisión, como la matriz de confusión, precisión, recall, entre otras.
  5. Predicciones: Finalmente, puedes usar tu modelo entrenado para hacer predicciones sobre nuevos datos que no se usaron durante el entrenamiento. Esto es útil en aplicaciones como predicciones de ventas, clasificación de correos como spam o no spam, etc.

Preprocesamiento de datos

El preprocesamiento de datos consiste en preparar tus datos para que un modelo de aprendizaje automático los pueda usar correctamente. Esto incluye tareas como escalar los datos (ajustar la escala de las variables para que tengan la misma importancia), transformar datos categóricos en numéricos, o vectorizar texto.

Ejemplo básico: Escalar datos numéricos

Imagina que tienes un conjunto de datos con varias características numéricas, pero estas están en diferentes rangos. Por ejemplo, una columna puede tener valores entre 0 y 1000, mientras que otra tiene valores entre 0 y 1. Esto puede confundir a muchos modelos de aprendizaje automático porque algunas características parecen tener más peso simplemente porque sus números son más grandes. Para evitar esto, se utilizan técnicas de escalado.

En el ejemplo que se muestra a continuación, usamos StandardScaler de scikit-learn para estandarizar los datos de modo que tengan una media de 0 y una desviación estándar de 1:

from sklearn.preprocessing import StandardScaler
import numpy as np

# Datos de ejemplo: una matriz con tres filas y tres columnas
X = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# Crear el escalador
scaler = StandardScaler()

# Ajustar (fit) el escalador y transformar (transform) los datos
X_scaled = scaler.fit_transform(X)

print(X_scaled)

Explicación del código:

  1. StandardScaler() crea un objeto escalador que se usará para ajustar y transformar los datos.
  2. fit_transform(X) ajusta el escalador a los datos y luego transforma esos datos, es decir, calcula la media y desviación estándar de cada columna y luego aplica la transformación para escalar los valores.

El escalado de datos es particularmente útil en algoritmos como regresión lineal, SVM y redes neuronales, donde los valores numéricos deben estar en un rango similar para un mejor rendimiento.

Algoritmos de aprendizaje supervisado

Los algoritmos de aprendizaje supervisado son aquellos que aprenden a partir de datos etiquetados, es decir, datos en los que sabemos cuál es la salida correcta (etiqueta). Uno de los algoritmos más simples es la regresión lineal, que predice un valor numérico basado en las características de entrada.

Ejemplo: Regresión lineal

La regresión lineal trata de ajustar una línea recta (o un plano en dimensiones superiores) que describa la relación entre las variables independientes (X) y la variable dependiente (Y).

from sklearn.linear_model import LinearRegression
import numpy as np

# Datos de ejemplo: X son las variables independientes (entrada) y y es la variable dependiente (salida)
X = np.array([[1], [2], [3], [4]])  # Cada número es una característica, en este caso un solo valor por observación
y = np.array([3, 6, 9, 12])  # Resultados que queremos aprender a predecir

# Crear el modelo de regresión lineal
model = LinearRegression()

# Entrenar el modelo con los datos
model.fit(X, y)

# Predecir un nuevo valor con el modelo entrenado
prediction = model.predict([[5]])
print(prediction)  # Salida esperada: [15]

Explicación del código:

  1. LinearRegression() crea un modelo de regresión lineal.
  2. model.fit(X, y) entrena el modelo con los datos de entrada X y los resultados conocidos y.
  3. model.predict([[5]]) usa el modelo entrenado para predecir el resultado cuando X = 5.

Este ejemplo muestra un caso simple, pero la regresión lineal se usa ampliamente en aplicaciones como la predicción de ventas, la valoración de bienes inmuebles o incluso en la ciencia para encontrar relaciones entre variables.

Aplicación real: Predicción de precios de casas

Imaginemos que tenemos un conjunto de datos de casas con características como el tamaño, número de habitaciones, etc., y queremos predecir el precio de una casa nueva basada en esas características. Para mejorar la precisión, primero escalamos los datos usando StandardScaler.

from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
import pandas as pd

# Supongamos que tenemos un archivo CSV con datos sobre casas
data = pd.read_csv('casas.csv')
X = data.drop('Precio', axis=1)  # Variables independientes (tamaño, habitaciones, etc.)
y = data['Precio']  # Variable dependiente (precio)

# Escalar los datos
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# Crear y entrenar el modelo
model = LinearRegression()
model.fit(X_scaled, y)

# Predecir el precio de una casa nueva con características específicas
nueva_casa = [[200, 3, 2, 1]]  # Tamaño de 200 m², 3 habitaciones, 2 baños, 1 garaje
nueva_casa_scaled = scaler.transform(nueva_casa)
precio_predicho = model.predict(nueva_casa_scaled)

print(precio_predicho)

Explicación del código:

  1. data = pd.read_csv('casas.csv'): Carga los datos desde un archivo CSV.
  2. X = data.drop('Precio', axis=1) y y = data['Precio']: Separa las características (X) del valor que queremos predecir (y).
  3. scaler.fit_transform(X): Escala los datos para que todas las características estén en un rango similar.
  4. model.fit(X_scaled, y): Entrena el modelo usando los datos escalados.
  5. model.predict(): Usa el modelo entrenado para hacer una predicción.

Aprendizaje supervisado para clasificación

La clasificación es otra tarea importante del aprendizaje supervisado, donde el objetivo es asignar etiquetas a datos de entrada. Un ejemplo clásico es clasificar correos electrónicos como spam o no spam.

Ejemplo: Clasificación de texto (spam vs no spam)

Este ejemplo muestra cómo usar TfidfVectorizer para convertir texto en datos numéricos y SVC (máquinas de soporte vectorial) para entrenar un modelo de clasificación.

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.svm import SVC
from sklearn.pipeline import make_pipeline
import pandas as pd

# Datos de ejemplo con textos y etiquetas (1 para spam, 0 para no spam)
data = pd.DataFrame({
    'texto': ['Hola, ¿cómo estás?', 'Gana dinero rápido', 'Te extrañamos', 'Oferta exclusiva para ti'],
    'spam': [0, 1, 0, 1]
})

# Crear un pipeline con TfidfVectorizer (para vectorizar texto) y SVC (para clasificar)
model = make_pipeline(TfidfVectorizer(), SVC(probability=True))

# Entrenar el modelo con los datos
model.fit(data['texto'], data['spam'])

# Predecir si un nuevo mensaje es spam
nuevo_mensaje = '¡Oferta exclusiva para ganar dinero!'
probabilidad = model.predict_proba([nuevo_mensaje])[0][1] * 100
print(f'Probabilidad de spam: {probabilidad}%')

Explicación del código:

  1. TfidfVectorizer() convierte texto en una representación numérica que el modelo puede usar. Calcula una medida llamada «TF-IDF» que refleja la importancia de las palabras en el texto.
  2. SVC() es un modelo de clasificación que aprende a separar las clases (spam y no spam) a partir de los datos de entrenamiento.
  3. make_pipeline() crea un flujo de trabajo que primero vectoriza el texto y luego aplica el modelo de clasificación.

Aprendizaje no supervisado

En el aprendizaje no supervisado, los modelos tratan de encontrar patrones en datos que no tienen etiquetas conocidas. Un algoritmo común es k-Nearest Neighbors (k-NN), que puede usarse para sugerir recetas basadas en ingredientes disponibles.

Ejemplo: k-Nearest Neighbors (k-NN) para sugerir recetas

El siguiente ejemplo muestra cómo usar k-NN para sugerir recetas similares basadas en los ingredientes proporcionados.

from sklearn.neighbors import NearestNeighbors
from sklearn.preprocessing import MultiLabelBinarizer
import pandas as pd

# Datos de ejemplo: lista de recetas y sus ingredientes
data = pd.DataFrame({
    'receta': ['Pasta con tomate', 'Ensalada de pollo', 'Tacos de pescado'],
    'ingredientes': ['pasta,tomate', 'lechuga,pollo', 'pescado,tortilla']
})

# Convertir los ingredientes en una representación binaria
mlb = MultiLabelBinarizer()
X = mlb.fit_transform(data['ingredientes'].apply(lambda x: x.split(',')))

# Crear y entrenar el modelo k-NN
model = NearestNeighbors(n_neighbors=2, metric='jaccard')
model.fit(X)

# Sugerir recetas basadas en los ingredientes proporcionados
ingredientes = ['tomate', 'pasta']
ingredientes_vector = mlb.transform([ingredientes])
distancias, indices = model.kneighbors(ingredientes_vector, n_neighbors=2)

# Mostrar recetas sugeridas
for idx in indices[0]:
    print(data.iloc[idx]['receta'])

Explicación del código:

  1. MultiLabelBinarizer() convierte listas de ingredientes en vectores binarios donde cada posición indica si un ingrediente está presente.
  2. NearestNeighbors() encuentra las recetas más cercanas a las dadas basándose en la similitud de ingredientes.
  3. kneighbors() busca las recetas más cercanas (vecinas) a los ingredientes proporcionados.

Uso de modelos de clasificación en aplicaciones más específicas

Los modelos de clasificación intentan predecir una etiqueta o clase para cada observación en los datos. Este tipo de problemas es común en una gran variedad de aplicaciones en campos más específicos. A través de los pasos de preparación de datos, preprocesamiento, entrenamiento y predicción, scikit-learn nos facilita el desarrollo de modelos que pueden ser usados en aplicaciones del mundo real, tales como:

  • Diagnóstico médico: Determinar si un paciente tiene una enfermedad en base a sus síntomas y análisis médicos.
  • Finanzas: Predecir si un cliente cumple las condiciones adecuadas para aprobar la concesión de un crédito.
  • Crowdfunding: Predecir si una campaña tendrá éxito en base a sus características.

A continuación vamos a detallar un ejemplo donde intentaremos predecir el éxito de campañas de crowdfunding. Así mostraremos cómo se puede utilizar un modelo de clasificación para resolver un problema práctico más concreto y específico.

Ejemplo: Predicción de éxito en campañas de crowdfunding

Contexto del problema: Imagina que tienes datos históricos de campañas de crowdfunding. Cada campaña tiene varias características (como la categoría del proyecto, el monto recaudado, la meta financiera, la duración de la campaña, etc.). El objetivo es entrenar un modelo que pueda predecir si una campaña tendrá éxito o no.

Paso 1: Preparación de los datos

El primer paso en cualquier problema de clasificación es preparar los datos de entrenamiento:

# Importar las bibliotecas necesarias
from sklearn.ensemble import RandomForestClassifier
import pandas as pd

# Supongamos que tenemos datos de campañas de crowdfunding
# Cada fila representa una campaña con sus características y si tuvo éxito (1) o no (0)
data = pd.DataFrame({
    'Categoría': ['Tecnología', 'Arte', 'Música'],
    'Meta Financiera': [5000, 3000, 8000],
    'Dinero Recaudado': [4000, 3500, 2000],
    'Duración (días)': [30, 40, 25],
    'Número de Patrocinadores': [20, 30, 10],
    'Éxito': [1, 1, 0]  # 1 indica que la campaña tuvo éxito, 0 indica que no tuvo éxito
})

# Mostrar los datos de ejemplo
print(data)

Explicación de los datos:

  • Categoría: La categoría a la que pertenece la campaña, como Tecnología, Arte o Música.
  • Meta Financiera: La cantidad de dinero que se espera recaudar.
  • Dinero Recaudado: El dinero que efectivamente se recaudó.
  • Duración (días): Los días que duró la campaña.
  • Número de Patrocinadores: El número de personas que contribuyeron a la campaña.
  • Éxito: Etiqueta que indica si la campaña tuvo éxito (1) o no (0).

Paso 2: Preprocesamiento de los datos

Antes de entrenar un modelo, necesitamos transformar las variables categóricas (en este caso, la categoría del proyecto) en un formato que los modelos puedan entender. Para esto, usamos get_dummies() que convierte las categorías en variables numéricas llamadas variables dummy:

# Convertir la variable categórica 'Categoría' en variables dummy
data = pd.get_dummies(data, columns=['Categoría'])

# Separar las características (X) y la variable objetivo (y)
X = data.drop('Éxito', axis=1)  # Características de entrada
y = data['Éxito']  # Variable de salida que queremos predecir

# Mostrar las nuevas características después de la transformación
print(X)

Explicación del preprocesamiento:

  • get_dummies() crea nuevas columnas para cada categoría. Por ejemplo, si la categoría es «Tecnología», se crea una columna Categoría_Tecnología con valores 1 (si es de esa categoría) o 0 (si no lo es).
  • X contiene las características que usaremos para predecir y y contiene las etiquetas de éxito (1) o fracaso (0).

Paso 3: Entrenamiento del modelo

En este ejemplo, usaremos un Random Forest Classifier (clasificador de bosque aleatorio), que es un modelo potente y versátil. Este algoritmo combina muchos árboles de decisión para mejorar la precisión y reducir el riesgo de sobreajuste.

# Crear y entrenar el modelo de bosque aleatorio
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X, y)  # Entrenar el modelo con las características X y la variable objetivo y

Explicación del modelo:

  • RandomForestClassifier(n_estimators=100) crea un modelo de bosque aleatorio con 100 árboles de decisión. Cuantos más árboles, más robusto es el modelo, pero también se necesitará más tiempo para completar el entrenamiento.
  • model.fit(X, y) ajusta (entrena) el modelo a los datos, encontrando patrones que relacionan las características con la etiqueta de éxito o fracaso.

Paso 4: Predicción de un nuevo proyecto

Una vez que el modelo está entrenado, puedes usarlo para predecir la probabilidad de éxito de nuevas campañas. A continuación, mostramos cómo hacer una predicción para una nueva campaña:

# Crear un nuevo proyecto para predecir
nuevo_proyecto = pd.DataFrame({
    'Meta Financiera': [6000],
    'Dinero Recaudado': [4500],
    'Duración (días)': [35],
    'Número de Patrocinadores': [25],
    'Categoría_Arte': [0],
    'Categoría_Música': [0],
    'Categoría_Tecnología': [1]  # Esta campaña es de Tecnología
})

# Mostrar los datos del nuevo proyecto
print(nuevo_proyecto)

# Predecir la probabilidad de éxito del nuevo proyecto
probabilidad_exito = model.predict_proba(nuevo_proyecto)[0][1] * 100
print(f'Probabilidad de éxito: {probabilidad_exito:.2f}%')

Explicación de la predicción:

  • nuevo_proyecto contiene las características del nuevo proyecto. Observa que debe tener las mismas columnas que las características de entrenamiento (X).
  • model.predict_proba(nuevo_proyecto) devuelve la probabilidad de cada clase (0 o 1). [0][1] selecciona la probabilidad de que el proyecto sea exitoso (1).
  • Multiplicamos por 100 para convertir la probabilidad a un porcentaje.

Análisis de resultados y ajuste del modelo

Después de predecir, es fundamental analizar el rendimiento del modelo y ajustarlo si es necesario:

  1. Métricas de evaluación: Usar métricas como precisión, recall, f1-score, y matriz de confusión para evaluar la calidad de predicción del modelo. En problemas de negocio reales, un alto recall (identificar todas las campañas exitosas) puede ser más importante que la precisión.
  2. Ajuste de hiperparámetros: Experimentar con el número de árboles (n_estimators) o la profundidad máxima de cada árbol (max_depth) para mejorar el rendimiento.
  3. Validación cruzada: Usar técnicas como la validación cruzada para asegurar que el modelo no esté sobreajustado a los datos de entrenamiento y pueda generalizar bien a nuevos datos.

Conclusión

Scikit-learn se ha convertido en una herramienta muy popular y versátil dentro del campo del aprendizaje automático debido a su simplicidad, la amplitud de sus capacidades y su integración con el ecosistema de Python. Es la elección perfecta tanto para principiantes como para expertos que buscan aplicar machine learning de manera efectiva en sus proyectos. Con scikit-learn, es posible abordar problemas complejos de predicción, clasificación y análisis de datos con una curva de aprendizaje moderada, proporcionando resultados precisos y valiosos que facilitan la toma de decisiones en el mundo real.

Manual básico de Matplotlib

Introducción a Matplotlib

¿Qué es Matplotlib?

Matplotlib es una librería de Python utilizada para crear visualizaciones de datos en forma de gráficos 2D. Es altamente versátil y permite generar una amplia gama de gráficos, desde simples gráficos de líneas y barras hasta complejos gráficos de dispersión, histogramas, gráficos de pastel, entre otros. Matplotlib es particularmente popular en campos como ciencia de datos, estadística e ingeniería, ya que ofrece una manera fácil y flexible de representar visualmente datos de manera clara y comprensible. La librería se integra bien con otras herramientas de análisis de datos en Python, como NumPy y Pandas, lo que facilita el análisis y la visualización de grandes conjuntos de datos. Con Matplotlib, los usuarios pueden personalizar cada aspecto de un gráfico, desde los colores y estilos de línea hasta la inclusión de leyendas, títulos y anotaciones, lo que la convierte en una excelente herramienta para crear visualizaciones que representen la información de manera eficaz.

Instalación

Para comenzar a utilizar Matplotlib, necesitas instalar la librería en tu entorno de Python. Esto se hace fácilmente utilizando pip, que es el gestor de paquetes de Python. Este comando descargará e instalará la última versión de Matplotlib y sus dependencias:

pip install matplotlib

Importar Matplotlib

En Python, las librerías se importan para acceder a sus funcionalidades. Para Matplotlib, la parte que se utiliza con mayor frecuencia es pyplot, un módulo que proporciona una interfaz de alto nivel para crear gráficos. Se suele importar con el alias plt para simplificar su uso. De hecho, este alias plt es un estándar de facto y verás que la mayoría de los ejemplos y tutoriales utilizan esta convención:

import matplotlib.pyplot as plt

En entornos donde no se tiene una pantalla (como en servidores web o scripts que generan gráficos sin mostrarlos), se recomienda utilizar matplotlib.use('Agg') para configurar Matplotlib en un backend que no requiere una interfaz gráfica:

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

Creación de gráficos básicos

Gráfico de líneas

Los gráficos de líneas son uno de los tipos de gráficos más comunes y se utilizan para mostrar la relación entre dos variables continuas. Son especialmente útiles para mostrar cómo cambia una variable en función del tiempo u otra métrica continua.

Ejemplo: Ventas a lo largo del año

import matplotlib.pyplot as plt

# Datos
meses = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio']
ventas = [150, 200, 250, 300, 350, 400]

# Crear el gráfico
plt.plot(meses, ventas)

# Añadir títulos y etiquetas
plt.title("Ventas Mensuales")
plt.xlabel("Meses")
plt.ylabel("Ventas en $")

# Mostrar el gráfico
plt.show()

Explicación:

  • plt.plot(meses, ventas) genera una línea que conecta los puntos definidos por las listas meses y ventas.
  • plt.title, plt.xlabel, y plt.ylabel se usan para añadir un título y etiquetas a los ejes.
  • plt.show() muestra el gráfico en la pantalla.

Gráfico de barras

Los gráficos de barras son ideales para comparar diferentes categorías. Cada barra representa una categoría, y su altura o longitud representa la magnitud de la variable asociada a esa categoría.

Ejemplo: Comparación de ventas por producto

productos = ['Producto A', 'Producto B', 'Producto C']
ventas = [300, 450, 150]

plt.bar(productos, ventas)

plt.title("Ventas por Producto")
plt.xlabel("Productos")
plt.ylabel("Ventas en $")

plt.show()

Explicación:

  • plt.bar(productos, ventas) crea un gráfico de barras donde cada barra corresponde a un producto y su altura muestra el volumen de ventas.
  • Este tipo de gráfico es útil para visualizar comparaciones directas entre diferentes elementos.

Gráfico de dispersión

Un gráfico de dispersión es útil cuando deseas visualizar la relación entre dos variables numéricas. Cada punto en el gráfico representa un par de valores.

Ejemplo: Relación entre publicidad y ventas

publicidad = [100, 200, 300, 400, 500]
ventas = [10, 20, 30, 40, 50]

plt.scatter(publicidad, ventas)

plt.title("Relación entre Publicidad y Ventas")
plt.xlabel("Publicidad en $")
plt.ylabel("Ventas en $")

plt.show()

Explicación:

  • plt.scatter(publicidad, ventas) dibuja un punto para cada par de valores en las listas publicidad y ventas.
  • Este gráfico es excelente para identificar patrones, tendencias o posibles correlaciones entre las variables.

Histograma

Los histogramas se utilizan para mostrar la distribución de un conjunto de datos. Dividen el rango de datos en intervalos (o «bins») y cuentan cuántos valores caen en cada intervalo.

Ejemplo: Distribución de edades en un grupo

edades = [23, 25, 26, 29, 30, 32, 35, 36, 40, 41, 42, 45, 50, 55, 60]

plt.hist(edades, bins=5)  # 'bins' define el número de barras en el histograma

plt.title("Distribución de Edades")
plt.xlabel("Edades")
plt.ylabel("Número de Personas")

plt.show()

Explicación:

  • plt.hist(edades, bins=5) crea un histograma que divide los datos en 5 intervalos y cuenta cuántos valores caen en cada intervalo.
  • Los histogramas son útiles para comprender la distribución de los datos, por ejemplo, si los datos están sesgados hacia un extremo o si tienen una distribución normal.

Personalización de gráficos

Colores y estilos de líneas

Matplotlib permite personalizar el color y el estilo de las líneas en los gráficos, lo que es útil para mejorar la claridad y la estética de la visualización.

Ejemplo: Personalización de un gráfico de líneas

dias = ['Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes']
temperaturas = [22, 24, 20, 21, 19]

plt.plot(dias, temperaturas, color='green', linestyle='--', marker='o')

plt.title("Temperaturas Diarias")
plt.xlabel("Días")
plt.ylabel("Temperatura (°C)")

plt.show()

Explicación:

  • color='green' cambia el color de la línea a verde.
  • linestyle='--' convierte la línea en discontinua.
  • marker='o' añade marcadores de círculos en cada punto de datos.

Añadir leyendas

Las leyendas identifican las distintas series de datos en un gráfico, lo que es esencial cuando se comparan varias series.

Ejemplo: Comparación de ventas de dos productos

meses = ['Enero', 'Febrero', 'Marzo', 'Abril']
ventas_producto_a = [200, 220, 250, 270]
ventas_producto_b = [180, 190, 200, 210]

plt.plot(meses, ventas_producto_a, label='Producto A')
plt.plot(meses, ventas_producto_b, label='Producto B')

plt.title("Comparación de Ventas")
plt.xlabel("Meses")
plt.ylabel("Ventas en $")
plt.legend()  # Añadir leyenda

plt.show()

Explicación:

  • label='Producto A' y label='Producto B' especifican el nombre de cada línea en la leyenda.
  • plt.legend() coloca la leyenda en el gráfico.

Gráficos con subtramas

Los subgráficos permiten colocar múltiples gráficos en una sola figura, organizándolos en una cuadrícula.

Ejemplo: Gráficos de ventas y beneficios

meses = ['Enero', 'Febrero', 'Marzo', 'Abril']
ventas = [250, 300, 350, 400]
beneficios = [50, 60, 70, 80]

fig, (ax1, ax2) = plt.subplots(1, 2)  # Una fila y dos columnas

ax1.plot(meses, ventas)
ax1.set_title("Ventas")

ax2.plot(meses, beneficios, color='red')
ax2.set_title("Beneficios")

plt.show()

Explicación:

  • plt.subplots(1, 2) crea una figura con una fila y dos columnas de subgráficos.
  • ax1.plot(...) y ax2.plot(...) permiten dibujar gráficos en los diferentes ejes.

Gráficos avanzados

Gráfico de series temporales

Los gráficos de series temporales son fundamentales para mostrar cómo cambian los datos a lo largo del tiempo.

Ejemplo: Evolución de precios de acciones

import pandas as pd
import matplotlib.pyplot as plt

# Datos de ejemplo
fechas = pd.date_range(start='2023-01-01', periods=6, freq='M')
precios = [100, 105, 102, 108, 110, 115]

plt.plot(fechas, precios, marker='o')

plt.title("Evolución de Precios de Acciones")
plt.xlabel("Fecha")
plt.ylabel("Precio ($)")
plt.xticks(rotation=45)

plt.show()

Explicación:

  • pd.date_range(start='2023-01-01', periods=6, freq='M') genera un rango de fechas mensuales a partir de enero de 2023.
  • Este gráfico es ideal para mostrar datos financieros, meteorológicos, u otras métricas que varían con el tiempo.

Gráfico de pastel

Los gráficos de pastel se utilizan para mostrar la proporción de diferentes categorías en un conjunto de datos.

Ejemplo: Distribución de ventas por región

regiones = ['Norte', 'Sur', 'Este', 'Oeste']
ventas = [400, 300, 150, 150]

plt.pie(ventas, labels=regiones, autopct='%1.1f%%')

plt.title("Distribución de Ventas por Región")

plt.show()

Explicación:

  • plt.pie(ventas, labels=regiones, autopct='%1.1f%%') crea un gráfico de pastel y muestra los porcentajes de cada categoría en el gráfico.
  • Este tipo de gráfico es útil para mostrar cómo se distribuyen los datos en diferentes categorías.

Gráfico de barras apiladas

Los gráficos de barras apiladas son útiles para mostrar cómo diferentes subcomponentes contribuyen a un total.

Ejemplo: Ventas por categoría en diferentes meses

import numpy as np

meses = ['Enero', 'Febrero', 'Marzo', 'Abril']
categoria_a = [20, 35, 30, 35]
categoria_b = [25, 32, 34, 20]
categoria_c = [30, 30, 30, 30]

ind = np.arange(len(meses))  # La posición de los grupos
ancho = 0.35  # El ancho de las barras

p1 = plt.bar(ind, categoria_a, ancho)
p2 = plt.bar(ind, categoria_b, ancho, bottom=categoria_a)
p3 = plt.bar(ind, categoria_c, ancho, bottom=np.array(categoria_a)+np.array(categoria_b))

plt.ylabel('Ventas')
plt.title('Ventas por Categoría y Mes')
plt.xticks(ind, meses)
plt.legend(('Categoría A', 'Categoría B', 'Categoría C'))

plt.show()

Explicación:

  • bottom=categoria_a apila las barras de categoria_b sobre las de categoria_a.
  • Este gráfico es útil para ver la contribución relativa de diferentes categorías a lo largo del tiempo.

Guardar y compartir gráficos

Guardar gráficos en un archivo

Matplotlib permite guardar gráficos en diferentes formatos de archivo como PNG, PDF, SVG, entre otros. Esto es especialmente útil si deseas incluir gráficos en informes o presentaciones.

Ejemplo: Guardar un gráfico como PNG

x = [1, 2, 3, 4, 5]
y = [10, 20, 25, 30, 40]

plt.plot(x, y)

plt.title("Gráfico para Guardar")
plt.xlabel("Eje X")
plt.ylabel("Eje Y")

plt.savefig('grafico_guardado.png')  # Guarda el gráfico como PNG

Explicación:

  • plt.savefig('grafico_guardado.png') guarda el gráfico en el archivo grafico_guardado.png en el formato especificado.
  • Es posible cambiar el formato del archivo guardándolo con una extensión diferente, como .pdf o .svg.

Uso de BytesIO para generar gráficos en memoria

En algunos casos, no es necesario guardar los gráficos en el disco como archivos para compartirlos o visualizarlos en otras aplicaciones. Por ejemplo, en aplicaciones web se pueden enviar los gráficos dinámicamente al navegador sin crear archivos temporales. Aquí es donde entra en juego BytesIO, una clase de la librería estándar io en Python, que actúa como un contenedor de datos en memoria que se comporta como un archivo. Puedes escribir en él, leer de él, y tratarlo como si fuera un archivo regular, pero todo ocurre en la memoria RAM en lugar de en el disco duro.

Además, BytesIO no necesita ser instalado por separado porque forma parte de la biblioteca estándar de Python, específicamente dentro del módulo io. Esto significa que BytesIO está disponible automáticamente en cualquier instalación de Python moderna (Python 3 y superior) y no requiere ninguna instalación adicional:

from io import BytesIO

Ejemplo: Generación de un gráfico y almacenamiento en BytesIO

A continuación se muestra cómo se puede crear un gráfico con Matplotlib, almacenarlo en un objeto BytesIO en lugar de guardarlo en un archivo físico, y luego usar plt.close() para liberar recursos de manera eficiente:

import matplotlib.pyplot as plt
from io import BytesIO

# Datos de ejemplo
x = [1, 2, 3, 4, 5]
y = [10, 20, 25, 30, 35]

# Crear un gráfico
plt.plot(x, y)
plt.title("Gráfico en Memoria")
plt.xlabel("Eje X")
plt.ylabel("Eje Y")

# Crear un objeto BytesIO para almacenar el gráfico
img = BytesIO()

# Guardar el gráfico en el objeto BytesIO en formato PNG
plt.savefig(img, format='png')

# Colocar el puntero del archivo en memoria al inicio
# Ahora `img` contiene el gráfico en formato PNG, listo para ser enviado o procesado
img.seek(0)

# Cerrar la figura para liberar memoria
plt.close()

Explicación:

  • BytesIO() crea un objeto en memoria que se comporta como un archivo.
  • plt.savefig(img, format='png') guarda el gráfico en el objeto BytesIO en formato PNG.
  • img.seek(0) reposiciona el puntero al inicio del archivo en memoria para poder leerlo desde el principio.
  • plt.close() cierra la figura actual y libera los recursos de memoria asociados al gráfico. Esto es especialmente importante en aplicaciones que generan muchos gráficos, ya que evita el consumo excesivo de memoria.

Uso de BytesIO en Aplicaciones web con Flask

Una de las aplicaciones más comunes de BytesIO es en el desarrollo de aplicaciones web con frameworks como Flask. En estas aplicaciones, los gráficos se generan en respuesta a las solicitudes HTTP y se envían directamente al usuario para que los pueda visualizar en el navegador:

from flask import Flask, send_file
import matplotlib.pyplot as plt
from io import BytesIO

app = Flask(__name__)

@app.route('/grafico')
def generar_grafico():
    # Datos de ejemplo
    x = [1, 2, 3, 4, 5]
    y = [10, 20, 25, 30, 35]

    # Crear un gráfico
    plt.plot(x, y)
    plt.title("Gráfico Generado en Flask")
    plt.xlabel("Eje X")
    plt.ylabel("Eje Y")

    # Crear un objeto BytesIO
    img = BytesIO()

    # Guardar el gráfico en el objeto BytesIO en formato PNG
    plt.savefig(img, format='png')
    img.seek(0)  # Reposicionar el puntero al inicio del archivo en memoria

    # Cerrar la figura para liberar memoria
    plt.close()

    # Enviar el gráfico como respuesta HTTP
    return send_file(img, mimetype='image/png')

if __name__ == '__main__':
    app.run(debug=True)

Explicación:

  • send_file(img, mimetype='image/png') envía el contenido del BytesIO al cliente web como una imagen PNG.
  • plt.close() cierra la figura una vez que el gráfico ha sido guardado en memoria, asegurando que no queden gráficos abiertos que puedan consumir memoria innecesariamente.
  • Esta configuración permite que cada vez que un usuario acceda a la ruta /grafico, se genere un gráfico dinámicamente en memoria y se envíe al navegador.

Ventajas del uso de BytesIO y plt.close()

  • Eficiencia: No se necesita escribir archivos temporales en disco, lo que reduce el I/O del disco y mejora el rendimiento. Además, plt.close() asegura que la memoria se libere inmediatamente después de generar el gráfico.
  • Seguridad: Al no crear archivos temporales, se minimiza el riesgo de dejar datos sensibles en el disco.
  • Flexibilidad: Este enfoque se puede utilizar con aplicaciones que requieren gráficos dinámicos, como servicios web o scripts automatizados, sin preocuparse por el manejo de archivos en el sistema.

Ejemplos reales

Análisis de datos meteorológicos

Este ejemplo muestra cómo crear un gráfico con la evolución de la temperatura a lo largo de un día. Es común en aplicaciones de monitoreo del clima o en la presentación de datos meteorológicos:

import matplotlib.pyplot as plt

horas = ['6 AM', '9 AM', '12 PM', '3 PM', '6 PM', '9 PM']
temperaturas = [15, 18, 22, 26, 23, 20]

plt.plot(horas, temperaturas, marker='o', linestyle='-', color='blue')

plt.title("Evolución de la Temperatura")
plt.xlabel("Hora del Día")
plt.ylabel("Temperatura (°C)")
plt.grid(True)

plt.show()

Explicación:

  • marker='o', linestyle='-', color='b' personaliza la línea del gráfico.
  • plt.grid(True) añade una cuadrícula al gráfico para mejorar la legibilidad.

Análisis de datos financieros

Con el siguiente código creamos un gráfico que muestra la evolución del precio de cierre de las acciones de una empresa durante una semana. Este tipo de gráfico es fundamental en finanzas para analizar el rendimiento de acciones, bonos, etc.:

import matplotlib.pyplot as plt

dias = ['Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes']
precios = [150, 152, 148, 155, 160]

plt.plot(dias, precios, marker='o', linestyle='-', color='green')

plt.title("Evolución del precio de las acciones")
plt.xlabel("Días de la Semana")
plt.ylabel("Precio de la Acción ($)")
plt.grid(True)

plt.show()

Explicación:

  • plt.grid(True) añade una cuadrícula al gráfico para facilitar la comparación entre los días.

Análisis de resultados de exámenes

Este ejemplo muestra cómo comparar los resultados de dos clases en un examen. Puede resultar últil para analizar el rendimiento de los estudiantes de grupos diferentes:

import matplotlib.pyplot as plt

clases = ['Clase A', 'Clase B']
promedio_matematicas = [78, 85]
promedio_lenguaje = [82, 88]

x = range(len(clases))

plt.bar(x, promedio_matematicas, width=0.4, label='Matemáticas', align='center')
plt.bar(x, promedio_lenguaje, width=0.4, label='Lenguaje', align='edge')

plt.xlabel('Clases')
plt.ylabel('Promedio de Examen')
plt.title('Comparación de Resultados de Exámenes por Clase')
plt.xticks(x, clases)
plt.legend()

plt.show()

Explicación:

  • plt.bar(x, promedio_matematicas, width=0.4, label='Matemáticas', align='center') dibuja barras para Matemáticas.
  • plt.bar(x, promedio_lenguaje, width=0.4, label='Lenguaje', align='edge') dibuja barras para Lenguaje justo al lado de las de Matemáticas.
  • plt.legend() añade una leyenda que identifica qué barras corresponden a cada materia.

Recursos adicionales para aprender Matplotlib

Aprender a utilizar Matplotlib a fondo requiere tiempo y práctica, pero afortunadamente, la documentación oficial está muy bien redactada y organizada, y se actualiza con frecuencia. Además, dispone de una extensa galería de ejemplos donde puedes consultar muchos fragmentos de código, y observar el resultado generado.

Documentación oficial

La documentación oficial de Matplotlib es el recurso más completo y fiable. Este es el lugar al que debes recurrir cuando necesites información específica sobre cómo hacer algo con Matplotlib. Aquí encontrarás información detallada sobre todas las funciones y características. La documentación incluye:

  • Tutoriales: Introducciones paso a paso para principiantes que cubren desde los gráficos más básicos hasta técnicas avanzadas.
  • Guías de Uso: Explicaciones detalladas sobre cómo usar diversas partes de la API de Matplotlib.
  • Referencia de API: Una lista exhaustiva de todas las funciones, métodos y clases disponibles en Matplotlib, junto con ejemplos de cómo usarlos.
  • Ejemplos de Código: Pequeños fragmentos de código que ilustran cómo lograr resultados específicos con Matplotlib.

Galería de ejemplos

La galería de ejemplos de Matplotlib te proporciona un excelente recurso visual que muestra una gran cantidad de gráficos que puedes crear con Matplotlib. Cada ejemplo en la galería está acompañado del código fuente, lo que te permite ver exactamente cómo se generó el gráfico y experimentar por ti mismo. Esta sección de la documentación oficial incluye:

  • Cientos de ejemplos: La galería es ideal para obtener ideas sobre cómo visualizar tus propios datos de manera efectiva.
  • Código listo para usar: Puedes copiar y pegar el código directamente en tu propio proyecto y ajustarlo según tus necesidades.
  • Tipos de gráficos muy diversos: Desde gráficos de líneas y barras hasta gráficos más complejos como gráficos de violín, mapas de calor, y gráficos 3D.