Bibliotecas de aprendizaje automático de Python

Este capítulo te presentará en detalle las cuatro bibliotecas de Python más fundamentales en el aprendizaje automático: NumPy, Pandas, Matplotlib y Scikit-learn.

Las bibliotecas de aprendizaje automático son como un conjunto de herramientas profesionales, cada biblioteca tiene un propósito específico, y al usarlas juntas se pueden completar tareas complejas de aprendizaje automático.

Roles de las cuatro bibliotecas principales

  • Numpy: la base del cálculo numérico, proporciona operaciones eficientes con arrays
  • Pandas: la herramienta para el procesamiento de datos, proporciona estructuras de datos y herramientas de análisis
  • Matplotlib: el pincel de la visualización de datos, crea diversos tipos de gráficos
  • scikit-learn: la navaja suiza del aprendizaje automático, proporciona una cadena de herramientas ML completa

NumPy: la base del cálculo numérico

¿Qué es NumPy?

NumPy es como una calculadora para cálculos matemáticos, pero muchísimo más potente. Es la biblioteca fundamental para la computación científica en Python y proporciona objetos de arrays multidimensionales eficientes.

Conceptos fundamentales de NumPy

1. Arrays

Ejemplo

# Operaciones básicas de arrays en NumPy
import numpy as np

# Diferentes formas de crear arrays
print("=== Creación de arrays en NumPy ===")

# Crear desde una lista
arr1 = np.array([1, 2, 3, 4, 5])
print(f"Creado desde la lista: {arr1}")

# Crear un array con progresión aritmética
arr2 = np.arange(0, 10, 2)  # de 0 a 10, con paso de 2
print(f"Array de progresión aritmética: {arr2}")

# Crear un array con intervalos iguales
arr3 = np.linspace(0, 1, 5)  # de 0 a 1, 5 puntos
print(f"Array de intervalos iguales: {arr3}")

# Crear arrays especiales
zeros_arr = np.zeros((2, 3))  # Array de ceros de 2 filas y 3 columnas
ones_arr = np.ones((2, 3))    # Array de unos de 2 filas y 3 columnas
identity_arr = np.eye(3)      # Matriz identidad de 3x3

