Agrupación del INB per cápita a nivel continental

7 de enero de 2018 | 14 minutos de lectura
Índice de contenido

Resumen:
La presente entrada cubre el aprendizaje automático no supervisado, el cual no fragmenta los datos, sino que construye el modelo con el conjunto de datos completo. Así pues, permite que el modelo descubra patrones en los datos por sí mismo, sin supervisión. Dado que esta entrada cubre el análisis de conglomerados, presenta el modelo de aprendizaje automático no supervisado más simple, llamado k-means. El método de k-medias es fácil de comprender. Cuando realiza un análisis de conglomerados, no hay una variable de respuesta real: Trata todas las variables de la misma manera. Tampoco hay variable predictora, por lo que no hay caso de predicción/pronóstico. Solo analiza los patrones en los datos.
¿Cómo citar el presente artículo?
Romero, J. (7 de enero de 2018). Agrupación del INB per cápita a nivel continental. Python.JeshuaRomeroGuadarrama. https://www.Python.jeshuaromeroguadarrama.com/es/blog/data-science-and-econometrics/clustering-gni-per-capita-on-a-continental-level/.
Agrupación del INB per cápita a nivel continental by Jeshua Romero Guadarrama, available under Attribution 4.0 International (CC BY 4.0) at https://www.Python.jeshuaromeroguadarrama.com/es/blog/data-science-and-econometrics/clustering-gni-per-capita-on-a-continental-level/.

Agrupación del INB per cápita a nivel continental

Introducción


La presente entrada cubre el aprendizaje automático no supervisado. El este tipo de aprendizaje automático no fragmenta los datos, sino que construye el modelo con el conjunto de datos completo y permite que el modelo descubra patrones en los datos por sí mismo, sin supervisión. Dado que la presente entrada cubre el análisis de conglomerados, se expone el modelo de aprendizaje automático no supervisado más simple, llamado k-means. El método de k-medias es fácil de comprender. Cuando realiza un análisis de conglomerados, no hay una variable de respuesta real: Trata todas las variables de la misma manera. Tampoco hay variable predictora (independiente), por lo que no hay caso de predicción/pronóstico. Solo analiza los patrones en los datos.

El modelo de k-medias agrupa los valores en función de sus similitudes. Primero, el modelo encuentra valores que están cerca uno del otro y estima la distancia entre ellos. Posteriormente, determina el centro del grupo de valores y extiende esos valores de tal manera que los valores están dentro de un grupo. Encuentra similitudes en grupos implementando la estimación de distancia. El método de estimación de distancia más común es la estimación de distancia euclidiana. La ecuación (1) muestra la ecuación euclidiana.

J=ki=1ci=1|xJiCj|2

Donde J representa la función objetivo, k representa el número de conglomerados, n representa el número de casos, xJi representa el Casoj , y Cj representa los centroides de j.

Este modelo difiere de otros modelos en el sentido de que supone que encuentra la cantidad de clústeres en función del análisis de datos. Para determinar el número de conglomerados, aplique la curva del codo o el gráfico de sedimentación.

Contexto


La presente entrada aborda el problema con la suposición de que hay tres grupos en los datos. A partir de lo cual, se agrupan los países africanos aplicando tres etiquetas:

  • INB (ingreso nacional bruto) per cápita bajo.
  • INB (ingreso nacional bruto) per cápita moderado.
  • INB (ingreso nacional bruto) per cápita alto.

Así pues, se aplica la curva del codo para determinar si esta suposición con respecto a los datos es correcta. Luego se utiliza el modelo de k-medias en todos los datos del INB per cápita de los países africanos. Dado que hay muchas variables, no describe todos los datos.

Para realizar el análisis de conglomerados, primero debe realizarse un análisis descriptivo y luego realizarse una reducción de dimensión para reducir los datos de alta dimensión en unas pocas dimensiones. La técnica de reducción de dimensiones es mejor conocida como Análisis de Componentes Principales (PCA). Esta técnica reduce los datos para que puedan representarse en dos dimensiones mediante la aplicación de un gráfico de dispersión.

