Proyección aleatoria: teoría e implementación en Python con Scikit-Learn

En esta guía, veremos la teoría y la implementación detrás de Random Projections en Python: Gaussian y Sparse Random Projections, así como un tutorial práctico con un conjunto de datos de la vida real.

Introducción

Esta guía es una introducción detallada a una técnica de reducción de dimensionalidad no supervisada llamada Proyecciones aleatorias. Se puede utilizar una proyección aleatoria para reducir la complejidad y el tamaño de los datos, lo que facilita su procesamiento y visualización. También es una técnica de preprocesamiento para la preparación de entradas a un clasificador o regresor.

Random Projection normalmente se aplica a datos altamente dimensionales, donde otras técnicas como *Análisis de componentes principales (PCA) * no puedo hacer justicia a los datos.

En esta guía, profundizaremos en los detalles del lema de Johnson-Lindenstrauss, que sienta las bases matemáticas de las proyecciones aleatorias. También mostraremos cómo realizar una proyección aleatoria utilizando la biblioteca Scikit-Learn de Python y cómo utilizarla para transformar los datos de entrada en un espacio de menor dimensión.

La teoría es teoría y la práctica es práctica. Como ejemplo práctico, cargaremos el Conjunto de datos del volumen I de Reuters Corpus, y aplicaremos Gaussian Random Projection y Proyección aleatoria dispersa.

