Ejemplo con Datos demográficos#

#!git clone https://github.com/cgg-upm/upm-dma-som
#!dir upm-dma-som\som
#!copy upm-dma-som\som\som.py .\*.*
#!copy upm-dma-som\som\utils.py .\*.*
from som import som
from utils import somutils
import numpy as np
import pandas as pd

Ejemplo datos Población de Irlanda#

  • Datos: censo irlandés, area de Dublín, año 2011

  • Visualización de los resultados

Censo Irlanda 2011

Referencia código R

Los datos cocinados en : dataIrelandPopulationSOM.csv

df = pd.read_csv('data/dataIrelandPopulationSOM.csv')
df.head()
Unnamed: 0 id avr_age avr_household_size avr_education_level avr_num_cars avr_health rented_percent unemployment_percent internet_percent single_percent married_percent separated_percent divorced_percent widow_percent
0 15687 267123023 40.028112 2.524752 3.038462 1.039604 4.385542 6.930693 15.343915 71.000000 53.413655 33.333333 4.819277 2.811245 5.622490
1 13895 267016001 35.673660 3.320611 3.597701 1.983740 4.509434 4.878049 12.461059 72.950820 49.417249 44.988345 1.398601 0.233100 3.962704
2 13896 267016002 35.882353 3.324324 4.295302 1.905405 4.596639 1.351351 10.404624 83.783784 47.478992 43.697479 3.361345 0.000000 5.462185
3 13729 267002034 38.516667 3.088608 3.871795 1.730769 4.530172 3.896104 8.108108 78.947368 47.083333 48.333333 0.833333 1.250000 2.500000
4 13724 267002029 24.678005 3.512000 3.933735 1.112000 4.510345 20.800000 21.810700 81.300813 67.120181 26.984127 2.267574 1.587302 2.040816
df.columns
Index(['Unnamed: 0', 'id', 'avr_age', 'avr_household_size',
       'avr_education_level', 'avr_num_cars', 'avr_health', 'rented_percent',
       'unemployment_percent', 'internet_percent', 'single_percent',
       'married_percent', 'separated_percent', 'divorced_percent',
       'widow_percent'],
      dtype='object')
df.values.shape
(4806, 15)
columns=['avr_age','avr_education_level','avr_num_cars','unemployment_percent']
X = df[columns].to_numpy()
X.shape
(4806, 4)
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_std = scaler.fit_transform(X)
X_std.shape
(4806, 4)

Definir y entrenar el SOM#

nrows = 10
ncols = 10
#dimensions = X_std.shape[1]
dimensions = X.shape[1]
#vicinity = "rectangular"
vicinity = "hexagonal"
smm = som(nrows=nrows,
          ncols=ncols,
          dimension=dimensions,
          vicinity=vicinity)
smm.train_SOM(train_data=X,
              epochs=5)
Hide code cell output
  0%|                                                                                                                                                      | 0/5 [00:00<?, ?it/s]
 20%|████████████████████████████▍                                                                                                                 | 1/5 [00:00<00:03,  1.30it/s]
 40%|████████████████████████████████████████████████████████▊                                                                                     | 2/5 [00:01<00:02,  1.25it/s]
 60%|█████████████████████████████████████████████████████████████████████████████████████▏                                                        | 3/5 [00:02<00:01,  1.24it/s]
 80%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████▌                            | 4/5 [00:03<00:00,  1.23it/s]
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:04<00:00,  1.19it/s]
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:04<00:00,  1.22it/s]

<som.som at 0x1ade7bde5d0>

Gráfico con el clustering y el recuento de nodos#

somutils.plot_Cluster(pSom=smm, n_clusters=4, figsize=(7,5))
_images/739cbac22cf19980fd8c5a2190834a86f89f0daacd74a6156a7fd588111211ef.png

Recuento de observaciones por neurona#

somutils.plot_neurPointsCount(pSom=smm, figsize=(7,5))
_images/193cbbda9b1d6587d37a7568cce8601d203108efcdbe6c4a37c5c8470451da6d.png

Mapeo de valores#

somutils.plot_valuesMap(pSom=smm, labels=columns, figsize=(9,7))
_images/c52d033793df55f03ad4caf38f95d5ae7aebda84d35b2816805d960c32e1e442.png

Mapas de calor#

somutils.plot_heatmaps(pSom=smm, labels=columns, ilabMap=[0], figsize=(7,5))
_images/6077d94bd252fcb9ef4b604c1c7532095066e8f8878a45a803d69efa1097e4d8.png
somutils.plot_heatmaps(pSom=smm, labels=columns, ilabMap=[0,2], figsize=(7,7))
_images/2f1aa48f38b620e0108e3e4cd526c8ee38ae4c9c88647c3bd893b081e68f77d2.png

Mapeo de observaciones sobre cada neurona#

somutils.plot_pointsMap(pSom=smm, figsize=(7,7))
_images/eeda8009a126d28ad4b9744fa4aec2f0b4b1ccded557d757d4999ba887e23a3e.png

Dibujo de la matriz de distancias unificadas (U-Matrix)#

Contiene la distancia entre los nodos del SOM. En el gráfico a más intensidad hay una menor distancia entre las neuronas adyacentes. Para cada neurona se calcula la distancia entre ella y sus neuronas vecinas más próximas. Cuanto menor sea el resultado, más próxima estará la neurona con sus vecinas.

somutils.plot_u_matrix(pSom=smm, figsize=(7,7))
_images/23f345660de0bc67974e6358e9bf6db93a4e2b3090abd69bb268fa8e6d27d56a.png

Distancia media a la neurona más próxima por iteración#

Acceder a los datos asociados a cada neurona#

Índices de las observaciones de una neurona, por ejemplo la neurona del nodo (0, 0)

Se muestra sólo la dimensión con len

len(smm.getIndexDataNeur(0, 0))
80

Y los datos de las observaciones asociados a la neurona (0,0)

Se muestra sólo la dimensión con shape

smm.getDataNeuron(0, 0).shape
(80, 4)

Clústeres sobre el mapa topográfico#

Si los datos contienen información GIS, es posible representar qué puntos del mapa topográfico de Dublín están relacionados con qué clústeres.

fishy

Fig. 37 Geolocalización de los clústeres hallados#