El siguiente código recupera los datos del INB per cápita (consultar la tabla final).

python
import warnings
warnings.filterwarnings('ignore')
python
import wbdata

# Cargar los datos del INB per cápita de África:
paises = ["AGO", "BDI", "BEN", "BWA", "CAF", "CIV",
          "COD", "DZA", "EGY", "ETH", "GAB", "GHA",
          "GIN", "GMB", "GNQ", "KEN", "LBR", "LBY",
          "LSO", "MAR", "MLI", "MOZ", "MWI", "NAM",
          "NER", "NGA", "RWA", "SDN", "SEN","SOM",
          "SWZ", "TCD", "TUN", "TZA", "UGA", "ZAF",
          "ZMB", "ZWE"]
indicadores = {"NY.GNP.PCAP.CD":"inb_per_capita"}
df = wbdata.get_dataframe(indicadores, 
                          country = paises,
                          convert_date = False)

# Datos del INB per cápita de África:
df.head()

inb_per_capita
countrydate
Angola20211770.0
20201780.0
20192070.0
20181900.0
20172010.0

El siguiente código desapila los datos: Cambia el índice de un índice múltiple a uno único.

python
# Desapilar datos:
df = df["inb_per_capita"]
df = df.unstack(level = 0)
df.iloc[0:10, 0:10]

countryAlgeriaAngolaBeninBotswanaBurundiCentral African RepublicChadCongo, Dem. Rep.Cote d'IvoireEgypt, Arab Rep.
date
1960NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
1961NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
1962190.0NaN90.080.070.080.0110.0NaN160.0NaN
1963230.0NaN100.080.080.080.0110.0NaN180.0NaN
1964240.0NaN110.090.080.080.0110.0NaN220.0NaN
1965250.0NaN110.090.070.090.0120.0NaN210.0NaN
1966230.0NaN110.0100.060.090.0120.0NaN230.0NaN
1967250.0NaN120.0100.050.0100.0130.0NaN240.0170.0
1968280.0NaN120.0120.050.0100.0130.0NaN270.0180.0
1969310.0NaN120.0140.050.0110.0140.0NaN280.0190.0

El siguiente código sustituye los valores faltantes con el valor promedio. Debe tenerse en cuenta que este ejemplo no maneja valores atípicos. Dado que hay tantas variables, que resultaría agotador hacerlo en un ejemplo tan simple. Sin embargo, en el mundo real, es fundamental manejar los valores atípicos, ya que pueden afectar negativamente las conclusiones.

