Herramientas de usuario

Herramientas del sitio


clase:ia:saa:2eval:reduccion_dimensionalidad

08 - Reducción de la dimensionalidad 1: Métodos de filtro

En el aprendizaje automático, la selección de características importantes en los datos es una parte importante del ciclo completo.

El entrenamiento del modelo con características irrelevantes puede afectar el rendimiento del modelo. Para evitarlo, se utilizan métodos de reducción de la dimensionalidad.

Existen varios tipos:

  • Métodos de filtro (filter methods): Selecciona características de manera independiente al algoritmo de ML que será utilizado. Realizan una clasificación de las características mediante una función que asigna una valor a cada una de ellas según su importancia para el modelo. Posteriormente, se eligen aquellas características más relevantes. Tienen un coste computacional bajo.

  • Métodos de envoltura (wrapper methods): Aplica un algoritmo de ML e itera haciendo todas las combinaciones de variables posibles (entre ellas y en número) para finalmente quedarse con aquella combinación que de mejor resultado en las métricas. Consume muchos recursos computacionales.

  • Métodos integrados (embedded methods): La selección de características más relevantes se hace durante la fase de entrenamiento, y esta selección depende de cada modelo. Tienen un coste computacional menor que los métodos de envoltura. Los veremos con detalle en el apartado regularización.

  • Métodos híbridos (hybrid methods): Combinan métodos de filtro y de envoltura. Obtienen mejores resultados que los métodos de filtro, pero no son tan rápidos. Por otra parte, tienen un coste computacional más bajo que los métodos de envoltura.

Métodos de filtro

Dos categorías:

  • Métodos de filtro univariante: Las características de clasifican según criterios específicos de forma individual. A continuación, se seleccionan las N características más relevantes. Se utilizan para eliminar características constantes (o cuasi constantes) de los datos, pero pueden seleccionar características redundantes porque la relación entre características individuales no se tiene en cuenta al tomar decisiones.

  • Métodos de filtro multivariante: Son capaces de eliminar características redundantes de los datos, ya que tienen en cuenta la relación mutua entre las características. Se pueden utilizar métodos de filtro multivariante para eliminar características duplicadas y correlacionadas de los datos.

Vamos a ver ejemplos de algunos métodos de filtro univariante y multivariante.

Métodos de filtro univariante

Para este ejemplo, utilizaremos un conjunto de datos de satisfacción de clientes del Santander.

Primero importamos las bibliotecas necesarias y cargamos los datos (cargamos sólo los primeros 40.000 datos):

import pandas as pd
import numpy as np

from sklearn.model_selection import train_test_split

from sklearn.feature_selection import VarianceThreshold

# Configuración warnings
# ==============================================================================
import warnings
warnings.filterwarnings('ignore')

datos = pd.read_csv("santander.csv", nrows=40000)
datos.shape

(40000, 371)

Como vemos, el dataset contiene 40.000 datos con 371 variables (370 características y nuestra variable objetivo, que, en este caso, es la columna TARGET).

Antes de nada, es importante separar siempre los datos en entrenamiento y test para evitar el sobreajuste.

X = datos.drop(columns = 'TARGET', axis = 1)
y = datos['TARGET']

X_train, X_test, y_train, y_test = train_test_split(X, y, train_size   = 0.7)

Para saber las características constantes (varianza 0), vamos a usar la función VarianceThreshold de la librería sklearn. Esta función, selecciona las características eliminando las que tienen una varianza por debajo de un umbral (en este caso, 0). Primero tenemos que crear el filtro, y después aplicarlo a nuestros datos de entrenamiento.

constant_filter = VarianceThreshold(threshold=0)

constant_filter.fit(X_train)

Para obtener todas las características que no son constantes, podemos usar la función get_support() del filtro que creamos.

len(X_train.columns[constant_filter.get_support()])

301

Como vemos, hay 301 características no constantes, con lo que tenemos 69 que sí lo son. Finalmente, para eliminar características constantes de los conjuntos de entrenamiento y prueba, podemos usar el método transform() del filtro.

X_train = constant_filter.transform(X_train)
X_test = constant_filter.transform(X_test)

X_train.shape, X_test.shape

((28000, 301), (12000, 301))

Si quisiéramos eliminar las características cuasi constantes, podemos variar el umbral del filtro:

constant_filter = VarianceThreshold(threshold=0.1)

constant_filter.fit(X_train)

len(X_train.columns[constant_filter.get_support()])

204