print(f"Array de ceros:\n{zeros_arr}")
print(f"Array de unos:\n{ones_arr}")
print(f"Matriz identidad:\n{identity_arr}")
```

2. Operaciones con arrays

Ejemplo

# Operaciones básicas con arrays
print("\n=== Operaciones básicas con arrays ===)

# Propiedades de los arrays
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(f"Array:\n{arr}")
print(f"Forma: {arr.shape}")
print(f"Dimensión: {arr.ndim}")
print(f"Número de elementos: {arr.size}")
print(f"Tipo de dato: {arr.dtype}")

# Indexación y corte de arrays
print(f"Primera fila: {arr)
print(f"Primera columna: {arr[:, 0]}")
print(f"Elemento [1,2]: {arr[1, 2]}")

# Operaciones con arrays
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])

print(f"Suma: {arr1 + arr2}")
print(f"Multiplicación: {arr1 * arr2}")
print(f"Producto punto: {np.dot(arr1, arr2)}")

# Funciones estadísticas
data = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(f"Media: {np.mean(data)}")
print(f"Desviación estándar: {np.std(data)}")
print(f"Máximo: {np.max(data)}")
print(f"Mínimo: {np.min(data)}")
print(f"Mediana: {np.median(data)}")

Ejemplo de aplicación práctica de NumPy

Ejemplo

# Aplicación práctica de NumPy: regresión lineal simple
def numpy_linear_regression():
    """Implementación de regresión lineal simple con NumPy"""
   
    # Generar datos de ejemplo
    np.random.seed(42)
    X = 2 * np.random.rand(100, 1)  # Características
    y = 4 + 3 * X + np.random.randn(100, 1)  # Etiquetas + ruido
   
    # Añadir x0 = 1 a X
    X_b = np.c_[np.ones((100, 1)), X]  # Añadir el término de sesgo
   
    # Resolver con la ecuación normal: θ = (X^T * X)^(-1) * X^T * y
    theta_best = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y)
   
    print("=== Ejemplo de regresión lineal con NumPy ===")
    print(f"Parámetros aprendidos: intercepto={theta_best)
   
    # Predicción
    X_new = np.array([[0], [2]])
    X_new_b = np.c_[np.ones((2, 1)), X_new]
    y_predict = X_new_b.dot(theta_best)
   
    print(f"Resultado de la predicción: cuando X=0, y={y_predict)
   
    return theta_best, X, y

# Ejecutar el ejemplo
theta, X, y = numpy_linear_regression()

Pandas: la herramienta para el procesamiento de datos

¿Qué es Pandas?

Pandas es como la navaja suiza del procesamiento de datos, proporciona potentes estructuras de datos y herramientas de análisis, especialmente adecuadas para manejar datos tabulares.

Estructuras de datos fundamentales de Pandas

1. Series (datos unidimensionales)

Ejemplo

# Operaciones básicas de Series en Pandas
import pandas as pd

print("=== Pandas Series ===")

# Crear una Series a partir de una lista
s1 = pd.Series([1, 2, 3, 4, 5])
print(f"Creada desde la lista:\n{s1}")

# Series con índice
s2 = pd.Series([10, 20, 30], index=['a', 'b', 'c'])
print(f"\nSeries con índice:\n{s2}")

# Crear una Series a partir de un diccionario
s3 = pd.Series({'Matemáticas': 90, 'Inglés': 85, 'Física': 88})
print(f"\nCreada desde el diccionario:\n{s3}")

# Operaciones con Series
print(f"\nAcceso al elemento: s2['b'] = {s2['b']}")
print(f"Rebanado: s2[0:2] =\n{s2[0:2]}")
print(f"Información estadística:\n{s2.describe()}")

2. DataFrame (datos bidimensionales)

Ejemplo

# Operaciones básicas de DataFrame en Pandas
print("\n=== Pandas DataFrame ===")

# Crear un DataFrame
data = {
    'Nombre': ['Zhang San', 'Li Si', 'Wang Wu', 'Zhao Liu'],
    'Edad': [25, 30, 35, 28],
    'Ciudad': ['Pekín', 'Shanghái', 'Guangzhou', 'Shenzhen'],
    'Salario': [15000, 20000, 18000, 22000]
}

df = pd.DataFrame(data)
print("DataFrame original: ")
print(df)

# Operaciones básicas con DataFrame
print(f"\nForma del DataFrame: {df.shape}")
print(f"\nNombres de columnas: {list(df.columns)}")
print(f"\nTipos de datos:\n{df.dtypes}")

# Seleccionar datos
print(f"\nSeleccionar la columna 'Nombre':\n{df['Nombre']}")
print(f"\nSeleccionar las dos primeras filas:\n{df.head(2)}")
print(f"\nSeleccionar las filas con edad mayor que 28:\n{df[df['Edad'] > 28]}")

# Información estadística
print(f"\nInformación estadística de las columnas numéricas:\n{df.describe()}")

# Añadir una nueva columna
df['Salario anual'] = df['Salario'] * 12
print(f"\nDespués de añadir la columna de salario anual:\n{df}")

Ejemplo de procesamiento de datos con Pandas

Ejemplo

# Ejemplo completo de procesamiento de datos con Pandas
def pandas_data_processing():
    """Demostrar el flujo completo de procesamiento de datos con Pandas"""
   
    print("=== Ejemplo de procesamiento de datos con Pandas ===")
   
    # 1. Crear datos de ejemplo
    np.random.seed(42)
    n_samples = 1000
   
    data = {
        'ID de estudiante': range(1, n_samples + 1),
        'Nombre': [f'Estudiante {i}' for i in range(1, n_samples + 1)],
        'Edad': np.random.randint(18, 25, n_samples),
        'Género': np.random.choice(['Masculino', 'Femenino'], n_samples),
        'Nota de matemáticas': np.random.normal(75, 15, n_samples),
        'Nota de inglés': np.random.normal(80, 12, n_samples),
        'Nota de Física': np.random.normal(72, 18, n_samples),
        'Clase': np.random.choice(['Clase 1', 'Clase 2', 'Clase 3'], n_samples)
    }
   
    df = pd.DataFrame(data)
   
    # 2. Limpieza de datos
    print("Forma de los datos originales:", df.shape)
   
    # Tratar valores atípicos (las calificaciones deben estar entre 0-100)
    score_columns = ['Nota de Matemáticas', 'Nota de Inglés', 'Nota de Física']
    for col in score_columns:
        df[col] = df[col].clip(0, 100)
   
    # 3. Ingeniería de características
    # Calcular la nota total y el promedio
    df['Nota total'] = df[score_columns].sum(axis=1)
    df['Promedio'] = df[score_columns].mean(axis=1)
   
    # Añadir nivel
    def get_grade(score):
        if score >= 90:
            return 'A'
        elif score >= 80:
            return 'B'
        elif score >= 70:
            return 'C'
        elif score >= 60:
            return 'D'
        else:
            return 'F'
   
    df['Nivel'] = df['Promedio'].apply(get_grade)
   
    # 4. Análisis de datos
    print("\n=== Resultados del análisis de datos ===")
   
    # Estadísticas básicas
    print("Promedio por materia:")
    print(df[score_columns].mean())
   
    # Análisis por clase
    print("\nPromedio de cada clase:")
    class_avg = df.groupby('Clase')['Promedio'].mean()
    print(class_avg)
   
    # Análisis por género
    print("\nDistribución de género:")
    gender_count = df['Género'].value_counts()
    print(gender_count)
   
    # Distribución de niveles
    print("\nDistribución de niveles:")
    grade_dist = df['Nivel'].value_counts().sort_index()
    print(grade_dist)
   
    # 5. Filtrado de datos
    print("\n=== Filtrado de datos específicos ===")
   
    # Estudiantes destacados (promedio > 85)
    excellent_students = df[df['Promedio'] > 85].head(5)
    print("Estudiantes destacados (top 5):")
    print(excellent_students[['Nombre', 'Promedio', 'Nivel']])
   
    # Estudiante con la nota más alta de cada clase
    print("\nEstudiante con la nota más alta de cada clase:")
    top_students = df.loc[df.groupby('Clase')['Promedio'].idxmax()]
    print(top_students[['Clase', 'Nombre', 'Promedio']])
   
    return df

# Ejecutar ejemplo
student_df = pandas_data_processing()

Matplotlib: el pincel de la visualización de datos

¿Qué es Matplotlib?

Matplotlib es como el pincel de un artista de datos, puede convertir datos aburridos en gráficos intuitivos, ayudándonos a comprender patrones y relaciones en los datos.

Gráficos básicos de Matplotlib

Ejemplo

# Ejemplo de gráficos básicos de Matplotlib
import matplotlib.pyplot as plt
import numpy as np

# Configurar la fuente china (para evitar que el chino se muestre como cuadros)
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False

def matplotlib_basic_charts():
    """Demostración de gráficos básicos de Matplotlib"""
   
    print("=== Ejemplo de gráficos básicos de Matplotlib ===")
   
    # 1. Gráfico de líneas
    plt.figure(figsize=(12, 8))
   
    plt.subplot(2, 3, 1)
    x = np.linspace(0, 10, 100)
    y1 = np.sin(x)
    y2 = np.cos(x)
    plt.plot(x, y1, label='sin(x)')
    plt.plot(x, y2, label='cos(x)')
    plt.title('Funciones trigonométricas')
    plt.xlabel('x')
    plt.ylabel('y')
    plt.legend()
    plt.grid(True)
   
    # 2. Gráfico de dispersión
    plt.subplot(2, 3, 2)
    np.random.seed(42)
    x = np.random.randn(100)
    y = 2 * x + np.random.randn(100) * 0.5
    plt.scatter(x, y, alpha=0.6, c='blue')
    plt.title('Gráfico de dispersión')
    plt.xlabel('X')
    plt.ylabel('Y')
   
    # 3. Gráfico de barras
    plt.subplot(2, 3, 3)
    categories = ['A', 'B', 'C', 'D', 'E']
    values = [23, 45, 56, 78, 32]
    plt.bar(categories, values, color=['red', 'green', 'blue', 'orange', 'purple'])
    plt.title('Gráfico de barras')
    plt.xlabel('Categoría')
    plt.ylabel('Valor')
   
    # 4. Histograma
    plt.subplot(2, 3, 4)
    data = np.random.normal(100, 15, 1000)
    plt.hist(data, bins=30, alpha=0.7, color='skyblue', edgecolor='black')
    plt.title('Histograma')
    plt.xlabel('Valor')
    plt.ylabel('Frecuencia')
   
    # 5. Gráfico circular
    plt.subplot(2, 3, 5)
    sizes = [30, 25, 20, 15, 10]
    labels = ['A', 'B', 'C', 'D', 'E']
    colors = ['gold', 'lightcoral', 'lightskyblue', 'lightgreen', 'plum']
    plt.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%', startangle=90)
    plt.title('Gráfico circular')
   
    # 6. Diagrama de caja
    plt.subplot(2, 3, 6)
    data1 = np.random.normal(0, 1, 100)
    data2 = np.random.normal(2, 1, 100)
    data3 = np.random.normal(-2, 1, 100)
    plt.boxplot([data1, data2, data3], labels=['Grupo 1', 'Grupo 2', 'Grupo 3'])
    plt.title('Diagrama de caja')
    plt.ylabel('Valor')
   
    plt.tight_layout()
    plt.show()
   
    print("¡Gráficos mostrados!")

# Ejecutar ejemplo
matplotlib_basic_charts()

Ejemplo de visualización avanzada

Ejemplo

# Ejemplo de visualización avanzada
def advanced_visualization():
    """Demostrar técnicas avanzadas de visualización"""
   
    print("=== Ejemplo de visualización avanzada ===")
   
    # Crear datos más complejos
    np.random.seed(42)
    n_points = 200
   
    # Generar datos correlacionados
    x = np.random.randn(n_points)
    y = 2 * x + np.random.randn(n_points) * 0.5
    colors = np.random.rand(n_points)
    sizes = 1000 * np.random.rand(n_points)
   
    # 1. Gráfico de burbujas
    plt.figure(figsize=(15, 5))
   
    plt.subplot(1, 3, 1)
    scatter = plt.scatter(x, y, c=colors, s=sizes, alpha=0.6, cmap='viridis')
    plt.colorbar(scatter, label='Valor de color')
    plt.title('Gráfico de burbujas')
    plt.xlabel('X')
    plt.ylabel('Y')
   
    # 2. Mapa de calor
    plt.subplot(1, 3, 2)
    data = np.random.randn(10, 10)
    im = plt.imshow(data, cmap='coolwarm', aspect='auto')
    plt.colorbar(im, label='Valor')
    plt.title('Mapa de calor')
   
    # 3. Combinación de subgráficos
    plt.subplot(1, 3, 3)
   
    # Crear subgráficos
    gs = plt.GridSpec(2, 2, subplot_kw={'projection': 'polar'})
   
    ax1 = plt.subplot(gs[0, 0])
    theta = np.linspace(0, 2*np.pi, 100)
    r = np.sin(3*theta)
    ax1.plot(theta, r)
    ax1.set_title('Gráfico polar')
   
    ax2 = plt.subplot(gs[0, 1])
    categories = ['A', 'B', 'C', 'D']
    values = [15, 30, 45, 10]
    ax2.bar(categories, values)
    ax2.set_title('Gráfico de barras')
   
    ax3 = plt.subplot(gs[1, :])
    x_line = np.linspace(0, 10, 100)
    y_line1 = np.sin(x_line)
    y_line2 = np.cos(x_line)
    ax3.plot(x_line, y_line1, label='sin')
    ax3.plot(x_line, y_line2, label='cos')
    ax3.set_title('Gráfico combinado')
    ax3.legend()
   
    plt.tight_layout()
    plt.show()
   
    print("¡Gráficos avanzados mostrados!")

# Ejecutar ejemplo
advanced_visualization()

Scikit-learn: la navaja suiza del aprendizaje automático

¿Qué es Scikit-learn?

Scikit-learn es como una caja de herramientas de aprendizaje automático, que proporciona una cadena de herramientas completa desde el preprocesamiento de datos hasta el entrenamiento y evaluación de modelos, y es el estándar de facto para el aprendizaje automático en Python.

Funcionalidades principales de Scikit-learn

Ejemplo

# Ejemplo de funciones principales de Scikit-learn
from sklearn.datasets import make_classification, load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix

def scikit_learn_basics():
    """Demostrar las funciones principales de Scikit-learn"""
   
    print("=== Ejemplo de funciones principales de Scikit-learn ===")
   
    # 1. Generación de datos
    X, y = make_classification(
        n_samples=1000,
        n_features=20,
        n_classes=3,
        n_informative=15,
        random_state=42
    )
   
    print(f"Forma de los datos: X={X.shape}, y={y.shape}")
    print(f"Distribución de clases: {np.bincount(y)}")
   
    # 2. División de datos
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.2, random_state=42, stratify=y
    )
   
    print(f"Tamaño del conjunto de entrenamiento: {X_train.shape)
    print(f"Tamaño del conjunto de prueba: {X_test.shape)
   
    # 3. Preprocesamiento de datos
    scaler = StandardScaler()
    X_train_scaled = scaler.fit_transform(X_train)
    X_test_scaled = scaler.transform(X_test)
   
    print("Estandarización de datos completada")
   
    # 4. Entrenamiento y comparación de modelos
    models = {
        'Regresión logística': LogisticRegression(random_state=42),
        'Bosque aleatorio': RandomForestClassifier(n_estimators=100, random_state=42),
        'Máquina de vectores de soporte': SVC(random_state=42)
    }
   
    results = {}
   
    for name, model in models.items():
        print(f"\nEntrenando {name}...")
       
        # Entrenar modelo
        model.fit(X_train_scaled, y_train)
       
        # Predecir
        y_pred = model.predict(X_test_scaled)
       
        # Evaluar
        accuracy = accuracy_score(y_test, y_pred)
        results[name] = accuracy
       
        print(f"{name} exactitud: {accuracy:.4f}")
        print(f"Informe de clasificación:\n{classification_report(y_test, y_pred)}")
   
    # 5. Comparación de resultados
    print("\n=== Comparación de modelos ===")
    for name, accuracy in results.items():
        print(f"{name}: {accuracy:.4f}")
   
    best_model = max(results, key=results.get)
    print(f"\nMejor modelo: {best_model}")
   
    return models[best_model]

# Ejecutar ejemplo
best_model = scikit_learn_basics()

El flujo completo de aprendizaje automático

Ejemplo

# Ejemplo del proceso completo de aprendizaje automático
def complete_ml_pipeline():
    """Demostrar el proceso completo de aprendizaje automático"""
   
    print("=== Proceso completo de aprendizaje automático ===")
   
    # 1. Cargar datos
    iris = load_iris()
    X = iris.data
    y = iris.target
    feature_names = iris.feature_names
    target_names = iris.target_names
   
    print(f"Conjunto de datos: {iris.DESCR.split('\n')[0]}")
    print(f"Número de características: {len(feature_names)}")
    print(f"Número de clases: {len(target_names)}")
   
    # 2. Exploración de datos
    df = pd.DataFrame(X, columns=feature_names)
    df['target'] = y
   
    print("\nVista previa de los datos:")
    print(df.head())
   
    print("\nEstadísticas de los datos:")
    print(df.describe())
   
    # 3. Visualización de datos
    plt.figure(figsize=(12, 4))
   
    plt.subplot(1, 2, 1)
    for i, target_name in enumerate(target_names):
        plt.scatter(
            df[df['target'] == i]['sepal length (cm)'],
            df[df['target'] == i]['sepal width (cm)'],
            label=target_name
        )
    plt.xlabel('Longitud del sépalo')
    plt.ylabel('Ancho del sépalo')
    plt.title('Distribución del tamaño del sépalo')
    plt.legend()
   
    plt.subplot(1, 2, 2)
    for i, target_name in enumerate(target_names):
        plt.scatter(
            df[df['target'] == i]['petal length (cm)'],
            df[df['target'] == i]['petal width (cm)'],
            label=target_name
        )
    plt.xlabel('Longitud del pétalo')
    plt.ylabel('Ancho del pétalo')
    plt.title('Distribución del tamaño del pétalo')
    plt.legend()
   
    plt.tight_layout()
    plt.show()
   
    # 4. Preparación de datos
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.3, random_state=42, stratify=y
    )
   
    # 5. Entrenamiento del modelo
    from sklearn.ensemble import RandomForestClassifier
    model = RandomForestClassifier(n_estimators=100, random_state=42)
    model.fit(X_train, y_train)
   
    # 6. Evaluación del modelo
    y_pred = model.predict(X_test)
    accuracy = accuracy_score(y_test, y_pred)
   
    print(f"\nExactitud del modelo: {accuracy:.4f}")
    print("\nMatriz de confusión:")
    print(confusion_matrix(y_test, y_pred))
    print("\nInforme de clasificación:")
    print(classification_report(y_test, y_pred, target_names=target_names))
   
    # 7. Importancia de las características
    feature_importance = model.feature_importances_
    feature_df = pd.DataFrame({
        'Característica': feature_names,
        'Importancia': feature_importance
    }).sort_values('Importancia', ascending=False)
   
    print("\nImportancia de las características:")
    print(feature_df)
   
    # 8. Visualización de la importancia de las características
    plt.figure(figsize=(8, 4))
    plt.bar(feature_df['Característica'], feature_df['Importancia'])
    plt.title('Importancia de las características')
    plt.xlabel('Característica')
    plt.ylabel('Importancia')
    plt.xticks(rotation=45)
    plt.tight_layout()
    plt.show()
   
    return model, feature_df

# Ejecutar ejemplo
trained_model, feature_importance = complete_ml_pipeline()

Ejemplo de trabajo conjunto de las cuatro bibliotecas

Ejemplo

# Trabajo colaborativo de las cuatro bibliotecas: un proyecto completo de aprendizaje automático
def four_libraries_integration():
    """Demostrar el trabajo colaborativo de NumPy, Pandas, Matplotlib y Scikit-learn"""
   
    print("=== Ejemplo de trabajo colaborativo de las cuatro bibliotecas ===")
   
    # 1. NumPy: generar datos simulados
    np.random.seed(42)
    n_samples = 500
   
    # Generar características
    study_hours = np.random.uniform(1, 10, n_samples)  # Tiempo de estudio
    sleep_hours = np.random.uniform(5, 9, n_samples)   # Tiempo de sueño
    practice_tests = np.random.randint(0, 20, n_samples) # Número de ejercicios
   
    # Generar etiquetas (notas de examen) a partir de una combinación lineal de las características más ruido
    exam_scores = (
        5 * study_hours +
        3 * sleep_hours +
        2 * practice_tests +
        np.random.normal(0, 10, n_samples)
    )
   
    # Asegurar que las calificaciones estén en el rango 0-100
    exam_scores = np.clip(exam_scores, 0, 100)
   
    # 2. Pandas: crear un DataFrame y procesar datos
    df = pd.DataFrame({
        'Tiempo de estudio': study_hours,
        'Tiempo de sueño': sleep_hours,
        'Número de ejercicios': practice_tests,
        'Nota de examen': exam_scores
    })
   
    # Añadir columna de nivel
    df['Nivel'] = pd.cut(df['Nota de examen'],
                       bins=[0, 60, 70, 80, 90, 100],
                       labels=['F', 'D', 'C', 'B', 'A'])
   
    print("Vista previa de los datos:")
    print(df.head())
    print(f"\nForma de los datos: {df.shape}")
    print(f"\nDistribución de niveles:")
    print(df['Nivel'].value_counts().sort_index())
   
    # 3. Matplotlib: Visualización de datos
    plt.figure(figsize=(15, 10))
   
    # Subplot 1: Distribución de características
    plt.subplot(2, 3, 1)
    df[['Tiempo de estudio', 'Tiempo de sueño', 'Número de ejercicios']].hist(bins=20, ax=plt.gca())
    plt.title('Distribución de características')
   
    # Subplot 2: Distribución de calificaciones
    plt.subplot(2, 3, 2)
    plt.hist(df['Calificación del examen'], bins=20, alpha=0.7, color='skyblue')
    plt.title('Distribución de calificaciones del examen')
    plt.xlabel('Puntuación')
    plt.ylabel('Frecuencia')
   
    # Subplot 3: Tiempo de estudio vs calificación
    plt.subplot(2, 3, 3)
    plt.scatter(df['Tiempo de estudio'], df['Calificación del examen'], alpha=0.6)
    plt.xlabel('Tiempo de estudio')
    plt.ylabel('Calificación del examen')
    plt.title('Relación entre tiempo de estudio y calificación')
   
    # Subplot 4: Tiempo de sueño vs calificación
    plt.subplot(2, 3, 4)
    plt.scatter(df['Tiempo de sueño'], df['Calificación del examen'], alpha=0.6, color='orange')
    plt.xlabel('Tiempo de sueño')
    plt.ylabel('Calificación del examen')
    plt.title('Relación entre tiempo de sueño y calificación')
   
    # Subplot 5: Número de ejercicios vs calificación
    plt.subplot(2, 3, 5)
    plt.scatter(df['Número de ejercicios'], df['Calificación del examen'], alpha=0.6, color='green')
    plt.xlabel('Número de ejercicios')
    plt.ylabel('Calificación del examen')
    plt.title('Relación entre número de ejercicios y calificación')
   
    # Subplot 6: Gráfico circular de distribución de niveles
    plt.subplot(2, 3, 6)
    grade_counts = df['Nivel'].value_counts()
    plt.pie(grade_counts.values, labels=grade_counts.index, autopct='%1.1f%%')
    plt.title('Distribución de niveles')
   
    plt.tight_layout()
    plt.show()
   
    # 4. Scikit-learn: Modelado de aprendizaje automático
    from sklearn.linear_model import LinearRegression
    from sklearn.ensemble import RandomForestRegressor
    from sklearn.metrics import mean_squared_error, r2_score
   
    # Preparar datos
    X = df[['Tiempo de estudio', 'Tiempo de sueño', 'Número de ejercicios']]
    y = df['Calificación del examen']
   
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.2, random_state=42
    )
   
    # Entrenar modelo de regresión lineal
    lr_model = LinearRegression()
    lr_model.fit(X_train, y_train)
    lr_pred = lr_model.predict(X_test)
    lr_mse = mean_squared_error(y_test, lr_pred)
    lr_r2 = r2_score(y_test, lr_pred)
   
    # Entrenar modelo de bosque aleatorio
    rf_model = RandomForestRegressor(n_estimators=100, random_state=42)
    rf_model.fit(X_train, y_train)
    rf_pred = rf_model.predict(X_test)
    rf_mse = mean_squared_error(y_test, rf_pred)
    rf_r2 = r2_score(y_test, rf_pred)
   
    # Comparación de modelos
    print("\n=== Comparación de modelos ===)
    print(f"Regresión lineal: MSE={lr_mse:.2f}, R²={lr_r2:.4f}")
    print(f"Bosque aleatorio: MSE={rf_mse:.2f}, R²={rf_r2:.4f}")
   
    # Coeficientes de regresión lineal
    print(f"\nCoeficientes de regresión lineal:")
    for feature, coef in zip(X.columns, lr_model.coef_):
        print(f"{feature}: {coef:.2f}")
   
    # Importancia de características del bosque aleatorio
    print(f"\nImportancia de características del bosque aleatorio:")
    for feature, importance in zip(X.columns, rf_model.feature_importances_):
        print(f"{feature}: {importance:.4f}")
   
    # Visualización de resultados de predicción
    plt.figure(figsize=(12, 5))
   
    plt.subplot(1, 2, 1)
    plt.scatter(y_test, lr_pred, alpha=0.6)
    plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--')
    plt.xlabel('Calificación real')
    plt.ylabel('Calificación predicha')
    plt.title('Resultados de predicción de regresión lineal')
   
    plt.subplot(1, 2, 2)
    plt.scatter(y_test, rf_pred, alpha=0.6)
    plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--')
    plt.xlabel('Calificación real')
    plt.ylabel('Calificación predicha')
    plt.title('Resultados de predicción de bosque aleatorio')
   
    plt.tight_layout()
    plt.show()
   
    return {
        'data': df,
        'linear_model': lr_model,
        'rf_model': rf_model,
        'linear_metrics': {'mse': lr_mse, 'r2': lr_r2},
        'rf_metrics': {'mse': rf_mse, 'r2': rf_r2}
    }

# Ejecutar ejemplo completo
results = four_libraries_integration()
Otras extensiones