python
# Reemplazar valores atípicos con valores promedio:
df["Algeria"] = df["Algeria"].fillna(df["Algeria"].mean())
df["Angola"] = df["Angola"].fillna(df["Angola"].mean())
df["Benin"] = df["Benin"].fillna(df["Benin"].mean())
df["Botswana"] = df["Botswana"] .fillna(df["Botswana"] .mean())
df["Burundi"] = df["Burundi"].fillna(df["Burundi"] .mean())
df["Central African Republic"] = df["Central African Republic"].fillna(df["Central African Republic"].mean())
df["Chad"] = df["Chad"].fillna(df["Chad"].mean())
df["Congo, Dem. Rep."] = df["Congo, Dem. Rep."].fillna(df["Congo, Dem. Rep."].mean())
df["Cote d'Ivoire"] = df["Cote d'Ivoire"].fillna(df["Cote d'Ivoire"].mean())
df["Egypt, Arab Rep."] = df["Egypt, Arab Rep."].fillna(df["Egypt, Arab Rep."].mean())
df["Equatorial Guinea"] = df["Equatorial Guinea"].fillna(df["Equatorial Guinea"].mean())
df["Eswatini"] = df["Eswatini"].fillna(df["Eswatini"].mean())
df["Ethiopia"] = df["Ethiopia"].fillna(df["Ethiopia"].mean())
df["Gabon"] = df["Gabon"].fillna(df["Gabon"].mean())
df["Gambia, The"] = df["Gambia, The"].fillna(df["Gambia, The"].mean())
df["Ghana"] = df["Ghana"].fillna(df["Ghana"].mean())
df["Guinea"] = df["Guinea"].fillna(df["Guinea"].mean())
df["Kenya"] = df["Kenya"].fillna(df["Kenya"].mean())
df["Lesotho"] = df["Lesotho"].fillna(df["Lesotho"].mean())
df["Liberia"] = df["Liberia"].fillna(df["Liberia"].mean())
df["Libya"] = df["Libya"].fillna(df["Libya"].mean())
df["Malawi"] = df["Malawi"].fillna(df["Malawi"].mean())
df["Mali"] = df["Mali"].fillna(df["Mali"].mean())
df["Morocco"] = df["Morocco"].fillna(df["Morocco"].mean())
df["Mozambique"] = df["Mozambique"] .fillna(df["Mozambique"].mean())
df["Namibia"] = df["Namibia"].fillna(df["Namibia"].mean())
df["Niger"] = df["Niger"].fillna(df["Niger"].mean())
df["Nigeria"] = df["Nigeria"].fillna(df["Nigeria"].mean())
df["Rwanda"] = df["Rwanda"].fillna(df["Rwanda"].mean())
df["Senegal"] = df["Senegal"].fillna(df["Senegal"].mean())
df["Somalia"] = df["Somalia"].fillna(df["Somalia"].mean())
df["South Africa"] = df["South Africa"].fillna(df["South Africa"].mean())
df["Sudan"] = df["Sudan"].fillna(df["Sudan"].mean())
df["Tanzania"] = df["Tanzania"].fillna(df["Tanzania"].mean())
df["Tunisia"] = df["Tunisia"].fillna(df["Tunisia"].mean())
df["Uganda"] = df["Uganda"].fillna(df["Uganda"].mean())
df["Zambia"] = df["Zambia"].fillna(df["Zambia"].mean())
df["Zimbabwe"] = df["Zimbabwe"].fillna(df["Zimbabwe"].mean())

Estadísticas descriptivas


El siguiente código recupera una tabla que muestra las estadísticas de tendencia central y dispersión de los datos:

python
# Resumen descriptivo (estadísticas descriptivas):
df.describe().transpose()

