Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Updated: 31 aug 2026

Modelo: Logistic Regression

Este proyecto usa un dataset real de calidad de vino tinto.
La idea es clasificar si un vino puede considerarse de buena calidad usando pocas variables químicas.

Este proyecto puede conectar con:

  • Química: acidez, alcohol, sulfatos, densidad.

  • Matemáticas: clasificación binaria, proporciones, evaluación de modelos.

  • Ciencias: relación entre propiedades medibles y calidad.

Pregunta del proyecto

¿Podemos clasificar si un vino es de buena calidad usando algunas propiedades químicas?

Modelo que usarás

LogisticRegression

Variables sugeridas

Features X:

  • alcohol

  • volatile acidity

  • sulphates

  • density

Target y:

  • good_quality

Donde:

  • 1: vino de buena calidad

  • 0: vino de calidad regular

Paso 1: Importar librerías

import pandas as pd
import matplotlib.pyplot as plt

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, ConfusionMatrixDisplay

print("Librerías cargadas correctamente.")
Librerías cargadas correctamente.

Paso 2: Cargar la data

Ejecuta la celda.
El dataset se cargará desde UCI Machine Learning Repository.

url = "https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv"

df = pd.read_csv(url, sep=";")

df.head()
Loading...

Paso 3: Explorar rápidamente la data

df.shape
(1599, 12)
df[["alcohol", "volatile acidity", "sulphates", "density", "quality"]].describe()
Loading...

Paso 4: Crear la variable objetivo

La columna original quality va de valores bajos a altos.

Para convertir esto en clasificación binaria, crearemos:

good_quality = 1 si quality >= 6
good_quality = 0 si quality < 6

Ejecuta la celda.

df["good_quality"] = (df["quality"] >= 6).astype(int)

df[["quality", "good_quality"]].head(10)
Loading...

Paso 5: Visualizar la variable objetivo

df["good_quality"].value_counts().plot(kind="bar")

plt.title("Distribución de calidad del vino")
plt.xlabel("0 = regular, 1 = buena calidad")
plt.ylabel("Cantidad")
plt.show()
<Figure size 640x480 with 1 Axes>

Paso 6: Visualizar alcohol vs calidad

Observa si el alcohol parece estar relacionado con la calidad.

plt.figure(figsize=(8,5))
plt.scatter(df["alcohol"], df["good_quality"], alpha=0.2)
plt.xlabel("Alcohol")
plt.ylabel("Buena calidad")
plt.title("Alcohol vs calidad")
plt.show()
<Figure size 800x500 with 1 Axes>

Paso 7: Definir features y target

Completa la celda.

Features sugeridas:

["alcohol", "volatile acidity", "sulphates", "density"]

Target:

"good_quality"
X = df[[___, ___, ___, ___]]
y = df[___]

X.head()
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Cell In[8], line 1
----> 1 X = df[[___, ___, ___, ___]]
      2 y = df[___]
      3 
      4 X.head()

File /opt/hostedtoolcache/Python/3.12.14/x64/lib/python3.12/site-packages/pandas/core/frame.py:4384, in DataFrame.__getitem__(self, key)
   4380                 indexer = [indexer]
   4381         else:
   4382             if is_iterator(key):
   4383                 key = list(key)
-> 4384             indexer = self.columns._get_indexer_strict(key, "columns")[1]
   4385 
   4386         # take() does not accept boolean indexers
   4387         if getattr(indexer, "dtype", None) == bool:

File /opt/hostedtoolcache/Python/3.12.14/x64/lib/python3.12/site-packages/pandas/core/indexes/base.py:6302, in Index._get_indexer_strict(self, key, axis_name)
   6299 else:
   6300     keyarr, indexer, new_indexer = self._reindex_non_unique(keyarr)
-> 6302 self._raise_if_missing(keyarr, indexer, axis_name)
   6304 keyarr = self.take(indexer)
   6305 if isinstance(key, Index):
   6306     # GH 42790 - Preserve name from an Index

File /opt/hostedtoolcache/Python/3.12.14/x64/lib/python3.12/site-packages/pandas/core/indexes/base.py:6352, in Index._raise_if_missing(self, key, indexer, axis_name)
   6350 if nmissing:
   6351     if nmissing == len(indexer):
-> 6352         raise KeyError(f"None of [{key}] are in the [{axis_name}]")
   6354     not_found = list(ensure_index(key)[missing_mask.nonzero()[0]].unique())
   6355     raise KeyError(f"{not_found} not in index")

KeyError: "None of [Index([(1599, 12), (1599, 12), (1599, 12), (1599, 12)], dtype='object')] are in the [columns]"

Paso 8: Dividir entrenamiento y prueba

Completa usando:

test_size=0.25
random_state=42
stratify=y
X_train, X_test, y_train, y_test = train_test_split(
    ___,
    ___,
    test_size=___,
    random_state=___,
    stratify=___
)

print("Datos de entrenamiento:", X_train.shape)
print("Datos de prueba:", X_test.shape)

Paso 9: Crear y entrenar el modelo

Completa usando LogisticRegression.

Pista:

modelo = LogisticRegression(max_iter=1000)
modelo.fit(X_train, y_train)
modelo = ___

modelo.___(x_train, Y_train)

print("Modelo entrenado correctamente.")

Paso 10: Hacer predicciones

Debes completar la línea usando .predict().

y_pred = modelo.___(x_train)

resultados = pd.DataFrame({
    "Real": y_test.values,
    "Predicción": y_pred
})

resultados.head(10)

Paso 11: Evaluar accuracy

Encuentra y corrige el error

accuracy = Accuracy_score(y_test, y_pred)

print(f"Accuracy del modelo: {accuracy:.2f}")

Paso 12: Matriz de confusión

ConfusionMatrixDisplay.from_predictions(
    y_test,
    y_pred
)

plt.title("Matriz de confusión - Calidad del vino")
plt.show()

Paso 13: Probar un vino nuevo

Completa los valores del vino nuevo.
Debe tener las mismas columnas que X.

Ejemplo de columnas:

  • alcohol

  • volatile acidity

  • sulphates

  • density

vino_nuevo = pd.DataFrame({
    "alcohol": [___],
    "volatile acidity": [___],
    "sulphates": [___],
    "density": [___]
})

prediccion = modelo.predict(vino_nuevo)

print("Predicción:", prediccion[0])
print("0 = calidad regular, 1 = buena calidad")

Conclusión

Escribe una conclusión breve:

  • ¿Qué intentaba clasificar el modelo?

  • ¿Qué features usaste?

  • ¿Qué accuracy obtuvo?

  • ¿El modelo fue capaz de identificar patrones químicos relacionados con la calidad?

Nota

Este proyecto usa pocas variables químicas.
Los resultados pueden mejorar si se agregan más features, pero aquí la meta es practicar clasificación binaria con Logistic Regression.