Uso del análisis de componentes principales con datos de la vida real
Motivación
Existen datos de acceso público que describen las características socioeconómicas de una ubicación geográfica. En Australia donde resido, el Gobierno a través de la Oficina Australiana de Estadísticas (ABS) recopila y publica datos individuales y de hogares de forma periódica con respecto a los ingresos, la ocupación, la educación, el empleo y la vivienda a nivel de área. Algunos ejemplos de los puntos de datos publicados incluyen:
- Porcentaje de personas con ingresos relativamente altos/bajos
- Porcentaje de personas clasificadas como directivos en sus respectivas ocupaciones
- Porcentaje de personas sin nivel educativo formal
- Porcentaje de personas desempleadas
- Porcentaje de propiedades con 4 o más dormitorios
Si bien estos puntos de datos parecen centrarse en gran medida en personas individuales, reflejan el acceso de las personas a los recursos materiales y sociales, y su capacidad para participar en la sociedad en un área geográfica particular, lo que en última instancia informa las ventajas y desventajas socioeconómicas de esta área.
Teniendo en cuenta estos puntos de datos, ¿hay alguna manera de derivar una puntuación que clasifique las áreas geográficas desde las más a las menos favorecidas?
El problema
El objetivo de obtener una puntuación puede formularse como un problema de regresión, donde cada punto o característica de datos se utiliza para predecir una variable objetivo, en este escenario, una puntuación numérica. Esto requiere que la variable objetivo esté disponible en algunos casos para entrenar el modelo predictivo.
Sin embargo, como no tenemos una variable objetivo para empezar, es posible que debamos abordar este problema de otra manera. Por ejemplo, bajo el supuesto de que cada área geográfica es diferente desde un punto de vista socioeconómico, ¿podemos intentar comprender qué puntos de datos ayudan a explicar la mayoría de las variaciones, derivando así una puntuación basada en una combinación numérica de estos puntos de datos?
Podemos hacer exactamente eso usando una técnica llamada Análisis de Componentes Principales (PCA), ¡y este artículo demuestra cómo!
Los datos
ABS publica puntos de datos que indican las características socioeconómicas de un área geográfica en la sección “Descarga de datos” de este Página weben el “Cubo de datos de proporciones variables estandarizadas”[1]. Estos puntos de datos se publican en el Área estadística 1 (SA1) nivel, que es una frontera digital que segrega a Australia en áreas de población de aproximadamente 200 a 800 personas. Este es un límite digital mucho más granular en comparación con el código postal o el límite digital de los estados.
Para fines de demostración en este artículo, derivaré una puntuación socioeconómica basada en 14 de los 44 puntos de datos publicados proporcionados en la Tabla 1 de la fuente de datos anterior (explicaré por qué selecciono este subconjunto más adelante). ). Estos son :
- INC_LOW: Porcentaje de personas que viven en hogares con ingresos anuales equivalentes declarados entre $1 y $25,999 AUD
- INC_HIGH: Porcentaje de personas con ingresos equivalentes anuales declarados superiores a $91,000 AUD
- UNEMPLOYED_IER: Porcentaje de personas de 15 años y más que están desempleadas
- CAMA ALTA: Porcentaje de propiedades privadas ocupadas con cuatro o más dormitorios
- HIPOTECA ALTA: Porcentaje de propiedades privadas ocupadas que pagan una hipoteca superior a $2,800 AUD por mes
- RENTA BAJO: Porcentaje de propiedades privadas ocupadas que pagan alquiler menos de $250 AUD por semana
- PROPIEDAD: Porcentaje de propiedades privadas ocupadas sin hipoteca
- HIPOTECA: Porcentaje de propiedades privadas ocupadas con hipoteca
- GRUPO: Porcentaje de propiedades privadas ocupadas que son propiedades privadas ocupadas por grupos (por ejemplo, apartamentos o unidades)
- SOLITARIO: Porcentaje de propiedades ocupadas que son propiedades privadas ocupadas por una sola persona
- HABITACIÓN: Porcentaje de propiedades privadas ocupadas que requieren uno o más dormitorios adicionales (según el Estándar Nacional de Ocupación de Canadá)
- NOCAR: Porcentaje de propiedades privadas ocupadas sin automóviles
- MONOPARENTE: Porcentaje de familias monoparentales
- UNINCORP: Porcentaje de inmuebles con al menos una persona que es dueño de negocio
Los pasos
En esta sección, analizaré el código Python para obtener una puntuación socioeconómica para una región SA1 en Australia utilizando PCA.
Comenzaré cargando los paquetes de Python requeridos y los datos.
## Load the required Python packages
### For dataframe operations
import numpy as np
import pandas as pd
### For PCA
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
### For Visualization
import matplotlib.pyplot as plt
import seaborn as sns
### For Validation
from scipy.stats import pearsonr
## Load data
file1 = 'data/standardised_variables_seifa_2021.xlsx'
### Reading from Table 1, from row 5 onwards, for column A to AT
data1 = pd.read_excel(file1, sheet_name = 'Table 1', header = 5,
usecols = 'A:AT')
## Remove rows with missing value (113 out of 60k rows)
data1_dropna = data1.dropna()
Un paso de limpieza importante antes de realizar PCA es estandarizar cada uno de los 14 puntos de datos (características) a una media de 0 y una desviación estándar de 1. Esto es principalmente para garantizar las cargas asignadas a cada característica por PCA (piense en ellas como indicadores de qué tan importante es una característica) son comparables entre características. De lo contrario, se puede dar más énfasis o mayor carga a una característica que en realidad no es significativa o viceversa.
Tenga en cuenta que la fuente de datos ABS citada anteriormente ya tiene las características estandarizadas. Dicho esto, para una fuente de datos no estandarizada:
## Standardise data for PCA
### Take all but the first column which is merely a location indicator
data_final = data1_dropna.iloc[:,1:]
### Perform standardisation of data
sc = StandardScaler()
sc.fit(data_final)
### Standardised data
data_final = sc.transform(data_final)
Con los datos estandarizados, la PCA se puede realizar en tan solo unas pocas líneas de código:
## Perform PCA
pca = PCA()
pca.fit_transform(data_final)
PCA tiene como objetivo representar los datos subyacentes por componentes principales (PC). La cantidad de PC proporcionadas en una PCA es igual a la cantidad de funciones estandarizadas en los datos. En este caso, se devuelven 14 PC.
Cada PC es una combinación lineal de todas las características estandarizadas, solo diferenciada por sus respectivas cargas de la característica estandarizada. Por ejemplo, la imagen a continuación muestra las cargas asignadas a la primera y segunda PC (PC1 y PC2) por función.
Con 14 PC, el siguiente código proporciona una visualización de cuánta variación explica cada PC:
## Create visualization for variations explained by each PC
exp_var_pca = pca.explained_variance_ratio_
plt.bar(range(1, len(exp_var_pca) + 1), exp_var_pca, alpha = 0.7,
label = '% of Variation Explained',color = 'darkseagreen')
plt.ylabel('Explained Variation')
plt.xlabel('Principal Component')
plt.legend(loc = 'best')
plt.show()
Como se ilustra en la visualización de resultados a continuación, el Componente Principal 1 (PC1) representa la mayor proporción de varianza en el conjunto de datos original, y cada PC siguiente explica menos de la varianza. Para ser específico, PC1 explica alrededor. 35% de la variación dentro de los datos.
A los efectos de la demostración en este artículo, se elige el PC1 como el único PC para derivar la puntuación socioeconómica, por las siguientes razones:
- PC1 explica una variación suficientemente grande dentro de los datos en términos relativos.
- Si bien elegir más PC permite potencialmente explicar (marginalmente) una mayor variación, dificulta la interpretación de la puntuación en el contexto de ventajas y desventajas socioeconómicas de un área geográfica particular. Por ejemplo, como se muestra en la imagen a continuación, PC1 y PC2 pueden proporcionar narrativas contradictorias sobre cómo una característica particular (por ejemplo, ‘INC_LOW’) influye en la variación socioeconómica de un área geográfica.
## Show and compare loadings for PC1 and PC2
### Using df_plot dataframe per Image 1
sns.heatmap(df_plot, annot = False, fmt = ".1f", cmap = 'summer')
plt.show()
Para obtener una puntuación para cada SA1, simplemente multiplicamos la porción estandarizada de cada característica por su carga de PC1. Esto se puede lograr mediante:
## Obtain raw score based on PC1
### Perform sum product of standardised feature and PC1 loading
pca.fit_transform(data_final)
### Reverse the sign of the sum product above to make output more interpretable
pca_data_transformed = -1.0*pca.fit_transform(data_final)
### Convert to Pandas dataframe, and join raw score with SA1 column
pca1 = pd.DataFrame(pca_data_transformed[:,0], columns = ['Score_Raw'])
score_SA1 = pd.concat([data1_dropna['SA1_2021'].reset_index(drop = True), pca1]
, axis = 1)
### Inspect the raw score
score_SA1.head()
Cuanto mayor sea la puntuación, más ventaja tendrá un SA1 en términos de acceso a recursos socioeconómicos.
La validación
¿Cómo sabemos que la puntuación que obtuvimos anteriormente fue remotamente correcta?
Para contextualizar, la ABS en realidad publicó una puntuación socioeconómica llamada Índice de Recursos Económicos (IER)definido en el sitio web de ABS como:
“El Índice de Recursos Económicos (IER) se centra en los aspectos financieros de las ventajas y desventajas socioeconómicas relativas, al resumir variables relacionadas con los ingresos y la vivienda. El IER excluye las variables de educación y ocupación porque no son medidas directas de recursos económicos. También excluye bienes como ahorros o patrimonio que, aunque relevantes, no pueden incluirse al no estar recogidos en el Censo”.
Sin revelar los pasos detallados, la ABS declaró en su Documento técnico que el IER se obtuvo utilizando las mismas características (14) y metodología (PCA, PC1 solamente) que habíamos realizado anteriormente. Es decir, si obtuvimos las puntuaciones correctas, deberían ser comparables con las puntuaciones IER publicadas. aquí (“Área Estadística Nivel 1, Índices, SEIFA 2021.xlsx”, Tabla 4).
Como la puntuación publicada está estandarizada a una media de 1000 y una desviación estándar de 100, comenzamos la validación estandarizando la puntuación bruta de la misma manera:
## Standardise raw scores
score_SA1['IER_recreated'] =
(score_SA1['Score_Raw']/score_SA1['Score_Raw'].std())*100 + 1000
A modo de comparación, leemos en las puntuaciones IER publicadas por SA1:
## Read in ABS published IER scores
## similarly to how we read in the standardised portion of the features
file2 = 'data/Statistical Area Level 1, Indexes, SEIFA 2021.xlsx'
data2 = pd.read_excel(file2, sheet_name = 'Table 4', header = 5,
usecols = 'A:C')
data2.rename(columns = {'2021 Statistical Area Level 1 (SA1)': 'SA1_2021', 'Score': 'IER_2021'}, inplace = True)
col_select = ['SA1_2021', 'IER_2021']
data2 = data2[col_select]
ABS_IER_dropna = data2.dropna().reset_index(drop = True)
Validación 1— Cargas PC1
Como se muestra en la imagen a continuación, comparando la carga de PC1 derivada arriba con la Carga PC1 publicada por la ABS sugiere que difieren en una constante de -45%. Como se trata simplemente de una diferencia de escala, no afecta las puntuaciones derivadas que están estandarizadas (a una media de 1000 y una desviación estándar de 100).
(Debería poder verificar la columna ‘Derivada (A)’ con las cargas de PC1 en la Imagen 1).
Validación 2— Distribución de puntuaciones
El siguiente código crea un histograma para ambas partituras, cuyas formas parecen casi idénticas.
## Check distribution of scores
score_SA1.hist(column = 'IER_recreated', bins = 100, color = 'darkseagreen')
plt.title('Distribution of recreated IER scores')
ABS_IER_dropna.hist(column = 'IER_2021', bins = 100, color = 'lightskyblue')
plt.title('Distribution of ABS IER scores')
plt.show()
Validación 3: puntuación IER por SA1
Como validación final, comparemos las puntuaciones IER según SA1:
## Join the two scores by SA1 for comparison
IER_join = pd.merge(ABS_IER_dropna, score_SA1, how = 'left', on = 'SA1_2021')
## Plot scores on x-y axis.
## If scores are identical, it should show a straight line.
plt.scatter('IER_recreated', 'IER_2021', data = IER_join, color = 'darkseagreen')
plt.title('Comparison of recreated and ABS IER scores')
plt.xlabel('Recreated IER score')
plt.ylabel('ABS IER score')
plt.show()
Una línea recta diagonal, como se muestra en la imagen de salida a continuación, respalda que las dos puntuaciones son en gran medida idénticas.
Además de esto, el siguiente código muestra que las dos puntuaciones tienen una correlación cercana a 1:
Pensamiento final
La demostración en este artículo replica efectivamente cómo el ABS calibra el IER, uno de los cuatro índices socioeconómicos que publica, que puede usarse para clasificar el estatus socioeconómico de un área geográfica.
Dando un paso atrás, lo que hemos logrado en esencia es una reducción en la dimensión de los datos de 14 a 1, perdiendo parte de la información transmitida por los datos.
La técnica de reducción de dimensionalidad, como el PCA, también se ve comúnmente para ayudar a reducir el espacio de alta dimensión, como las incrustaciones de texto, a 2 o 3 componentes principales (visualizables).
Referencia
[1] Oficina de Estadísticas de Australia (2021), Índices Socioeconómicos por Áreas (SEIFA)Sitio web de ABS, consultado el 29 de diciembre de 2023 (Licencia común creativa)
Mientras me sumo a la ola de IA/ML, disfruto escribiendo y compartiendo guías paso a paso y tutoriales prácticos en un lenguaje integral con códigos listos para ejecutar. Si desea acceder a todos mis artículos (y artículos de otros profesionales/escritores en Medium), puede registrarse usando el enlace ¡aquí!
Obtención de una puntuación para mostrar las ventajas y desventajas socioeconómicas relativas de un área geográfica fue publicado originalmente en Hacia la ciencia de datos en Medium, donde las personas continúan la conversación resaltando y respondiendo a esta historia.