countmeanstdmin25%50%75%max
country
Algeria62.02206.0000001483.949316190.01155.0000001985.0000003035.0000005520.0
Angola62.01590.0000001048.747887180.0727.5000001590.0000001725.0000004830.0
Benin62.0526.833333395.50959790.0235.000000370.000000850.0000001370.0
Botswana62.02925.5000002438.96607080.0607.5000002927.7500005230.0000007570.0
Burundi62.0169.16666768.50371950.0120.000000169.166667230.000000260.0
Central African Republic62.0316.166667140.23506880.0242.500000316.166667420.000000570.0
Chad62.0356.666667263.542491110.0190.000000225.000000515.000000980.0
Congo, Dem. Rep.62.0297.857143102.674995110.0297.857143297.857143297.857143580.0
Cote d'Ivoire62.0900.500000574.017835160.0600.000000765.0000001105.0000002450.0
Egypt, Arab Rep.62.01278.000000956.810617170.0552.5000001165.0000001427.5000003510.0
Equatorial Guinea62.04377.7500004043.103615130.0717.5000004377.7500005444.43750014250.0
Eswatini62.02521.142857887.719073300.01937.5000002521.1428573245.0000004420.0
Ethiopia62.0332.051282191.501226110.0210.000000332.051282332.051282960.0
Gabon62.04275.5000002489.630577330.03145.0000004265.0000005685.0000009330.0
Gambia, The62.0483.703704217.807979110.0300.000000483.703704682.500000890.0
Ghana62.0681.333333635.327376190.0300.000000390.000000681.3333332360.0
Guinea62.0573.529412145.127218340.0492.500000573.529412573.5294121010.0
Kenya62.0549.000000478.665152100.0262.500000390.000000572.2500002010.0
Lesotho62.0692.142857412.66711280.0412.500000645.0000001102.5000001500.0
Liberia62.0478.50000095.750273180.0478.500000478.500000478.500000650.0
Libya62.09093.0000001426.9939755140.09093.0000009093.0000009093.00000012900.0
Malawi62.0221.666667143.80276450.0132.500000175.000000307.500000630.0
Mali62.0382.830189236.18121260.0225.000000310.000000490.000000870.0
Morocco62.01551.851852923.661768220.0807.5000001405.0000002197.5000003350.0
Mozambique62.0419.31034598.262463190.0419.310345419.310345419.827586690.0
Namibia62.03228.0000001158.0257371320.02272.5000003228.0000003905.0000005950.0
Niger62.0322.666667139.939878150.0220.000000285.000000405.000000590.0
Nigeria62.0954.166667809.165309100.0367.500000635.0000001425.0000002940.0
Rwanda62.0323.333333236.52308440.0152.500000270.000000357.500000850.0
Senegal62.0863.888889321.886940310.0642.500000863.8888891020.0000001540.0
Somalia62.0172.77777892.44601670.0112.500000172.777778172.777778450.0
South Africa62.03595.5000002210.700820530.01807.5000003230.0000005835.0000008370.0
Sudan62.0674.500000553.375410140.0340.000000480.000000782.5000002420.0
Tanzania62.0577.500000236.254933160.0505.000000577.500000577.5000001140.0
Tunisia62.02103.0909091257.362413220.01165.0000002103.0909093265.0000004390.0
Uganda62.0450.263158193.479671180.0292.500000450.263158450.263158850.0
Zambia62.0656.000000444.504513190.0360.000000450.000000712.5000001800.0
Zimbabwe62.0719.666667332.590265260.0452.500000690.000000857.5000001400.0

El siguiente código determina el INB per cápita de los primeros cinco países a lo largo del tiempo (consulte el gráfico):

python
import matplotlib.pyplot as plt

# Gráfico lineal del INB per cápita de África:
df.iloc[::,0:5].plot()
plt.title("INB per cápita, gráfico lineal del método Atlas (US$ actuales)")
plt.xlabel("Fecha")
plt.ylabel("INB per cápita, método Atlas (US$ actuales)")

# GNI per cápita de África:
plt.show()

png

El gráfico muestra que, desde 1960 hasta 2020, Burundi tiene el INB per cápita más bajo entre los cinco países. También muestra que el INB per cápita de Argelia, Angola, Benin y Botswana aumentó a principios de la década de 2000.

Reducción de dimensiones


El siguiente código aplica el análisis de componentes principales para reducir los datos en dos dimensiones y luego el siguiente código representa gráficamente los datos reducidos utilizando un diagrama de dispersión bidimensional (vease el gráfico resultante). Antes de realizar un análisis de dimensiones, se deben estandarizar los datos (centrar los datos para que el valor medio sea 0 y la desviación estándar sea 1):

python
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler

# Estandarizar los datos: 
escalador = StandardScaler()
df_estandarizado = escalador.fit_transform(df)
python
from sklearn.decomposition import PCA

# Reducir los datos:
acp2 = PCA(n_components = 3)
acp2.fit(df_estandarizado)
x_3d = acp2.transform(df_estandarizado)
plt.scatter(x_3d[:, 0], 
            x_3d[:, 2], 
            c = df['South Africa'],
            cmap = "viridis",
            s = 200)
plt.title("Datos 2-D de desigualdad en África")
plt.xlabel("y")

# Datos bidimensionales:
plt.show()

png

El gráfico anterior muestra el INB per cápita de los países africanos en un gráfico de dispersión bidimensional.

Detección de número de clúster


El siguiente código usa la curva del codo para identificar el número de conglomerados que se incluirán antes de entrenar el modelo de k-medias. Un gráfico del codo traza el valor propio o eigenvalor (un vector escalar después de una transformación lineal) en el eje y y el número de k en el eje x.