X_train = constant_filter.transform(X_train)
X_test = constant_filter.transform(X_test)

X_train.shape, X_test.shape

((28000, 204), (12000, 204))

No existe una regla sobre cuál debería ser el umbral para la varianza de las características cuasi constantes. Sin embargo, como regla general, se eliminan aquellas características que tengan valores similares en más del 99%.

Métodos de filtro multivariante

Vamos a ver un ejemplo de método de filtro multivariante, eliminando características que están altamente correlacionadas entre sí.

En este caso, vamos a utilizar el dataset wine de la librería sklearn. Importamos las librerías, cargamos los datos y separamos test y entrenamiento.

import pandas as pd
import numpy as np

import matplotlib.pyplot as plt
import seaborn as sns

from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split

# Configuración warnings
# ==============================================================================
import warnings
warnings.filterwarnings('ignore')

data = load_wine()
df = pd.DataFrame(data = data.data, columns = data.feature_names)
df['class'] = data.target
df.shape

(178, 14)

Nuestro conjunto de datos tiene 178 registros con 13 características (más nuestra variable objetivo, que es class).

X = df.drop(columns = 'class', axis = 1)
y = df['class']

X_train, X_test, y_train, y_test = train_test_split(X, y, train_size   = 0.7)

Primero, sacamos la matriz de correlación de las características con el método corr() y mostramos el gráfico con un mapa de colores.

figure = plt.figure(figsize = (15, 10))
axes = figure.add_subplot()
corr_features = X_train.corr()
_ = sns.heatmap(corr_features, annot=True, cmap=plt.cm.coolwarm, axes = axes)

Lo siguiente será sacar las características que tienen una correlación mayor a un umbral dado. Para eso, definimos el umbral y volvemos a sacar la matriz de correlación, pero esta vez con los valores absolutos (un valor de correlación = -1 indica una alta correlación negativa, con lo que también deberíamos tenerlo en cuenta).

umbral_corr = 0.7

corr_matrix = X_train.corr().abs()

Para seleccionar las características que tienen una correlación mayor que nuestro umbral, vamos a usar un par de funciones de numpy:

  • ones(): Crea un array de 1's de una dimensión dada.
  • triu(): Devuelve una copia de un array con los elementos inferiores a la diagonal k-ésima igual a 0.

Por ejemplo, si queremos crear una matriz de 5×5 con los elementos del triángulo superior = 1 y el resto a 0:

np.triu(np.ones((5, 5)), k=1)

array([[0., 1., 1., 1., 1.],
       [0., 0., 1., 1., 1.],
       [0., 0., 0., 1., 1.],
       [0., 0., 0., 0., 1.],
       [0., 0., 0., 0., 0.]])

También podemos pasar los elementos a booleanos:

np.triu(np.ones((5, 5)), k=1).astype(np.bool)

array([[False,  True,  True,  True,  True],
       [False, False,  True,  True,  True],
       [False, False, False,  True,  True],
       [False, False, False, False,  True],
       [False, False, False, False, False]])

Ahora podemos combinar ambas matrices (la de correlación y la que hemos creado) con el método where de pandas para quedarnos sólo con los valores del triángulo superior de la matriz de correlación (el triángulo inferior contiene los mismos valores, con lo que no hace falta tenerlos en cuenta).

upper = corr_matrix.where(np.triu(np.ones(corr_matrix.shape), k=1).astype(np.bool))

El método where() de pandas, reemplaza los valores de una variable donde la condición es Falso

Al final, tendremos una matriz parecida a ésta:

upper

Lo último será seleccionar aquellas columnas que contengan algún valor por encima del umbral dado:

to_drop = [column for column in upper.columns if any(upper[column] > umbral_corr)]
print(to_drop)

['flavanoids', 'od280/od315_of_diluted_wines']

Ahora ya podemos eliminar las características:

# Drop features 
X_train = X_train.drop(columns = to_drop, axis=1)
X_test = X_test.drop(columns = to_drop, axis=1)

X_train.shape, X_test.shape

((124, 11), (54, 11))

En realidad, si un par de características están altamente correlacionadas, deberíamos borrar aquella que tenga una correlación más baja con nuestro target
No existe un umbral definido para borrar características correlacionadas. Si elegimos un umbral muy alto, podemos introducir información redundante al modelo, mientras que si elegimos un valor bajo, podemos perder información valiosa

Referencias

clase/ia/saa/2eval/reduccion_dimensionalidad.txt · Última modificación: 2024/02/26 09:47 por cesguiro