# =============================================================================
# COMPARATIVA: REGRESIÓN LOGÍSTICA vs REGRESIÓN LINEAL
# ¿En qué se diferencian? ¿Cuándo usar cada una?
# =============================================================================
#
# IDEA GENERAL DEL EJERCICIO:
# Tenemos 10 alumnos con sus horas de estudio.
# Vamos a entrenar DOS modelos distintos con los mismos datos:
#
# Modelo 1 — Regresión LOGÍSTICA:
# Pregunta: ¿Aprueba o suspende? → Responde con 0 o 1 (categoría)
#
# Modelo 2 — Regresión LINEAL:
# Pregunta: ¿Qué nota sacará? → Responde con un número decimal (valor continuo)
#
# Esto ilustra la diferencia clave entre CLASIFICACIÓN y REGRESIÓN en ML.
# =============================================================================
# ─────────────────────────────────────────────────────────────────────────────
# IMPORTACIONES
# ─────────────────────────────────────────────────────────────────────────────
import numpy as np
# numpy nos permite trabajar con arrays numéricos de forma eficiente.
# Lo usamos aquí para crear los datos de entrada y darles el formato correcto.
from sklearn.linear_model import LogisticRegression, LinearRegression
# De scikit-learn importamos los dos modelos que vamos a comparar:
# - LogisticRegression: clasifica (aprueba / suspende)
# - LinearRegression: predice un número continuo (la nota)
from sklearn.model_selection import train_test_split
# Herramienta para dividir los datos en entrenamiento y prueba.
# En este ejercicio no la usamos porque los datos son muy pocos (solo 10),
# pero se importa para recordar que en proyectos reales SIEMPRE hay que usarla.
from sklearn.metrics import accuracy_score
# Función para medir el porcentaje de aciertos de un clasificador.
# Igual que train_test_split, se importa como recordatorio de buenas prácticas,
# aunque en este ejercicio simplificado no la aplicamos.
# =============================================================================
# PASO 1 — PREPARAR LOS DATOS
# =============================================================================
# Horas de estudio de 10 alumnos (la variable de entrada, llamada X)
# Cada número representa cuántas horas estudió ese alumno.
X = np.array([1, 2, 2, 3, 4, 5, 6, 7, 8, 9]).reshape(-1, 1)
#
# ¿Qué hace .reshape(-1, 1)?
# ─────────────────────────
# scikit-learn espera que X tenga forma de TABLA (filas × columnas),
# aunque tengamos una sola columna.
#
# Sin reshape, X sería una lista plana: [1, 2, 2, 3, ...] → forma (10,)
# Con reshape(-1, 1), X se convierte en una columna vertical:
#
# [[1],
# [2],
# [2],
# [3], ← cada alumno ocupa una fila
# ...]
#
# El -1 le dice a numpy: "calcula tú cuántas filas hacen falta".
# El 1 indica que queremos 1 columna.
# Resultado: shape (10, 1) → 10 filas, 1 columna.
# Etiquetas para el Modelo 1 — Regresión LOGÍSTICA
# 0 = suspende, 1 = aprueba
y = np.array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1])
#
# Alumno 1 estudió 1 hora → suspende (0)
# Alumno 2 estudió 2 horas → suspende (0)
# Alumno 3 estudió 2 horas → suspende (0)
# Alumno 4 estudió 3 horas → suspende (0)
# Alumno 5 estudió 4 horas → suspende (0)
# Alumno 6 estudió 5 horas → aprueba (1)
# Alumno 7 estudió 6 horas → aprueba (1)
# Alumno 8 estudió 7 horas → aprueba (1)
# Alumno 9 estudió 8 horas → aprueba (1)
# Alumno 10 estudió 9 horas → aprueba (1)
#
# El patrón es claro: a partir de 5 horas, los alumnos aprueban.
# El modelo logístico tiene que aprender ese umbral.
# =============================================================================
# PASO 2 — MODELO 1: REGRESIÓN LOGÍSTICA (clasificación)
# =============================================================================
#
# La regresión logística responde preguntas de tipo SÍ/NO, o en este caso
# APRUEBA/SUSPENDE. Internamente calcula la probabilidad de que el resultado
# sea 1 (aprueba), y si esa probabilidad supera el 50%, predice 1.
#
# Ejemplo: para un alumno con 3 horas podría calcular:
# probabilidad de aprobar = 15% → predice 0 (suspende)
#
# Para un alumno con 7 horas:
# probabilidad de aprobar = 92% → predice 1 (aprueba)
modelo = LogisticRegression()
# Creamos el modelo. Por ahora es una "caja vacía", aún no ha aprendido nada.
modelo.fit(X, y)
# .fit() es el entrenamiento.
# El modelo analiza todos los pares (horas_estudio, resultado)
# y ajusta sus parámetros internos para aprender el patrón:
# "a partir de X horas, la probabilidad de aprobar supera el 50%".
# ── Predicción con el Modelo 1 ────────────────────────────────────────────
print("=== MODELO 1: Regresión Logística (¿aprueba o suspende?) ===")
print(modelo.predict([[3]]))
# Le preguntamos al modelo: ¿un alumno que estudia 3 horas aprueba o suspende?
#
# [[3]] → los corchetes dobles son necesarios porque el modelo espera
# una tabla, no un número suelto. Es la misma lógica que el reshape anterior.
#
# Resultado esperado: [0] → el modelo predice que SUSPENDE.
# Esto tiene sentido: con solo 3 horas, los datos de entrenamiento
# mostraban que ese alumno suspendería.
print(modelo.predict_proba([[3]]))
# predict_proba nos da la probabilidad de cada clase, no solo la decisión.
# Devuelve dos números: [P(suspende), P(aprueba)]
# Por ejemplo: [0.82, 0.18] → 82% de probabilidad de suspender, 18% de aprobar.
# Útil cuando no queremos solo un sí/no, sino el grado de certeza del modelo.
# =============================================================================
# PASO 3 — DATOS PARA EL MODELO 2
# =============================================================================
# Notas numéricas de los mismos 10 alumnos (la nueva variable objetivo)
notas = np.array([3, 3, 4, 4, 5, 5, 6, 6, 8, 9])
#
# Alumno 1 (1 hora) → nota 3
# Alumno 2 (2 horas) → nota 3
# Alumno 3 (2 horas) → nota 4
# Alumno 4 (3 horas) → nota 4
# Alumno 5 (4 horas) → nota 5
# Alumno 6 (5 horas) → nota 5
# Alumno 7 (6 horas) → nota 6
# Alumno 8 (7 horas) → nota 6
# Alumno 9 (8 horas) → nota 8
# Alumno 10 (9 horas) → nota 9
#
# Aquí ya no es aprueba/suspende, sino la nota EXACTA.
# El modelo lineal tiene que aprender cuánto sube la nota por cada hora más.
# =============================================================================
# PASO 4 — MODELO 2: REGRESIÓN LINEAL (predicción de un valor continuo)
# =============================================================================
#
# La regresión lineal ajusta una LÍNEA RECTA a los datos.
# Busca la ecuación: nota = a × horas + b
#
# Donde:
# a (pendiente) = cuántos puntos sube la nota por cada hora extra
# b (intercepto) = nota base si el alumno estudiara 0 horas
#
# A diferencia del modelo logístico, la salida puede ser CUALQUIER número
# decimal: 4.2, 5.87, 7.3... No está limitada a 0 y 1.
modelo_2 = LinearRegression()
# Creamos el segundo modelo, también vacío de momento.
modelo_2.fit(X, notas)
# Entrenamos el modelo con las mismas horas de estudio (X)
# pero ahora la variable objetivo son las notas numéricas.
#
# Internamente calcula la recta que mejor se ajusta a los datos,
# minimizando el error total entre las notas reales y las predichas.
# ── Predicción con el Modelo 2 ────────────────────────────────────────────
print("\n=== MODELO 2: Regresión Lineal (¿qué nota sacará?) ===")
print(modelo_2.predict([[3]]))
# Le preguntamos: ¿qué nota obtendrá un alumno que estudia 3 horas?
#
# Resultado esperado: algo cercano a 4.0 o 4.2 (un número decimal).
# No devuelve 0 o 1, sino un valor numérico que representa la nota estimada.
# =============================================================================
# RESUMEN: ¿EN QUÉ SE DIFERENCIAN LOS DOS MODELOS?
# =============================================================================
#
# ┌──────────────────────┬─────────────────────┬──────────────────────────┐
# │ │ Regresión LOGÍSTICA │ Regresión LINEAL │
# ├──────────────────────┼─────────────────────┼──────────────────────────┤
# │ Tipo de problema │ Clasificación │ Regresión │
# │ Pregunta que responde│ ¿Categoría A o B? │ ¿Qué valor numérico? │
# │ Salida del modelo │ 0 o 1 (clase) │ Número decimal (nota) │
# │ En este ejercicio │ Suspende / Aprueba │ Nota entre 0 y 10 │
# │ Función interna │ Sigmoide (0 a 1) │ Recta y = ax + b │
# │ Métrica habitual │ Accuracy │ MSE, RMSE, R² │
# └──────────────────────┴─────────────────────┴──────────────────────────┘
#
# REGLA PRÁCTICA:
# → Si la respuesta es una CATEGORÍA (sí/no, color, especie...) → Logística
# → Si la respuesta es un NÚMERO CONTINUO (precio, temperatura...) → Lineal
# =============================================================================
Regresión logística spam
"""
Ejemplo didáctico de Regresión Logística
========================================
Objetivo:
Predecir si un correo es SPAM (1) o NO SPAM (0).
Este ejemplo está pensado para enseñar:
1. Qué es un dataset.
2. Por qué se divide en entrenamiento (train) y prueba (test).
3. Cómo aprende un modelo de regresión logística.
4. Qué significa predecir.
5. Cómo interpretar las métricas.
Dataset:
- 30 correos ficticios.
- Variables:
* num_palabras_promocionales
* num_enlaces
* porcentaje_mayusculas
* spam (objetivo)
La variable spam vale:
1 = spam
0 = no spam
"""
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import (
accuracy_score,
confusion_matrix,
classification_report
)
# ------------------------------------------------------------------
# 1. DATASET
# ------------------------------------------------------------------
datos = [
[0,0,5,0],
[1,0,4,0],
[0,1,8,0],
[2,0,6,0],
[1,1,7,0],
[0,0,3,0],
[2,1,10,0],
[1,0,12,0],
[0,1,6,0],
[2,0,8,0],
[5,3,45,1],
[6,4,55,1],
[4,2,40,1],
[7,5,60,1],
[5,4,50,1],
[6,3,48,1],
[8,5,70,1],
[4,3,42,1],
[7,4,65,1],
[5,2,46,1],
[1,1,15,0],
[2,1,18,0],
[3,1,22,0],
[3,2,25,0],
[4,1,28,0],
[4,2,30,1],
[3,3,35,1],
[2,2,20,0],
[5,1,32,1],
[1,2,18,0]
]
df = pd.DataFrame(
datos,
columns=[
"num_palabras_promocionales",
"num_enlaces",
"porcentaje_mayusculas",
"spam"
]
)
print("="*70)
print("DATASET COMPLETO")
print("="*70)
print(df)
# ------------------------------------------------------------------
# 2. SEPARAR VARIABLES DE ENTRADA Y SALIDA
# ------------------------------------------------------------------
X = df[
[
"num_palabras_promocionales",
"num_enlaces",
"porcentaje_mayusculas"
]
]
y = df["spam"]
# ------------------------------------------------------------------
# 3. DIVISIÓN TRAIN / TEST
# ------------------------------------------------------------------
"""
¿Por qué dividimos los datos?
Imagina que un profesor enseña las respuestas exactas de un examen
a un alumno y luego le pone exactamente el mismo examen.
Sacar un 10 no demostraría que ha aprendido.
Con Machine Learning ocurre lo mismo.
TRAIN:
Datos que el modelo utiliza para aprender.
TEST:
Datos que el modelo NO ha visto nunca.
Si funciona bien en TEST, tenemos más confianza en que
generaliza correctamente.
"""
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.30,
random_state=42
)
print("\n")
print("="*70)
print("DIVISIÓN TRAIN / TEST")
print("="*70)
print(f"Filas para entrenamiento: {len(X_train)}")
print(f"Filas para prueba: {len(X_test)}")
print("Estos datos los hemos reservado para test")
print(X_test)
print("Y estas son los datos reales")
print(y_test)
# ------------------------------------------------------------------
# 4. ENTRENAMIENTO
# ------------------------------------------------------------------
modelo = LogisticRegression()
modelo.fit(X_train, y_train)
print("\nModelo entrenado.")
# ------------------------------------------------------------------
# 5. PREDICCIÓN
# ------------------------------------------------------------------
"""
¿Qué significa predecir?
El modelo observa las características de un correo que nunca
ha visto y estima:
P(spam)
Es decir, la probabilidad de que sea spam.
Después convierte esa probabilidad en una clase:
>= 0.5 -> spam
< 0.5 -> no spam
"""
probabilidades = modelo.predict_proba(X_test)
predicciones = modelo.predict(X_test)
print("\n")
print("="*70)
print("PREDICCIONES")
print("="*70)
for i in range(len(X_test)):
prob_no_spam = probabilidades[i][0]
prob_spam = probabilidades[i][1]
print(
f"Correo {i+1:2d} | "
f"P(No Spam)={prob_no_spam:.3f} | "
f"P(Spam)={prob_spam:.3f} | "
f"Predicción={predicciones[i]} | "
f"Real={list(y_test)[i]}"
)
print("Los datos reales vs. predichos:")
print(y_test.tolist())
print(predicciones)
# ------------------------------------------------------------------
# 6. MÉTRICAS
# ------------------------------------------------------------------
accuracy = accuracy_score(y_test, predicciones)
print("\n")
print("="*70)
print("ACCURACY")
print("="*70)
print(f"Accuracy = {accuracy:.3f}")
"""
Accuracy:
(Número de aciertos) / (Número total de casos)
Ejemplo:
Si el modelo acierta 8 de 10 correos:
Accuracy = 8/10 = 0.80 = 80%
"""
print("\n")
print("="*70)
print("MATRIZ DE CONFUSIÓN")
print("="*70)
cm = confusion_matrix(y_test, predicciones)
print(cm)
"""
Matriz de confusión:
Predijo No Spam Predijo Spam
Real No Spam VN FP
Real Spam FN VP
VN = Verdadero Negativo
FP = Falso Positivo
FN = Falso Negativo
VP = Verdadero Positivo
FP:
Correo normal marcado como spam.
FN:
Correo spam que el modelo dejó pasar.
"""
print("\n")
print("="*70)
print("CLASSIFICATION REPORT")
print("="*70)
print(classification_report(y_test, predicciones))
"""
Precision:
De todos los correos marcados como spam,
¿cuántos eran realmente spam?
Recall:
De todos los spam reales,
¿cuántos encontró el modelo?
F1:
Media armónica entre Precision y Recall.
Support:
Número de ejemplos de cada clase.
"""
# ------------------------------------------------------------------
# 7. EJEMPLO NUEVO
# ------------------------------------------------------------------
nuevo_correo = pd.DataFrame(
[[6, 4, 58]],
columns=[
"num_palabras_promocionales",
"num_enlaces",
"porcentaje_mayusculas"
]
)
prob = modelo.predict_proba(nuevo_correo)[0][1]
print("\n")
print("="*70)
print("EJEMPLO DE CORREO NUEVO")
print("="*70)
print(nuevo_correo)
print(f"Probabilidad de spam: {prob:.3f}")
print(f"Clasificación final: {modelo.predict(nuevo_correo)[0]}")
"""
Conclusión:
Entrenamiento:
El modelo aprende patrones.
Prueba:
Verificamos si esos patrones funcionan en datos nuevos.
Predicción:
Aplicamos lo aprendido a correos nunca vistos.
Métricas:
Cuantifican si el modelo está funcionando bien.
"""
Regresión logística
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
#1. DATOS
# Horas de estudio de 10 alumnos
X = np.array([1, 2, 2, 3, 4, 5, 6, 7, 8, 9]).reshape(-1, 1)
# 0 = suspenso, 1 = aprobado
y = np.array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1])
print(X)
# Dividir train y test
X_train, X_test, y_train, y_test = train_test_split(X, y,test_size=0.2, random_state=42)
# Entreno el modelo
# Creamos el modelo
modelo = LogisticRegression()
# Entrenamos el modelo con los datos de entrenamiento
modelo.fit(X_train, y_train)
# Medimos que tal funciona nuestro modelo
# Predecimos con los datos de prueba
predicciones = modelo.predict(X_test)
print('Predicciones:', predicciones)
# Calculamos la precisión
precision = accuracy_score(y_test, predicciones)
print(f'Precisión del modelo: {precision * 100:.1f}%')
# Predecir un alumno nuevo: ¿aprobará alguien que estudió 5 horas?
nuevo_alumno = np.array([[5]])
print('¿Aprueba con 5 horas?', modelo.predict(nuevo_alumno))
print('Probabilidad:', modelo.predict_proba(nuevo_alumno))
Ejemplo completo
# =============================================================================
# EJERCICIO GUIADO: Regresión Lineal Multivariable
# Dataset: Propinas en un restaurante (tips)
# Nivel: Principiante / Intermedio
# =============================================================================
#
# CONTEXTO DEL PROBLEMA
# ─────────────────────
# En el ejercicio anterior usamos solo el total de la cuenta para predecir
# la propina. ¡Pero hay más información disponible!
#
# PREGUNTA: ¿Podemos predecir mejor la propina usando VARIAS variables?
#
# Esto es lo que hace la REGRESIÓN LINEAL MULTIVARIABLE:
# aprender cómo influye cada variable de entrada en la propina.
#
# La fórmula pasa de tener una sola X a varias:
#
# tip = b₀ + b₁×total_bill + b₂×size
#
# donde cada bᵢ (coeficiente) indica cuánto influye esa variable.
#
# Al final del ejercicio sabrás:
# · Seleccionar múltiples variables numéricas
# · Normalizar los datos para que las variables estén en la misma escala
# · Entrenar un modelo de regresión multivariable
# · Comparar su rendimiento con el modelo simple anterior
# · Interpretar los coeficientes de cada variable
# · Predecir la propina para una comanda nueva con múltiples datos
#
# VARIABLES DEL DATASET
# ─────────────────────
# total_bill → importe total de la cuenta en dólares [numérica]
# tip → propina dejada por el cliente [numérica, objetivo]
# sex → sexo del cliente que paga [categórica]
# smoker → si la mesa es de fumadores [categórica]
# day → día de la semana [categórica]
# time → Lunch / Dinner [categórica]
# size → número de personas en la mesa [numérica]
#
# En este ejercicio usaremos: total_bill y size.
#
# =============================================================================
# ─────────────────────────────────────────────────────────────────────────────
# PASO 0 — IMPORTACIONES
# ─────────────────────────────────────────────────────────────────────────────
#
# Ejecuta este bloque primero. Si alguna librería no está instalada:
# pip install seaborn scikit-learn matplotlib
import seaborn as sns
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler # ← nueva importación
from sklearn.metrics import (
r2_score,
mean_absolute_error,
mean_squared_error,
root_mean_squared_error
)
# ─────────────────────────────────────────────────────────────────────────────
# PASO 1 — CARGAR EL DATASET
# ─────────────────────────────────────────────────────────────────────────────
#
# Cargamos el mismo dataset de propinas que en el ejercicio anterior.
print("=" * 60)
print(" PASO 1: Carga del dataset")
print("=" * 60)
df = sns.load_dataset("tips")
# ─────────────────────────────────────────────────────────────────────────────
# PASO 3 — SELECCIONAR X e y
# ─────────────────────────────────────────────────────────────────────────────
#
# Ahora X tiene DOS columnas (de ahí el nombre "multivariable"):
# X = [total_bill, size]
# y = tip (lo mismo que antes)
#
# 💡 PISTA: Usa doble corchete para seleccionar varias columnas:
# X = df[["total_bill", "size"]]
#
# 🛠️ TU TURNO:
# 1. Define X con las dos variables indicadas.
# 2. Define y como la columna "tip".
# 3. Imprime X.shape e y.shape.
# ¿Qué diferencia ves en X respecto al ejercicio de regresión simple?
print("\n" + "=" * 60)
print(" PASO 3: Seleccionar X e y")
print("=" * 60)
# --- ESCRIBE TU CÓDIGO AQUÍ ---
X = df[["total_bill", "size"]] # ¿Qué variables? total_bill y size
y = df["tip"]
# ─────────────────────────────────────────────────────────────────────────────
# PASO 4 — DIVIDIR EN ENTRENAMIENTO Y TEST
# ─────────────────────────────────────────────────────────────────────────────
#
# Dividimos ANTES de normalizar para evitar "data leakage":
# si normalizamos con todos los datos, el modelo vería información
# del conjunto de test durante el entrenamiento (hace trampa).
#
# Orden correcto: dividir → normalizar con train → aplicar a test.
#
# 💡 PISTA: train_test_split(X, y, test_size=0.2, random_state=42)
#
# 🛠️ TU TURNO:
# Aplica train_test_split y guarda los cuatro conjuntos:
# X_train, X_test, y_train, y_test
# Imprime cuántas filas tiene cada parte.
print("\n" + "=" * 60)
print(" PASO 4: División train / test (80% / 20%)")
print("=" * 60)
# --- ESCRIBE TU CÓDIGO AQUÍ -
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# ─────────────────────────────────────────────────────────────────────────────
# PASO 5 — NORMALIZACIÓN (StandardScaler)
# ─────────────────────────────────────────────────────────────────────────────
#
# PROBLEMA: total_bill va de 3 a 51 $, pero size va de 1 a 6 personas.
# Son escalas muy distintas. Si no normalizamos, el modelo puede dar
# más "peso" a total_bill simplemente porque sus valores son más grandes,
# no porque sea más importante.
#
# StandardScaler convierte cada variable para que tenga:
# · media = 0
# · desviación típica = 1
#
# Fórmula: z = (x − media) / desviación_típica
#
# ⚠️ REGLA IMPORTANTE: el scaler se "aprende" (fit) SOLO con X_train.
# Luego se aplica (transform) tanto a X_train como a X_test.
# Nunca hagas fit con X_test: estarías mirando datos que no deberías ver.
#
# 💡 PISTA:
# scaler = StandardScaler()
# X_train_sc = scaler.fit_transform(X_train) # aprende Y transforma
# X_test_sc = scaler.transform(X_test) # solo transforma
#
# 🛠️ TU TURNO:
# 1. Crea el scaler y aplícalo según el ejemplo de arriba.
# 2. Imprime la media y desviación típica que aprendió el scaler.
# Pista: scaler.mean_ y scaler.scale_
# 3. Comprueba que X_train_sc tiene media ≈ 0 y std ≈ 1 por columna.
# Pista: pd.DataFrame(X_train_sc, columns=X.columns).describe().round(2)
print("\n" + "=" * 60)
print(" PASO 5: Normalización con StandardScaler")
print("=" * 60)
# --- ESCRIBE TU CÓDIGO AQUÍ ---
scaler = StandardScaler()
X_train_sc = scaler.fit_transform(X_train)
X_test_sc = scaler.transform(X_test)
# ─────────────────────────────────────────────────────────────────────────────
# PASO 6 — ENTRENAR EL MODELO
# ─────────────────────────────────────────────────────────────────────────────
#
# Entrenamos con X_train_sc (los datos normalizados), no con X_train.
#
# Con dos variables normalizadas, la fórmula aprendida será:
# tip = b₀ + b₁×total_bill_sc + b₂×size_sc
#
# Ahora los coeficientes b₁ y b₂ SÍ son directamente comparables:
# el mayor indica la variable que más influye en la propina.
#
# 💡 PISTA:
# modelo = LinearRegression()
# modelo.fit(X_train_sc, y_train)
#
# 🛠️ TU TURNO:
# 1. Crea el modelo y entrénalo con los datos normalizados.
# 2. Imprime los coeficientes junto al nombre de cada variable.
# Pista: zip(X.columns, modelo.coef_)
# 3. ¿Qué variable tiene el coeficiente más alto?
# Después de normalizar, eso sí que indica cuál importa más.
print("\n" + "=" * 60)
print(" PASO 6: Entrenamiento del modelo")
print("=" * 60)
# --- ESCRIBE TU CÓDIGO AQUÍ ---
modelo = LinearRegression()
modelo.fit(X_train_sc, y_train)
# ─────────────────────────────────────────────────────────────────────────────
# PASO 7 — EVALUAR EL MODELO
# ─────────────────────────────────────────────────────────────────────────────
#
# Calcula las predicciones sobre X_test_sc y luego las tres métricas:
# · R² → ¿qué porcentaje de la variación explica el modelo?
# · MAE → error medio en dólares
# · RMSE → igual que MAE pero penaliza más los errores grandes
#
# 💡 PISTA: El modelo simple (solo total_bill, sin normalizar) obtenía R² ≈ 0.46.
# ¿Mejora al usar dos variables normalizadas?
#
# 🛠️ TU TURNO:
# 1. Obtén y_pred con modelo.predict(X_test_sc).
# 2. Calcula r2, mae y rmse.
# 3. Imprime los resultados y compáralos con el modelo simple.
print("\n" + "=" * 60)
print(" PASO 7: Evaluación del modelo")
print("=" * 60)
# --- ESCRIBE TU CÓDIGO AQUÍ ---
y_pred = modelo.predict(X_test_sc)
r2 = r2_score(y_test, y_pred)
mae = mean_absolute_error(y_test, y_pred)
rmse = root_mean_squared_error(y_test, y_pred)
print(f" R² = {r2:.4f}")
print(f" MAE = {mae:.4f} $")
print(f" RMSE = {rmse:.4f} $")
print("\n ¿Mejoró respecto al modelo simple (R² ≈ 0.46)?")
Regresión lineal multivariable
import numpy as np # Operaciones numéricas y arrays
import pandas as pd # Manejo de tablas de datos (DataFrames)
import matplotlib.pyplot as plt # Gráficas
from sklearn.model_selection import train_test_split # Dividir datos en tren/test
from sklearn.linear_model import LinearRegression # Nuestro modelo
from sklearn.preprocessing import StandardScaler # Normalizar datos
from sklearn.metrics import mean_squared_error, r2_score
np.random.seed(42) # Fijamos semilla para reproducibilidad
n = 200 # Número de pisos en nuestro dataset
# Cada columna representa una característica del piso
data = pd.DataFrame({
'metros2' : np.random.randint(30, 150, n), # Entre 30 y 150 m²
'habitaciones': np.random.randint(1, 6, n), # Entre 1 y 5 habitaciones
'planta' : np.random.randint(0, 10, n), # Entre planta 0 y 9
'antiguedad' : np.random.randint(0, 50, n), # Años de antigüedad
})
# Fórmula ficticia para el precio (así sabemos cuál es la verdad)
# precio = 50k + 2000×m² + 8000×hab + 500×planta - 300×antigüedad + ruido
ruido = np.random.normal(0, 10000, n) # Variación aleatoria realista
data['precio'] = (
50000
+ 2000 * data['metros2']
+ 8000 * data['habitaciones']
+ 500 * data['planta']
- 300 * data['antiguedad']
+ ruido
)
print(data.head()) # Ver las primeras filas
# Aquí tenemos un dataset de 200 pisos con sus precios aleatorio pero siguiendo
# una fórmula que podemos predecir
# ─── Separar variables de entrada (X) y salida (y) ─────────────
X = data.drop(columns=['precio']) # Todo excepto el precio
y = data['precio'] # Solo el precio (lo que queremos predecir)
# ─── Dividir en entrenamiento (80%) y test (20%) ─────────────
X_train, X_test, y_train, y_test = train_test_split(
X, y, # Datos de entrada y salida
test_size=0.2, # 20% para test
random_state=42 # Semilla para resultados reproducibles
)
print(f'Datos de entrenamiento: {len(X_train)} pisos')
print(f'Datos de test: {len(X_test)} pisos')
# → Datos de entrenamiento: 160 pisos
# → Datos de test: 40 pisos
# ─── Normalizar los datos ──────────────────────────────────────
scaler = StandardScaler() # Creamos el normalizador
# fit_transform: aprende la media y std DE LOS DATOS DE ENTRENAMIENTO
# y luego transforma. NUNCA uses fit en los datos de test.
X_train_scaled = scaler.fit_transform(X_train)
# transform solo: aplica la misma transformación al test
# (sin volver a aprender — eso sería trampa)
X_test_scaled = scaler.transform(X_test)
modelo = LinearRegression() # Instanciar el modelo
# .fit() es donde ocurre el 'aprendizaje':
# el modelo encuentra los mejores coeficientes β
modelo.fit(X_train_scaled, y_train)
# Ver los coeficientes aprendidos
print('Intercepto (β₀):', modelo.intercept_)
for nombre, coef in zip(X.columns, modelo.coef_):
print(f' {nombre:<15}: {coef:>10.2f}')
y_pred = modelo.predict(X_test_scaled) # Predicciones
# R² (R-cuadrado): qué porcentaje de la variación explica el modelo
# Va de 0 a 1. Cuanto más cerca de 1, mejor.
r2 = r2_score(y_test, y_pred)
# RMSE: error promedio en las mismas unidades que y (euros)
# Fácil de interpretar: 'me equivoco en promedio X euros'
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
print(f'R² = {r2:.4f}') # p.ej. R² = 0.9812
print(f'RMSE = {rmse:.2f} €') # p.ej. RMSE = 9.847,23 €
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# --- Gráfico 1: Predicciones vs Valores reales ---
axes[0].scatter(y_test, y_pred, alpha=0.5, color='steelblue')
# La línea perfecta (y = x) sirve como referencia visual
axes[0].plot([y_test.min(), y_test.max()],
[y_test.min(), y_test.max()], 'r--', label='Predicción perfecta')
axes[0].set_xlabel('Precio real (€)')
axes[0].set_ylabel('Precio predicho (€)')
axes[0].set_title(f'Predicciones vs. Valores reales\nR² = {r2:.4f}')
axes[0].legend()
# --- Gráfico 2: Residuos (errores del modelo) ---
residuos = y_test - y_pred # Diferencia entre real y predicho
axes[1].scatter(y_pred, residuos, alpha=0.5, color='coral')
axes[1].axhline(0, color='black', linestyle='--') # Línea en 0
axes[1].set_xlabel('Precio predicho (€)')
axes[1].set_ylabel('Residuo (real - predicho)')
axes[1].set_title('Análisis de Residuos\n(idealmente dispersos sin patrón)')
plt.tight_layout() # Ajusta márgenes automáticamente
plt.savefig('resultados_regresion.png', dpi=150, bbox_inches='tight')
plt.show()
# ─── Predecir el precio de un piso nuevo ───────────────────────
# Creamos un DataFrame con las características del piso nuevo
# ¡Importante: usar los mismos nombres de columna que en el entrenamiento!
piso_nuevo = pd.DataFrame([{
'metros2' : 90, # 90 metros cuadrados
'habitaciones': 3, # 3 habitaciones
'planta' : 5, # Planta 5
'antiguedad' : 10, # 10 años de antigüedad
}])
# Normalizar usando el MISMO scaler que entrenamos (no fit_transform)
piso_nuevo_scaled = scaler.transform(piso_nuevo)
# Predecir
precio_estimado = modelo.predict(piso_nuevo_scaled)[0]
print(f'Precio estimado: {precio_estimado:,.0f} €')
# → Precio estimado: 250.500 € (resultado aproximado)
Gráficos
import matplotlib.pyplot as plt
# --- DATOS ---
# Estos son los datos que queremos representar.
# Cada elemento de 'ventas' corresponde a un mes.
meses = ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun']
ventas = [120, 145, 132, 178, 165, 200]
ventas2 = [150, 125, 162, 128, 105, 230]
# plt.subplots() crea dos cosas a la vez:
# fig → la figura (el lienzo completo)
# ax → los ejes (la zona de dibujo)
fig, ax = plt.subplots()
# --- DIBUJAR LA LÍNEA ---
# ax.plot(eje_x, eje_y) dibuja la línea.
# color → color de la línea (nombre o código hex)
# linewidth → grosor de la línea
# marker → símbolo en cada punto ('o' = círculo)
ax.plot(meses, ventas, color='blueviolet', linewidth=2, marker='p',label="Tienda A")
ax.plot(meses, ventas2,mfc='green', color='tomato', linewidth=2, marker='s', linestyle='--', label="Tienda B")
ax.legend(loc='upper left', fontsize=10)
# --- ETIQUETAS Y TÍTULO ---
ax.set_title('Ventas mensuales') # Título de la gráfica
ax.set_xlabel('Mes') # Etiqueta del eje horizontal
ax.set_ylabel('Unidades vendidas') # Etiqueta del eje vertical
# --- CUADRÍCULA ---
# La cuadrícula facilita leer los valores.
# linestyle='--' → líneas discontinuas
# alpha=0.4 → 40% de opacidad (líneas sutiles)
ax.grid(True, linestyle='--', alpha=0.4)
# --- MOSTRAR ---
plt.tight_layout() # Ajusta márgenes automáticamente
plt.savefig('ejemplo.png', dpi=150, bbox_inches='tight')
# plt.show() abre la ventana y muestra el resultado
plt.show()
Ejercicio métricas
# ================================================================
# EJERCICIO PRÁCTICO: Evaluación de Modelos de Predicción
# de Ventas con Métricas de Regresión
# ================================================================
#
# CONTEXTO:
# Una cafetería registró sus ventas diarias (en €) durante
# 30 días. Dos modelos intentaron predecir esas ventas:
# - Modelo A: regresión lineal simple
# - Modelo B: red neuronal experimental
#
# Tu misión: calcular las métricas, interpretar los resultados
# y decidir qué modelo recomendarías al dueño de la cafetería.
#
# ================================================================
import numpy as np
import matplotlib.pyplot as plt
# ----------------------------------------------------------------
# DATOS: 30 días de ventas reales y predicciones de cada modelo
# ----------------------------------------------------------------
dias = list(range(1, 31)) # Días del mes (1 al 30)
# Ventas reales registradas en la caja (en €)
ventas_reales = [
312, 298, 341, 287, 305, 198, 210, # Semana 1 (fin de semana bajo)
330, 315, 352, 298, 341, 215, 224, # Semana 2
345, 318, 361, 302, 349, 231, 228, # Semana 3
358, 334, 372, 315, 360, 244, 237, # Semana 4
365, 348 # Últimos 2 días del mes
]
# Predicciones del Modelo A (regresión lineal, más estable)
predicciones_modelo_A = [
308, 301, 338, 291, 309, 205, 214,
325, 318, 347, 303, 338, 221, 220,
340, 322, 355, 308, 344, 226, 232,
352, 330, 368, 319, 355, 240, 242,
361, 344
]
# Predicciones del Modelo B (sobreajustado en semanas centrales)
predicciones_modelo_B = [
295, 275, 360, 270, 325, 185, 240,
310, 340, 330, 285, 365, 200, 245,
325, 340, 340, 290, 370, 210, 255,
340, 350, 350, 300, 385, 225, 265,
350, 335
]
# ================================================================
# SECCIÓN 1 — CÁLCULO DE MÉTRICAS
# ================================================================
# Completa cada celda marcada con ??? usando sklearn o numpy.
# Pista: todas las funciones están en sklearn.metrics
# Documentación: https://scikit-learn.org/stable/modules/model_evaluation.html
# ================================================================
from sklearn.metrics import mean_squared_error # MSE
from sklearn.metrics import mean_absolute_error # MAE
from sklearn.metrics import root_mean_squared_error # RMSE
from sklearn.metrics import r2_score # R²
print("=" * 55)
print(" MÉTRICAS DE EVALUACIÓN — VENTAS 30 DÍAS")
print("=" * 55)
# ---- 1.1 MSE -----------------------------------------------
# Pista: mean_squared_error(valores_reales, valores_predichos)
# Un MSE menor indica mejor ajuste.
# ¿Qué ocurre si un día el modelo falla por 50 €?
# Ese error pesa 50² = 2500 en el MSE.
mse_A = ??? # Calcula el MSE del Modelo A
mse_B = ??? # Calcula el MSE del Modelo B
print(f"\nMSE → Modelo A: {mse_A:.2f} | Modelo B: {mse_B:.2f}")
# ---- 1.2 MAE -----------------------------------------------
# Pista: mean_absolute_error(valores_reales, valores_predichos)
# A diferencia del MSE, todos los errores pesan igual.
# Un MAE de 15 significa: "me equivoco ~15 € por día de media".
mae_A = ??? # Calcula el MAE del Modelo A
mae_B = ??? # Calcula el MAE del Modelo B
print(f"MAE → Modelo A: {mae_A:.2f} | Modelo B: {mae_B:.2f}")
# ---- 1.3 RMSE ----------------------------------------------
# Pista: root_mean_squared_error(valores_reales, valores_predichos)
# Es la raíz cuadrada del MSE → devuelve el error en euros (€),
# igual que los datos originales. Más fácil de interpretar.
rmse_A = ??? # Calcula el RMSE del Modelo A
rmse_B = ??? # Calcula el RMSE del Modelo B
print(f"RMSE → Modelo A: {rmse_A:.2f} | Modelo B: {rmse_B:.2f}")
# ---- 1.4 R² ------------------------------------------------
# Pista: r2_score(valores_reales, valores_predichos)
# Mide qué porcentaje de la variación en ventas explica el modelo.
# R² = 1 → perfecto | R² = 0 → igual que predecir siempre la media.
r2_A = ??? # Calcula el R² del Modelo A
r2_B = ??? # Calcula el R² del Modelo B
print(f"R² → Modelo A: {r2_A:.4f} | Modelo B: {r2_B:.4f}")
print("\n" + "=" * 55)
# ================================================================
# SECCIÓN 2 — GRÁFICA DE AJUSTE
# ================================================================
# Aquí tienes la estructura completa de la gráfica.
# Descomentar el bloque cuando tengas las métricas calculadas.
# ================================================================
# x = np.array(dias)
# fig, axes = plt.subplots(2, 1, figsize=(14, 9))
# fig.suptitle("Comparativa de Modelos — Ventas Diarias Cafetería", fontsize=14, fontweight="bold")
#
# # --- Subgráfica superior: líneas de ajuste ---
# ax1 = axes[0]
# ax1.plot(x, ventas_reales, "o-", color="#2C3E50", lw=2.5, ms=5, label="Ventas Reales")
# ax1.plot(x, predicciones_modelo_A,"s--", color="#2980B9", lw=1.8, ms=4, label=f"Modelo A (RMSE={rmse_A:.1f} €)")
# ax1.plot(x, predicciones_modelo_B,"^--", color="#E74C3C", lw=1.8, ms=4, label=f"Modelo B (RMSE={rmse_B:.1f} €)")
# ax1.fill_between(x, ventas_reales, predicciones_modelo_A, alpha=0.12, color="#2980B9")
# ax1.fill_between(x, ventas_reales, predicciones_modelo_B, alpha=0.12, color="#E74C3C")
# ax1.set_ylabel("Ventas (€)")
# ax1.set_xticks(x)
# ax1.set_xticklabels([f"D{d}" for d in dias], fontsize=7, rotation=45)
# ax1.legend(); ax1.grid(True, linestyle="--", alpha=0.4)
#
# # --- Subgráfica inferior: error absoluto por día ---
# error_A = [abs(r - p) for r, p in zip(ventas_reales, predicciones_modelo_A)]
# error_B = [abs(r - p) for r, p in zip(ventas_reales, predicciones_modelo_B)]
# ancho = 0.35
# ax2 = axes[1]
# ax2.bar(x - ancho/2, error_A, width=ancho, color="#2980B9", alpha=0.8, label="Error diario Modelo A")
# ax2.bar(x + ancho/2, error_B, width=ancho, color="#E74C3C", alpha=0.8, label="Error diario Modelo B")
# ax2.axhline(y=mae_A, color="#1A5276", linestyle="--", lw=1.5, label=f"MAE Modelo A = {mae_A:.1f} €")
# ax2.axhline(y=mae_B, color="#922B21", linestyle="--", lw=1.5, label=f"MAE Modelo B = {mae_B:.1f} €")
# ax2.set_xlabel("Día del mes")
# ax2.set_ylabel("Error absoluto (€)")
# ax2.set_xticks(x)
# ax2.set_xticklabels([f"D{d}" for d in dias], fontsize=7, rotation=45)
# ax2.legend(); ax2.grid(True, axis="y", linestyle="--", alpha=0.4)
#
# plt.tight_layout()
# plt.savefig("ajuste_ventas.png", dpi=150, bbox_inches="tight")
# plt.show()
# ================================================================
# SECCIÓN 3 — PREGUNTAS DE REFLEXIÓN
# ================================================================
# Responde a continuación como comentarios de Python (#).
# No hay una única respuesta correcta; razona tu decisión.
# ================================================================
# PREGUNTA 1 ── ¿Qué modelo tiene menor MSE?
# ¿Por qué crees que el MSE es más sensible a errores grandes
# que el MAE? Piensa en qué ocurre matemáticamente al elevar al
# cuadrado un error de 50 € frente a uno de 5 €.
#
# Tu respuesta:
#
# ─────────────────────────────────────────────────────────────
# PREGUNTA 2 ── Si el MAE de ambos modelos fuese muy similar
# pero el MSE fuese muy distinto, ¿qué nos estaría indicando
# sobre la distribución de los errores de cada modelo?
# Pista: piensa en días concretos donde un modelo falla mucho.
#
# Tu respuesta:
#
# ─────────────────────────────────────────────────────────────
# PREGUNTA 3 ── El dueño de la cafetería puede asumir errores
# pequeños cotidianos, pero le resulta muy perjudicial quedarse
# sin stock un día puntual por una predicción muy mala.
# ¿Qué métrica debería priorizar para elegir el modelo?
# ¿MSE/RMSE o MAE? Justifica tu respuesta.
#
# Tu respuesta:
#
# ─────────────────────────────────────────────────────────────
# PREGUNTA 4 ── Interpreta el valor de R² de cada modelo.
# ¿Un R² de 0.95 significa que el modelo predice bien siempre?
# ¿Podría haber algún día donde falle mucho y aun así tener
# un R² alto globalmente?
#
# Tu respuesta:
#
# ─────────────────────────────────────────────────────────────
# PREGUNTA 5 ── DECISIÓN FINAL
# Con los valores que has calculado, ¿qué modelo recomendarías
# al dueño de la cafetería y por qué?
# Menciona al menos dos métricas en tu argumento.
#
# Tu respuesta:
#
# ================================================================
# FIN DEL EJERCICIO
# ================================================================
Comparaciones métricas
# =============================================================
# COMPARACIÓN DE MÉTRICAS ENTRE DOS MODELOS
# =============================================================
# Este script compara las predicciones de dos modelos frente
# a los valores reales usando MSE, MAE y RMSE, y genera una
# gráfica para visualizar el ajuste de cada modelo.
# =============================================================
# Valores predichos por cada modelo para 4 observaciones
modelo1 = [20, 22, 23, 24] # Modelo 1: predicciones más conservadoras
modelo2 = [21, 24, 26, 24] # Modelo 2: predicciones más variables
real = [21, 24, 20, 31] # Valores reales que queremos acertar
# -------------------------------------------------------------
# MSE — Error Cuadrático Medio
# Eleva cada error al cuadrado antes de promediar, por lo que
# penaliza más los errores grandes. Unidades: valor² (ej: €²)
# -------------------------------------------------------------
from sklearn.metrics import mean_squared_error
mse1 = mean_squared_error(real, modelo1) # MSE del modelo 1
mse2 = mean_squared_error(real, modelo2) # MSE del modelo 2
print(f"MSE → Modelo1: {mse1:.2f} | Modelo2: {mse2:.2f}")
# -------------------------------------------------------------
# MAE — Error Absoluto Medio
# Promedio de los errores en valor absoluto. No penaliza tanto
# los errores grandes; más robusto ante outliers. Unidades: las
# mismas que los datos originales.
# -------------------------------------------------------------
from sklearn.metrics import mean_absolute_error
mae1 = mean_absolute_error(real, modelo1)
mae2 = mean_absolute_error(real, modelo2)
print(f"MAE → Modelo1: {mae1:.2f} | Modelo2: {mae2:.2f}")
# -------------------------------------------------------------
# RMSE — Raíz del Error Cuadrático Medio
# Es la raíz cuadrada del MSE. Devuelve el error en las mismas
# unidades que los datos originales, siendo más interpretable
# que el MSE pero manteniendo la penalización de errores grandes.
# -------------------------------------------------------------
from sklearn.metrics import root_mean_squared_error
rmse1 = root_mean_squared_error(real, modelo1)
rmse2 = root_mean_squared_error(real, modelo2)
print(f"RMSE → Modelo1: {rmse1:.2f} | Modelo2: {rmse2:.2f}")
# =============================================================
# GRÁFICA: Ajuste de los modelos a los datos reales
# =============================================================
import matplotlib.pyplot as plt
import numpy as np
# Eje X: índices de las 4 observaciones (puntos de tiempo o muestras)
x = np.arange(1, len(real) + 1) # [1, 2, 3, 4]
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
fig.suptitle("Ajuste de Modelos vs. Datos Reales", fontsize=15, fontweight="bold", y=1.01)
# ---- Colores ----
COLOR_REAL = "#2C3E50"
COLOR_M1 = "#2980B9"
COLOR_M2 = "#E74C3C"
COLOR_ERROR1 = "#AED6F1"
COLOR_ERROR2 = "#F1948A"
# ----------------------------------------------------------
# Subgráfica izquierda: líneas de los tres conjuntos
# ----------------------------------------------------------
ax1 = axes[0]
ax1.plot(x, real, "o-", color=COLOR_REAL, linewidth=2.5, markersize=8, label="Valores Reales", zorder=3)
ax1.plot(x, modelo1, "s--", color=COLOR_M1, linewidth=2, markersize=7, label=f"Modelo 1 (MSE={mse1:.1f})")
ax1.plot(x, modelo2, "^--", color=COLOR_M2, linewidth=2, markersize=7, label=f"Modelo 2 (MSE={mse2:.1f})")
# Sombrear el área de error de cada modelo respecto a los reales
ax1.fill_between(x, real, modelo1, alpha=0.15, color=COLOR_M1, label="Error Modelo 1")
ax1.fill_between(x, real, modelo2, alpha=0.15, color=COLOR_M2, label="Error Modelo 2")
ax1.set_title("Líneas de ajuste y área de error", fontsize=12)
ax1.set_xlabel("Observación")
ax1.set_ylabel("Valor")
ax1.set_xticks(x)
ax1.set_xticklabels([f"Obs {i}" for i in x])
ax1.legend(fontsize=9)
ax1.grid(True, linestyle="--", alpha=0.5)
ax1.set_ylim(15, 36)
# ----------------------------------------------------------
# Subgráfica derecha: barras comparativas de métricas
# ----------------------------------------------------------
ax2 = axes[1]
metricas = ["MSE", "MAE", "RMSE"]
valores_m1 = [mse1, mae1, rmse1]
valores_m2 = [mse2, mae2, rmse2]
ancho = 0.3
pos = np.arange(len(metricas))
bars1 = ax2.bar(pos - ancho/2, valores_m1, width=ancho, color=COLOR_M1,
label="Modelo 1", edgecolor="white", linewidth=0.8)
bars2 = ax2.bar(pos + ancho/2, valores_m2, width=ancho, color=COLOR_M2,
label="Modelo 2", edgecolor="white", linewidth=0.8)
# Etiquetar el valor encima de cada barra
for bar in bars1:
ax2.text(bar.get_x() + bar.get_width() / 2, bar.get_height() + 0.2,
f"{bar.get_height():.2f}", ha="center", va="bottom", fontsize=9, color=COLOR_M1, fontweight="bold")
for bar in bars2:
ax2.text(bar.get_x() + bar.get_width() / 2, bar.get_height() + 0.2,
f"{bar.get_height():.2f}", ha="center", va="bottom", fontsize=9, color=COLOR_M2, fontweight="bold")
ax2.set_title("Comparativa de métricas de error", fontsize=12)
ax2.set_ylabel("Valor del error")
ax2.set_xticks(pos)
ax2.set_xticklabels(metricas, fontsize=11)
ax2.legend(fontsize=10)
ax2.grid(True, axis="y", linestyle="--", alpha=0.5)
plt.tight_layout()
plt.savefig("ajuste_modelos.png", dpi=150, bbox_inches="tight")
plt.show()
print("Gráfica guardada en ajuste_modelos.png")
MSE
predicho=[20,22,23,24]
real=[21,24,20,31]
total=0
for i in range(4):
total+=(predicho[i]-real[i])**2
mse=total/4
print(mse)
import numpy as np
pred=np.array(predicho)
obs=np.array(real)
cuadraticos=(pred-real)**2
print(cuadraticos)
mse=np.mean(cuadraticos)
print(mse)
from sklearn.metrics import mean_squared_error
mse=mean_squared_error(real,pred)
print(mse)
Y más regresiones
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
metros_cuadrados = [
40, 42, 45, 48, 50, 52, 55, 58, 60, 62,
65, 68, 70, 72, 75, 78, 80, 82, 85, 88,
90, 92, 95, 98, 100, 102, 105, 108, 110, 112,
115, 118, 120, 122, 125, 128, 130, 132, 135, 138,
140, 142, 145, 148, 150, 152, 155, 158, 160, 165
]
precio_miles_euros = [
120, 125, 128, 135, 140, 145, 150, 158, 160, 168,
175, 180, 185, 190, 198, 205, 210, 215, 223, 230,
235, 240, 248, 255, 260, 265, 273, 280, 285, 290,
298, 305, 310, 315, 323, 330, 335, 340, 348, 355,
360, 365, 373, 380, 385, 390, 398, 405, 410, 425
]
x = np.array(metros_cuadrados).reshape(-1, 1)
y = np.array(precio_miles_euros)
# Datos de entrenamiento y pruebas (split)
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)
# Crear modelo y entrenar (fit)
model = LinearRegression()
model.fit(X_train, y_train)
print(f"Pendiente {model.coef_} intercepto {model.intercept_}")
# Predecir datos de test
y_pred = model.predict(X_test)
print(y_test)
print(y_pred.round(0))
# Métricas de errores
print(mean_absolute_error(y_test, y_pred))
print(mean_squared_error(y_test, y_pred))
print(r2_score(y_test, y_pred))