python
# Curva del codo:
acp = PCA(n_components = 3).fit(df_estandarizado)
acp_df = acp.transform(df_estandarizado)

from sklearn.cluster import KMeans

# Número de clústeres:
Nc = range(1, 20)
kmedias = [KMeans(n_clusters = i) for i in Nc]

# Puntuaciones:
puntuaciones = [kmedias[i].fit(acp_df).score(acp_df) for i in range(len(kmedias))]

# Gráfico:
fig, ax = plt.subplots()
plt.plot(Nc, 
         puntuaciones, 
         color = "navy", 
         lw = 4)
plt.xlabel("Número de clústeres")
plt.title("Curva del codo")
plt.ylabel("Puntuación")

# Curva del codo:
plt.show()

png

El gráfico muestra la curva del codo. El eje x es el número de k (que representa el número de grupos) y el eje y es la distorsión (que representa los valores propios, un escalar recuperado después de una transformación lineal). El eje y revela mucho sobre la severidad de la correlación entre las variables en estos datos, también llamados WSS (o dentro de grupos de sumas de cuadrados, por sus siglas en ingles: “within clusters of sums of squares”). Para determinar cuántos conglomerados debe incluir, debe determinar el punto de corte. Para seleccionar el punto de corte, debe identificar el punto en el que la curva del codo comienza a doblarse drásticamente. En este caso, el número de clústeres es tres.

Desarrollo del modelo de K-medias


El siguiente código entrena el modelo de k-medias aplicando todos los datos y el número de conglomerado (tres):

python
# Desarrollo del modelo de K-medias:
kmedias = KMeans(n_clusters = 3,
                 copy_x = False,
                 max_iter = 1,
                 n_init = 10,
                 tol= 1.0)
salida_kmedias = kmedias.fit(acp_df)

# Configuración k-medias:
salida_kmedias
KMeans(copy_x=False, max_iter=1, n_clusters=3, tol=1.0)

Predicciones

El siguiente código predice las etiquetas (ver la tabla resultante):

python
import pandas as pd

# predicciones:
y_predicciones_kmedias = pd.DataFrame(salida_kmedias.labels_, 
                                      columns = ["Clústeres"])

# Etiquetas pronosticadas:
y_predicciones_kmedias

Clústeres
00
10
22
32
42
......
571
581
591
601
611

62 rows × 1 columns

El código anterior no revela mucho acerca de cómo el modelo de k-medias estima las etiquetas.

Detección de centros de clústeres

El siguiente código recupera una tabla que muestra el valor medio de cada grupo:

python
# Buscar centros de clústeres:
centros = salida_kmedias.cluster_centers_
centroidess = pd.DataFrame(centros).transpose()
centroidess.columns = ["Clúster 1", "Clúster 2", "Clúster 3"]

# Centros de conglomerados:
centroidess

Clúster 1Clúster 2Clúster 3
0-1.7486368.956419-4.187186
11.463747-0.473839-2.278964
20.444593-0.170266-0.670509

El siguiente código genera un gráfico que muestra las etiquetas estimadas:

python
# Dispersión del INB per cápita de África:
fig, ax = plt.subplots()
plt.scatter(acp_df[:, 0],
            acp_df[:, 1],
            c = salida_kmedias.labels_,
            cmap = "viridis",
            s = 200)
plt.scatter(centros[:, 0], 
            centros[:, 1], 
            color = "red")
plt.title("INB per cápita de África, clústeres del método Atlas (US$ actuales)")
plt.xlabel("y")

# África INB per cápita modelo k-medias:
plt.show()

png

El gráfico muestra los puntos de datos (resaltados en amarillo, morado y verde) en sus respectivos grupos (puntos rojos).

Análisis de resultados de conglomerados


Para comprender mejor las etiquetas pronosticadas del siguiente código, consulte la tabla resultante:

python
# Tabla de conglomerados del INB per cápita de África:
stocks = pd.DataFrame(df.columns)
etiquetas_cluster = pd.DataFrame(kmedias.labels_)
stock_clusteres = pd.concat([stocks, etiquetas_cluster], 
                            axis = 1)
