En este tutorial vamos a ver cómo se utilizan un modelo de regresión logística en Machine Learning y vamos a explorar varias maneras de entrenarlo en Python.
Primero lo contruiremos desde cero y paso a paso utilizando Numpy y después vemos cómo hacerlo de una manera mucho más directa gracias a la librería de Scikit learn.
El modelo de regresión logística se utiliza normalmente para resolver problemas de clasificación.
En este tipo de problemas el objetivo es saber a qué clase pertenece nuestra observación.
Es decir, el modelo va a devolver una respuesta discreta. Una opción.
Puede ser sí
o no
.
Puede ser Spam
o No spam
.
Puede ser la especie de un pingüino. Ya sea la especie de pingüino Adélie
, la especie Gentoo
o la especie Chinstrap
.
Pero antes de soltarte toda la turra teórica de estos modelos, decirte que puedes pasar directamente al ejemplo de clasificar pingüinos aquí 🐧
La regresión logística binaria es aquella en la que hay que clasificar la observación en una de las dos clases que tenemos disponibles.
Si tuvieras un conjunto de datos como el de la imagen, en el que representamos la especie de los pingüinos que viven en el archipiélago de Palmer en función de la longitud de su pico, podrías decirme fácilmente la especie si yo te digo cuánto mide el pico del pingüino.
Para conseguir que lo que tú has hecho de manera visual y muy rápida lo haga un modelo de Machine Learning necesitamos a la función sigmoide (que es la línea rosa en forma de S
en la imagen).
La función sigmoide o logística convierte cualquier número real (positivo o negativo) a un valor entre 0 y 1. Esto nos viene genial para poder obtener una clase a partir de una característica de nuestro dataset (en este caso la longitud del pico del pingüino 🐧).
Cuando el valor de entrada de la función sigmoide es muy grande, la salida se acerca mucho a 1. Es decir, que cuanto mayor es la longitud del pico del pingüino, más probable es que estemos ante un pingüino Gentoo.
De la misma manera, cuánto menor sea la entrada a la función sigmoide, la salida estará más próxima a 0.
O sea, que cuanto más corto sea el pico del pingüino, más probable será que sea un pingüino Adélie.
Como ves, gracias a la función sigmoide, somos capaces de trasladar la relación lineal de las características (la longitud del pico) con nuestra variable objetivo, que es discreta, (la especie) y resolver el problema de clasificación.
La función sigmoide adapta la regresión lineal para clasificación, y así podemos trabajar con probabilidades (salida de la función entre 0 y 1) en lugar de con valores continuos.
Como ves la regresión logística está muy relacionada con la regresión lineal así que te recomiendo que eches un vistazo al tutorial sobre regresión lineal si no lo has hecho todavía.
En resumen, la regresión logística binaria es un método estadístico que nos permite predecir la probabilidad de que una observación pertenezca a una de dos clases.
El modelo produce una salida que es la probabilidad de que la observación pertenezca a la clase positiva (1
).
Esta probabilidad se calcula usando la función sigmoide aplicada a una combinación lineal de las características.
Una regresión logística binaria predice la probabilidad de que una observación pertenezca a una de dos categorías posibles. Por ejemplo, podría predecir si un paciente tiene o no una cierta enfermedad (categorías: enfermedad o sin enfermedad) basándose en ciertos indicadores o características.
En este ejemplo vamos a clasificar pingüinos 🐧
Vamos a utilizar un dataset simplificado de los datos recogidos sobre la población de pingüinos en el archipiélago de Palmer, cerca de la Antártida y un Notebook de Google Colab. No es necesario que te instales nada, solo te hace falta una cuenta en Google 🙂
Así que te aconsejo que vayas siguiendo el tutorial en tu propio Notebook de Colab, será bastante más divertido que sólo leer 😉
Para poder utilizar el dataset directamente en Google Colab sólo tienes que seguir este tutorial y sustituir el dataset que se descarga en ese tutorial por el que realmente queremos utilizar aquí.
!kaggle datasets download -d martaarroyo/palmer-penguins-for-binary-classification
El dataset está simplificado porque, para que estuviéramos ante un problema de clasificación binaria, he eliminado las observaciones de los pingüinos Chinstrap (🥲).
Lo vamos a simplificar aún más para centrar el foco a tope en la regresión logística y nos vamos a quedar únicamente con dos características:
bill_length_mm
)bill_depth_mm
)Y vamos a transformar el dataset en un array de Numpy.
import numpy as np import pandas as pd import math # data es nuestro dataset -> data = pd.read_csv('penguins_binary_classification.csv') X = data[['bill_length_mm','bill_depth_mm']].to_numpy() # Transformamos el dataset a una matriz Numpy
La columna que queremos clasificar es la especie del pingüino (species
), que es una columna de texto.
Como el modelo de regresión logística únicamente admite variables numéricas primero tendremos que codificarla:
y = pd.get_dummies(data['species'], drop_first= True) # y = 0 -> Adelie # y = 1 -> Gentoo y = y['Gentoo'].to_numpy()
Siempre recomiendo hacer una exploración de los datos (aunque sea mínima).
Vamos a ver los primeros elementos de nuestro dataset y cerciorarnos de que son arrays de Numpy:
print("Primeros 5 elementos de nuestro dataset:\n", X[:5]) print("Tipo de X:",type(X))
Lo mismo para el vector de etiquetas:
print("Primeros 5 elementos del vector de etiquetas:\n", y[:5]) print("Tipo de y:",type(y))
También es importante tener claras las dimensiones de los datos con los que estamos trabajando y cuantas observaciones tenemos:
print ('Las dimensiones de X son: ' + str(X.shape)) print ('Las dimensiones de y son: ' + str(y.shape)) print ('Tenemos m = %d muestras de entrenamiento' % (len(y)))
Vamos a ver ahora de manera gráfica cómo se clasificarían los pingüinos en función de las dimensiones de su pico 🐧
import matplotlib.pyplot as plt %matplotlib inline # Buscamos los índices en los que la etiqueta es positiva y negativa pos = y == 1 neg = y == 0 #Representamos los pingüinos plt.plot(X[pos, 0], X[pos, 1], 'k+', label="Gentoo") plt.plot(X[neg, 0], X[neg, 1], 'yo', label="Adelie") # Etiqueta eje y plt.ylabel('bill_depth_mm') # Etiqueta eje X plt.xlabel('bill_length_mm') plt.legend(loc="upper right") plt.show()
Parece bastante claro dónde dibujaríamos la frontera entre una especie y la otra ¿verdad?
¡Pues vamos al lío!
La regresión lineal está diseñada para predecir valores continuos. Por ejemplo, se usa para predecir el precio de una casa o la temperatura.
Por otro lado, la regresión logística se utiliza en problemas de clasificación, donde el objetivo es predecir categorías binarias.
Es decir, saber a qué clase pertenece nuestra observación y lo que obtenemos de un modelo de regresión logística es la probabilidad de que la observación pertenezca a una de las clases.
Las probabilidades siempre toman valores entre 0 y 1.
Cuando se usa la regresión lineal en un problema de clasificación, el modelo puede predecir valores fuera del rango [0,1], lo que no tiene sentido en un problema de clasificación binaria.
En la clasificación, es útil entender la probabilidad de que una observación pertenezca a una clase particular, algo que la regresión logística puede proporcionar pero la regresión lineal no.