¿Qué es una proyección aleatoria de un conjunto de datos? {#lo que es una proyección aleatoria de un conjunto de datos}

En pocas palabras:

Random Projection es un método de reducción de dimensionalidad y visualización de datos que simplifica la complejidad de los conjuntos de datos de alta dimensión.

El método genera un nuevo conjunto de datos tomando la proyección de cada punto de datos a lo largo de un conjunto de direcciones elegido al azar. La proyección de un solo punto de datos en un vector es matemáticamente equivalente a tomar el producto escalar del punto con el vector.

Ilustración de proyecciones aleatorias

Dada una matriz de datos \(X\) de dimensiones \(mxn\) y una matriz \(dxn\) \(R\) cuyas columnas son los vectores que representan direcciones aleatorias, la Proyección Aleatoria de \(X\) viene dado por \(X_p\).

$$X_{p} = XR$$

Cada vector que representa una dirección aleatoria tiene una dimensionalidad \(n\), que es la misma que todos los puntos de datos de \(X\). Si tomamos \(d\) direcciones aleatorias, entonces terminamos con un conjunto de datos transformado dimensional \(d\). A los efectos de este tutorial, arreglaremos algunas notaciones:

  • m: Total de puntos/muestras de ejemplo de datos de entrada.
  • n: Características/atributos totales de los datos de entrada. Es también la dimensionalidad de los datos originales.
  • d: Dimensionalidad de los datos transformados.

La idea de Random Projections es muy similar a Análisis de componentes principales (PCA), fundamentalmente. Sin embargo, en PCA, la matriz de proyección se calcula a través de vectores propios, lo que puede resultar costoso desde el punto de vista computacional para matrices grandes.

Al realizar Random Projection, los vectores se eligen aleatoriamente, lo que lo hace muy eficiente. El nombre "proyección" puede ser un poco engañoso ya que los vectores se eligen aleatoriamente, los puntos transformados matemáticamente no son proyecciones verdaderas pero están cerca de ser proyecciones verdaderas.

Los datos con dimensiones reducidas son más fáciles de trabajar. No solo se puede visualizar, sino que también se puede utilizar en la etapa de preprocesamiento para reducir el tamaño de los datos originales.

Un ejemplo simple

Solo para entender cómo funciona la transformación, tomemos el siguiente ejemplo simple.

Supongamos que nuestra matriz de entrada \(X\) está dada por:

$$X = \begin{bmatriz} 1 y 3 y 2 y 0 \ 0 y 1 y 2 y 1 \ 1 y 3 y 0 y 0 \ \end{bmatriz}$$

Y la matriz de proyección viene dada por:

$$R = \frac{1}{2}\begin{bmatriz} 1 & {- 1} \ 1 y 1 \ 1 & {- 1} \ 1 y 1 \ \end{bmatriz}$$

La proyección de X sobre R es:

$$X_{p} = XR = \frac{1}{2}\begin{bmatriz} 6 y 0 \ 4 y 0 \ 4 y 2 \ \end{bmatriz}$$

Comenzamos con tres puntos en un espacio de cuatro dimensiones, y con operaciones matriciales inteligentes terminamos con tres puntos transformados en un espacio de dos dimensiones.

Tenga en cuenta algunos atributos importantes de la matriz de proyección \(R\). Cada columna es una matriz unitaria, es decir, la norma de cada columna es uno. Además, el producto punto de todas las columnas tomadas por pares (en este caso, solo la columna 1 y la columna 2) es cero, lo que indica que ambos vectores de columna son ortogonales entre sí.

Esto hace que la matriz sea una Matriz Ortonormal. Sin embargo, en el caso de la técnica de proyección aleatoria, la matriz de proyección no tiene que ser una verdadera matriz ortonormal cuando se trata de datos de muy alta dimensión.

El éxito de Random Projection se basa en un asombroso hallazgo matemático conocido como Lema de Johnson-Lindenstrauss, que se explica en detalle en la siguiente sección.

El lema de Johnson-Lindenstrauss

El lema de Johnson-Lindenstrauss es la base matemática de la proyección aleatoria:

El lema de Johnson-Lindenstrauss establece que si los puntos de datos se encuentran en un espacio de dimensiones muy altas, la proyección de dichos puntos en direcciones aleatorias simples conserva sus distancias por pares.

Preservar las distancias por pares implica que las distancias por pares entre puntos en el espacio original son iguales o casi iguales que la distancia por pares en el espacio proyectado de menor dimensión.

Por lo tanto, la estructura de los datos y los grupos dentro de los datos se mantienen en un espacio de menor dimensión, mientras que la complejidad y el tamaño de los datos se reducen sustancialmente.

En esta guía, nos referimos a la diferencia en las distancias por pares reales y proyectadas como la "distorsión" en los datos, que se introduce debido a su proyección en un nuevo espacio.

El lema de Johnson-Lindenstrauss también proporciona una medida "segura" del número de dimensiones para proyectar los puntos de datos, de modo que el error/distorsión se encuentre dentro de un cierto rango, por lo que encontrar el número objetivo de dimensiones es hecho facil.

Matemáticamente, dado un par de puntos \((x_1,x_2)\) y sus correspondientes proyecciones \((x_1',x_2')\) define una eps-incrustación:

$$
(1 - \epsilon) |x_1 - x_2|^2 < |x_1' - x_2'|^2 < (1 + \epsilon) |x_1 - x_2|\ ^2
$$

El lema de Johnson-Lindenstrauss especifica las dimensiones mínimas del espacio de dimensiones inferiores para que se mantenga el eps-incrustación anterior.

Determinación de las direcciones aleatorias de la matriz de proyección {#determinación de las direcciones aleatorias de la matriz de proyección}

Dos métodos bien conocidos para determinar la matriz de proyección son:

  • Proyección aleatoria gaussiana: La matriz de proyección se construye eligiendo elementos aleatoriamente de una distribución gaussiana con media cero.

  • Proyección aleatoria dispersa: Este es un método comparativamente más simple, donde cada componente del vector es un valor del conjunto {-k,0,+k}, donde k es una constante. Un esquema simple para generar los elementos de esta matriz, también llamado método Achlioptas es establecer \(k=\sqrt 3\):

$$R_{ij} = \sqrt{3}\left{ \begin{matriz} {+ 1} & \text{~con\ probabilidad~} & \frac{1}{6} \ 0 & \text{~con\ probabilidad~} & \frac{2}{3} \ {- 1} & \text{~con\ probabilidad~} & \frac{1}{6} \ \end{matriz} \right.$$

El método anterior es equivalente a elegir los números de {+k,0,-k} según el resultado del lanzamiento de un dado. Si la puntuación de los dados es 1, elige +k. Si la puntuación de dados está en el rango [2,5], elija 0 y elija -k para una puntuación de dados de 6.

Un método más general utiliza un parámetro de densidad para elegir la matriz de proyección aleatoria. Estableciendo \(s=\frac{1}{\text{density}}\), los elementos de la matriz de proyección aleatoria se eligen como:

$$R_{ij} = \izquierda{ \begin{matriz} {+ \sqrt{\frac{s}{d}}} & \text{~con\ probabilidad~} & \frac{1}{2s} \ 0 & \text{~con\ probabilidad~} & {1 - \frac{1}{s}} \ {- \sqrt{\frac{s}{d}}} & \text{~con\ probabilidad~} & \frac{1}{2s} \ \end{matriz} \right.$$

La recomendación general es establecer el parámetro densidad en \(\frac{1}{\sqrt n}\).

Como se mencionó anteriormente, tanto para el método gaussiano como para el método disperso, la matriz de proyección no es una verdadera matriz ortonormal. Sin embargo, se ha demostrado que en espacios de alta dimensión, la matriz elegida al azar utilizando cualquiera de los dos métodos anteriores es cercana a una matriz ortonormal.

Proyección aleatoria usando Scikit-Learn

La biblioteca Scikit-Learn nos proporciona el módulo random_projection, que tiene tres clases/módulos importantes:

  • johnson_lindenstrauss_min_dim(): para determinar el número mínimo de dimensiones de los datos transformados cuando se da un tamaño de muestra m.
  • GaussianRandomProjection: realiza proyecciones aleatorias gaussianas.
  • SparseRandomProjection: realiza proyecciones aleatorias escasas.

Demostraremos los tres anteriores en las siguientes secciones, pero primero importemos las clases y funciones que usaremos:

1
2
3
4
5
6
from sklearn.random_projection import SparseRandomProjection, johnson_lindenstrauss_min_dim
from sklearn.random_projection import GaussianRandomProjection
import numpy as np
from matplotlib import pyplot as plt
import sklearn.datasets as dt
from sklearn.metrics.pairwise import euclidean_distances

Determinación del número mínimo de dimensiones a través del lema de Johnson Lindenstrauss {#determinación del número mínimo de dimensiones a través del lema de Johnson Lindenstrauss}

La función johnson_lindenstrauss_min_dim() determina el número mínimo de dimensiones d, a las que se pueden asignar los datos de entrada cuando se da el número de ejemplos m, y eps o \(\epsilon\) parámetro.

El siguiente código experimenta con un número diferente de muestras para determinar el tamaño mínimo del espacio de menor dimensión, que mantiene una cierta distorsión "segura" de los datos.

Además, traza log(d) contra diferentes valores de eps para diferentes tamaños de muestra m.

Una cosa importante a tener en cuenta es que el lema de Johnson Lindenstrauss determina el tamaño del espacio de dimensión inferior \(d\) solo en función del número de puntos de ejemplo \(m\) en los datos de entrada. El número de atributos o características \(n\) de los datos originales es irrelevante:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
eps = np.arange(0.001, 0.999, 0.01)
colors = ['b', 'g', 'm', 'c']
m = [1e1, 1e3, 1e7, 1e10]
for i in range(4):
    min_dim = johnson_lindenstrauss_min_dim(n_samples=m[i], eps=eps)
    label = 'Total samples = ' + str(m[i])
    plt.plot(eps, np.log10(min_dim), c=colors[i], label=label)
    
plt.xlabel('eps')
plt.ylabel('log$_{10}$(d)')
plt.axhline(y=3.5, color='k', linestyle=':')
plt.legend()
plt.show()

cómo determinar el tamaño del espacio dimensional inferior para proyecciones aleatorias

Del gráfico anterior, podemos ver que para valores pequeños de eps, d es bastante grande pero disminuye a medida que eps se acerca a uno. La dimensionalidad está por debajo de 3500 (la línea negra punteada) para valores medianos a grandes de “eps”.

Esto muestra que aplicar Proyecciones aleatorias solo tiene sentido para datos de alta dimensión, del orden de miles de características. En tales casos, se puede lograr una gran reducción de la dimensionalidad.

Las proyecciones aleatorias son, por lo tanto, muy exitosas para datos de texto o imágenes, que involucran una gran cantidad de características de entrada, donde el análisis de componentes principales

Transformación de datos {#transformación de datos}

Python incluye la implementación de Gaussian Random Projections y Sparse Random Projections en su biblioteca sklearn a través de las dos clases GaussianRandomProjection y SparseRandomProjection respectivamente. Algunos atributos importantes para estas clases son (la lista no es exhaustiva):

  • n_components: Número de dimensiones de los datos transformados. Si se establece en “automático”, las dimensiones óptimas se determinan antes de la proyección.
  • eps: El parámetro del lema de Johnson-Lindenstrauss, que controla el número de dimensiones para que la distorsión en los datos proyectados se mantenga dentro de un cierto límite.
  • densidad: Solo aplicable para SparseRandomProjection. El valor predeterminado es auto, que establece \(s=\frac{1}{\sqrt n}\) para la selección de la matriz de proyección.

Al igual que otras clases de reducción de dimensionalidad de sklearn, ambas clases incluyen los métodos estándar fit() y fit_transform(). Un conjunto notable de atributos, que son útiles son:

  • n_components: El número de dimensiones del nuevo espacio sobre el que se proyectan los datos.
  • components_: La matriz de transformación o proyección.
  • density_: Solo aplicable a SparseRandomProjection. Es el valor de la densidad a partir del cual se calculan los elementos de la matriz de proyección.
Proyección aleatoria con GaussianRandomProjection

Comencemos con la clase GaussianRandomProjection. Los valores de la matriz de proyección se grafican como un histograma y podemos ver que siguen una distribución Gaussiana con media cero. El tamaño de la matriz de datos se reduce de 5000 a 3947:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
X_rand = np.random.RandomState(0).rand(100, 5000)
proj_gauss = GaussianRandomProjection(random_state=0)
X_transformed = proj_gauss.fit_transform(X_rand)

# Print the size of the transformed data
print('Shape of transformed data: ' + str(X_transformed.shape))

# Generate a histogram of the elements of the transformation matrix
plt.hist(proj_gauss.components_.flatten())
plt.title('Histogram of the flattened transformation matrix')
plt.show()

Este código da como resultado:

1
Shape of transformed data: (100, 3947)

gaussian random projection scikit learn

Proyección aleatoria con SparseRandomProjection

El siguiente código demuestra cómo se puede realizar la transformación de datos utilizando una proyección aleatoria dispersa. Toda la matriz de transformación se compone de tres valores distintos, cuyo diagrama de frecuencia también se muestra a continuación.

Tenga en cuenta que la matriz de transformación es una SciPy escasa csr_matrix. El siguiente código accede a los valores distintos de cero de csr_matrix y los almacena en p. Luego, usa p para obtener los conteos de los elementos de la matriz de proyección dispersa:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
proj_sparse = SparseRandomProjection(random_state=0)
X_transformed = proj_sparse.fit_transform(X_rand)

# Print the size of the transformed data
print('Shape of transformed data: ' + str(X_transformed.shape))

# Get data of the transformation matrix and store in p. 
# p consists of only 2 non-zero distinct values, i.e., pos and neg
# pos and neg are determined below
p = proj_sparse.components_.data
total_elements = proj_sparse.components_.shape[0] *\
                  proj_sparse.components_.shape[1]
pos = p[p>0][0]
neg = p[p<0][0]
print('Shape of transformation matrix: '+ str(proj_sparse.components_.shape))
counts = (sum(p==neg), total_elements - len(p), sum(p==pos))
# Histogram of the elements of the transformation matrix
plt.bar([neg, 0, pos], counts, width=0.1)
plt.xticks([neg, 0, pos])
plt.suptitle('Histogram of flattened transformation matrix, ' + 
             'density = ' +
             '{:.2f}'.format(proj_sparse.density_))
plt.show()

Esto resulta en:

1
2
Shape of transformed data: (100, 3947)
Shape of transformation matrix: (3947, 5000)

sparse random projections scikit learn

El histograma está de acuerdo con el método de generar una matriz de Proyección Aleatoria dispersa como se discutió en la sección anterior. El cero se selecciona con probabilidad (1-1/100 = 0,99), por lo que alrededor del 99% de los valores de esta matriz son cero. El uso de estructuras de datos y rutinas para matrices dispersas hace que este método de transformación sea muy rápido y eficiente en grandes conjuntos de datos.

Proyecciones aleatorias prácticas con el conjunto de datos del volumen 1 de Reuters Corpus {#proyecciones aleatorias prácticas con el conjunto de datos del volumen 1 de Reuters Corpus}

Esta sección ilustra Proyecciones aleatorias en el Conjunto de datos del volumen I de Reuters Corpus. Se puede acceder libremente al conjunto de datos en línea, aunque para nuestros propósitos, es más fácil cargarlo a través de Scikit-Learn.

El módulo sklearn.conjuntos de datos contiene una función fetch_rcv1() que descarga e importa el conjunto de datos.

{.icon aria-hidden=“true”}

Nota: El conjunto de datos puede tardar unos minutos en descargarse, si nunca lo ha importado de antemano a través de este método. Dado que no hay una barra de progreso, puede parecer que el script se cuelga sin avanzar más. Dale un poco de tiempo, cuando lo ejecutes inicialmente.

El conjunto de datos RCV1 es un conjunto de datos multietiqueta, es decir, cada punto de datos puede pertenecer a varias clases al mismo tiempo y consta de 103 clases. Cada punto de datos tiene una dimensionalidad de la friolera de 47.236, ​​lo que lo convierte en un caso ideal para aplicar proyecciones aleatorias rápidas y económicas.

Para demostrar la eficacia de las proyecciones aleatorias y simplificar las cosas, seleccionaremos 500 puntos de datos que pertenecen al menos a una de las tres primeras clases. La función fetch_rcv1() recupera el conjunto de datos y devuelve un objeto con datos y objetivos, los cuales son matrices CSR dispersas de SciPy.

Busquemos el Corpus de Reuters y preparémoslo para la transformación de datos:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
total_points = 500
# Fetch the dataset
dat = dt.fetch_rcv1()
# Select the sparse matrix's non-zero targets
target_nz = dat.target.nonzero()
# Select only indices of target_nz for data points that belong to 
# either of class 1,2,3
ind_class_123 = np.asarray(np.where((target_nz[1]==0) |\
                                    (target_nz[1]==1) |\
                                    (target_nz[1] == 2))).flatten()
# Choose only 500 indices randomly
np.random.seed(0)
ind_class_123 = np.random.choice(ind_class_123, total_points, 
                                 replace=False)

# Retreive the row indices of data matrix and target matrix
row_ind = target_nz[0][ind_class_123]
X = dat.data[row_ind,:]
y = np.array(dat.target[row_ind,0:3].todense())

Después de la preparación de datos, necesitamos una función que cree una visualización de los datos proyectados. Para tener una idea de la calidad de la transformación, podemos calcular las siguientes tres matrices:

  • dist_raw: matriz de las distancias euclidianas por pares de los puntos de datos reales.
  • dist_transform: Matriz de las distancias euclidianas por pares de los puntos de datos transformados.
  • abs_diff: Matriz de la diferencia absoluta de dist_raw y dist_actual

La matriz abs_diff_dist es un buen indicador de la calidad de la transformación de datos. Valores cercanos a cero o pequeños en esta matriz indican baja distorsión y una buena transformación. Podemos mostrar directamente una imagen de esta matriz o generar un histograma de sus valores para evaluar visualmente la transformación. También podemos calcular el promedio de todos los valores de esta matriz para obtener una sola medida cuantitativa para comparar.

La función create_visualization() crea tres gráficos. El primer gráfico es un diagrama de dispersión de puntos proyectados a lo largo de las dos primeras direcciones aleatorias. El segundo gráfico es una imagen de la matriz de diferencia absoluta y el tercero es el histograma de los valores de la matriz de diferencia absoluta:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
def create_visualization(X_transform, y, abs_diff):
    fig,ax = plt.subplots(nrows=1, ncols=3, figsize=(20,7))

    plt.subplot(131)
    plt.scatter(X_transform[y[:,0]==1,0], X_transform[y[:,0]==1,1], c='r', alpha=0.4)
    plt.scatter(X_transform[y[:,1]==1,0], X_transform[y[:,1]==1,1], c='b', alpha=0.4)
    plt.scatter(X_transform[y[:,2]==1,0], X_transform[y[:,2]==1,1], c='g', alpha=0.4)
    plt.legend(['Class 1', 'Class 2', 'Class 3'])
    plt.title('Projected data along first two dimensions')

    plt.subplot(132)
    plt.imshow(abs_diff)
    plt.colorbar()
    plt.title('Visualization of absolute differences')

    plt.subplot(133)
    ax = plt.hist(abs_diff.flatten())
    plt.title('Histogram of absolute differences')

    fig.subplots_adjust(wspace=.3) 

Conjunto de datos de Reuters: Proyección aleatoria gaussiana

Apliquemos la proyección aleatoria gaussiana al conjunto de datos de Reuters. El siguiente código ejecuta un bucle for para diferentes valores eps. Si las dimensiones seguras mínimas devueltas por johnson_lindenstrauss_min_dim son menores que las dimensiones de datos reales, entonces llama al método fit_transform() de GaussianRandomProjection. Luego se llama a la función create_visualization() para crear una visualización para ese valor de eps.

En cada iteración, el código también almacena la diferencia absoluta media y la reducción porcentual en la dimensionalidad lograda por la proyección aleatoria gaussiana:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
reduction_dim_gauss = []
eps_arr_gauss = []
mean_abs_diff_gauss = []
for eps in np.arange(0.1, 0.999, 0.2):

    min_dim = johnson_lindenstrauss_min_dim(n_samples=total_points, eps=eps)
    if min_dim > X.shape[1]:
        continue
    gauss_proj = GaussianRandomProjection(random_state=0, eps=eps)
    X_transform = gauss_proj.fit_transform(X)
    dist_raw = euclidean_distances(X)
    dist_transform = euclidean_distances(X_transform)
    abs_diff_gauss = abs(dist_raw - dist_transform) 

    create_visualization(X_transform, y, abs_diff_gauss)
    plt.suptitle('eps = ' + '{:.2f}'.format(eps) + ', n_components = ' + str(X_transform.shape[1]))
    
    reduction_dim_gauss.append(100-X_transform.shape[1]/X.shape[1]*100)
    eps_arr_gauss.append(eps)
    mean_abs_diff_gauss.append(np.mean(abs_diff_gauss.flatten()))

RCV1 dataset gaussian random projections

RCV1 dataset gaussian random projections

RCV1 dataset gaussian random projections

RCV1 dataset gaussian random projections

RCV1 dataset gaussian random projections

Las imágenes de la matriz de diferencias absolutas y su correspondiente histograma indican que la mayoría de los valores son cercanos a cero. Por lo tanto, la gran mayoría del par de puntos mantienen su distancia real en el espacio de baja dimensión, conservando la estructura original de los datos.

Para evaluar la calidad de la transformación, representemos gráficamente la diferencia absoluta media contra eps. Además, cuanto mayor sea el valor de eps, mayor será la reducción de dimensionalidad. Tracemos también el porcentaje de reducción frente a eps en una segunda subtrama:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
fig,ax = plt.subplots(nrows=1, ncols=2, figsize=(10,5))
plt.subplot(121)
plt.plot(eps_arr_gauss, mean_abs_diff_gauss, marker='o', c='g')
plt.xlabel('eps')
plt.ylabel('Mean absolute difference')

plt.subplot(122)
plt.plot(eps_arr_gauss, reduction_dim_gauss, marker = 'o', c='m')
plt.xlabel('eps')
plt.ylabel('Percentage reduction in dimensionality')

fig.subplots_adjust(wspace=.4) 
plt.suptitle('Assessing the Quality of Gaussian Random Projections')
plt.show()

Calidad de reducción de proyecciones aleatorias RCV1

¡Podemos ver que usando la proyección aleatoria gaussiana podemos reducir la dimensionalidad de los datos a más del 99%! Sin embargo, esto tiene el costo de una mayor distorsión de los datos.

Conjunto de datos de Reuters: Proyección aleatoria escasa

Podemos hacer una comparación similar con la proyección aleatoria dispersa:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
reduction_dim_sparse = []
eps_arr_sparse = []
mean_abs_diff_sparse = []
for eps in np.arange(0.1, 0.999, 0.2):

    min_dim = johnson_lindenstrauss_min_dim(n_samples=total_points, eps=eps)
    if min_dim > X.shape[1]:
        continue
    sparse_proj = SparseRandomProjection(random_state=0, eps=eps, dense_output=1)
    X_transform = sparse_proj.fit_transform(X)
    dist_raw = euclidean_distances(X)
    dist_transform = euclidean_distances(X_transform)
    abs_diff_sparse = abs(dist_raw - dist_transform) 

    create_visualization(X_transform, y, abs_diff_sparse)
    plt.suptitle('eps = ' + '{:.2f}'.format(eps) + ', n_components = ' + str(X_transform.shape[1]))
    
    reduction_dim_sparse.append(100-X_transform.shape[1]/X.shape[1]*100)
    eps_arr_sparse.append(eps)
    mean_abs_diff_sparse.append(np.mean(abs_diff_sparse.flatten()))

RCV1 dataset sparse random projections

RCV1 dataset sparse random projections

RCV1 dataset sparse random projections

RCV1 dataset sparse random projections

En el caso de la Proyección Aleatoria, la matriz de diferencia absoluta parece similar a la de la proyección Gaussiana. Sin embargo, los datos proyectados en las dos primeras dimensiones tienen un patrón más interesante, con muchos puntos mapeados en el eje de coordenadas.

Tracemos también la diferencia absoluta media y la reducción porcentual en la dimensionalidad para varios valores del parámetro eps:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
fig,ax = plt.subplots(nrows=1, ncols=2, figsize=(10,5))
plt.subplot(121)
plt.plot(eps_arr_sparse, mean_abs_diff_sparse, marker='o', c='g')
plt.xlabel('eps')
plt.ylabel('Mean absolute difference')

plt.subplot(122)
plt.plot(eps_arr_sparse, reduction_dim_sparse, marker = 'o', c='m')
plt.xlabel('eps')
plt.ylabel('Percentage reduction in dimensionality')

fig.subplots_adjust(wspace=.4) 
plt.suptitle('Assessing the Quality of Sparse Random Projections')
plt.show()

calidad de reducción de proyecciones aleatorias dispersas

La tendencia de los dos gráficos es similar a la de una proyección gaussiana. Sin embargo, la diferencia media absoluta para la proyección gaussiana es menor que la de la proyección aleatoria.

Yendo más lejos: proyecto de extremo a extremo portátil

¿Tu naturaleza inquisitiva te hace querer ir más allá? Recomendamos consultar nuestro Proyecto guiado: ["Predicción práctica del precio de la vivienda: aprendizaje automático en Python"](https://wikihtp.com/courses/hands-on-house- precio-predicción-aprendizaje-máquina-en-python/#cta){target="_blank"}.

[](https://wikihtp.com/ cursos/predicción-de-precio-de-la-casa-práctica-aprendizaje-de-máquina-en-python/#cta)

En este proyecto guiado, aprenderá a crear potentes modelos tradicionales de aprendizaje automático, así como modelos de aprendizaje profundo, utilizar Ensemble Learning y capacitar a los meta-aprendices para predecir los precios de la vivienda a partir de una bolsa de modelos Scikit-Learn y Keras.

Con Keras, la API de aprendizaje profundo creada sobre Tensorflow, experimentaremos con arquitecturas, crearemos un conjunto de modelos apilados y entrenaremos una red neuronal meta-aprendizaje (modelo de nivel 1) para calcular el precio de un casa.

El aprendizaje profundo es sorprendente, pero antes de recurrir a él, se recomienda intentar resolver el problema con técnicas más simples, como los algoritmos de aprendizaje superficial. Nuestro rendimiento de referencia se basará en un algoritmo de Regresión de bosque aleatorio. Además, exploraremos la creación de conjuntos de modelos a través de Scikit-Learn a través de técnicas como embalaje y votación.

Este es un proyecto integral y, como todos los proyectos de aprendizaje automático, comenzaremos con Análisis exploratorio de datos, seguido de Preprocesamiento de datos y, finalmente, Creación de modelos superficiales y Aprendizaje profundo para ajustarse a los datos que hemos explorado y limpiado previamente.

Conclusiones

En esta guía, analizamos los detalles de dos tipos principales de proyecciones aleatorias, es decir, la proyección aleatoria gaussiana y dispersa.

Presentamos los detalles del Lema de Johnson-Lindenstrauss, la base matemática de estos métodos. Luego mostramos cómo se puede usar este método para transformar datos usando la biblioteca sklearn de Python.

También ilustramos los dos métodos en un [Conjunto de datos del volumen I de Reuters Corpus] de la vida real (https://www.jmlr.org/papers/volume5/lewis04a/lewis04a.pdf).

Alentamos al lector a probar este método en tareas de clasificación o regresión supervisadas en la etapa de preprocesamiento cuando se trata de conjuntos de datos de muy alta dimensión. .