stock_clusteres.columns = ["País", "Clústeres"]
stock_clusteres = stock_clusteres.replace({0: "INB per cápita bajo",1: "INB per cápita moderado",2: "INB per cápita alto"})

# Tabla de conglomerados del INB per cápita de África:
stock_clusteres.head(20)

PaísClústeres
0AlgeriaINB per cápita bajo
1AngolaINB per cápita bajo
2BeninINB per cápita alto
3BotswanaINB per cápita alto
4BurundiINB per cápita alto
5Central African RepublicINB per cápita alto
6ChadINB per cápita alto
7Congo, Dem. Rep.INB per cápita alto
8Cote d'IvoireINB per cápita alto
9Egypt, Arab Rep.INB per cápita alto
10Equatorial GuineaINB per cápita alto
11EswatiniINB per cápita alto
12EthiopiaINB per cápita alto
13GabonINB per cápita alto
14Gambia, TheINB per cápita alto
15GhanaINB per cápita alto
16GuineaINB per cápita alto
17KenyaINB per cápita alto
18LesothoINB per cápita alto
19LiberiaINB per cápita bajo

El siguiente código simplifica los datos de la tabla anterior (consultar la gráfica resultante):

python
# Número de conglomerados del INB per cápita de África: 
serie_clases = stock_clusteres.groupby("Clústeres").size()
serie_clases.name = "Cuenta"
serie_clases.plot.pie(autopct = "%2.f",
                      cmap = "Blues_r")
plt.title("Gráfico circular de clústeres")

# Recuento de conglomerados del INB per cápita de África:
plt.show()

png

El gráfico muestra que el 27 tiene un INB per cápita alto, el 23 de los países tiene un INB per cápita moderado y el 50 tiene un INB per cápita bajo.

Evaluación del modelo de K-Means


El modelo de k-medias no hace suposiciones extremas sobre los datos. Se puede aplicar sin una hipótesis predeterminada: Establece la verdad sobre los datos en lugar de probar afirmaciones. Tampoco cuenta con matrices robustas de evaluación de modelos.

Los métodos de la silueta

Puede confiar en el método de Silhouette para determinar hasta qué punto el modelo realiza estimaciones inteligentes (consulte el siguiente código). En este contexto, estima la diferencia entre la distancia media del cúmulo más cercano y la distancia dentro del cúmulo y la distancia media máxima del cúmulo más cercano y la distancia dentro del cúmulo. Devuelve valores que van de 1 a 1, donde:

  • 1 indica un modelo deficiente.
  • 0 indica un modelo mediocre.
  • 1 indica un modelo que es ejemplar en la realización de cálculos aproximados.
python
# Encontrar la puntuación de silueta:
from sklearn import metrics
metrics.silhouette_score(df, y_predicciones_kmedias)
0.4332307316309596

La puntuación de la silueta es 0.4332307316309596. Lo cual significa que el clasificador es mediocre al estimar etiquetas de INB per cápita para los países africanos.

Conclusión


En la presente entrada expongo un modelo de aprendizaje automático no supervisado para la agrupación en clústeres, llamado modelo k-means. Desarrolló un modelo con hiperparámetros predeterminados. Estimó la distancia entre los valores del INB per cápita en los países de África. Posteriormente, agrupó a los países en clusters por INB per cápita. Finalmente, concluyo con una breve discusión sobre el aprendizaje automático no supervisado.

popular post

El modelo AR de series temporales univariadas

Resumen: En esta entrada, descubrirá el modelo AR: El modelo autorregresivo.

Leer más

Evaluación de modelos para pronosticar

Resumen: Al desarrollar modelos de aprendizaje automático, generalmente se comparan varios modelos durante la fase de construcción.

Leer más

Modelos para pronosticar

Resumen: El pronóstico, traducido groseramente como la tarea de predecir el futuro, ha estado presente en la sociedad humana durante siglos.

Leer más