Detección de leyes de potencia en datos del mundo real con Python |  por Shawhin Talebi

En el Artículo anterior, nos centramos en dos tipos de distribuciones: la distribución gaussiana y la distribución de la ley de potencia. Vimos que estas distribuciones tenían propiedades estadísticas diametralmente opuestas. A saber, Las leyes de potencia están impulsadas por eventos raros, mientras que las gaussianas no lo están..

Ejemplo de distribuciones gaussianas y de ley de potencia, respectivamente. Imagen del autor

Esta propiedad impulsada por eventos raros planteó 3 problemas con muchas de nuestras herramientas estadísticas favoritas (por ejemplo, media, desviación estándar, regresión, etc.) para analizar las leyes de potencia. La conclusión fue que si los datos son de tipo gaussiano, se pueden utilizar enfoques comunes como la regresión y calcular los valores esperados sin preocupaciones. Sin embargo, si los datos son más Ley de potencia similar, Estas técnicas pueden dar resultados incorrectos y engañosos..

También vimos una tercera distribución (más traviesa) que podría parecerse tanto a una ley gaussiana como a una ley de potencia (a pesar de sus propiedades opuestas) llamada Registro Distribución normal.

La (traviesa) distribución Log Normal parece tanto guassiana como de ley de potencia. Imagen del autor.

Esta ambigüedad presenta desafíos para los profesionales a la hora de decidir la mejor forma de analizar un conjunto de datos determinado. Para ayudar a superar estos desafíos, puede resultar ventajoso determinar si los datos se ajustan a una ley de potencia, un registro normal o algún otro tipo de distribución.

Una forma popular de adaptar una ley de potencia a datos del mundo real es lo que llamaré “enfoque Log-Log”. [1]. La idea surge de tomando el logaritmo de la función de densidad de probabilidad de la ley de potencia (PDF)como se deriva a continuación.

Tomando el registro de la función de distribución de probabilidad de la ley de potencia [2]. Imagen del autor.

La derivación anterior traduce la definición de PDF de la Ley de Potencias en una ecuación lineal, como se muestra en la siguiente figura.

Resalte la forma lineal del registro (PDF). Imagen del autor.

Esto implica que el El histograma de datos que sigue una ley de potencia seguirá una línea recta.. En la práctica, esto parece generar un histograma para algunos datos y trazarlo en un diagrama log-log. [1]. Se podría ir aún más lejos y realizar una regresión lineal para estimar el valor α de la distribución (aquí, α = -m+1).

Sin embargo, este enfoque tiene limitaciones importantes. Estos se describen en la referencia. [1] y resumido a continuación.

  • Las estimaciones de la pendiente (por lo tanto α) están sujetas a errores sistemáticos
  • Los errores de regresión pueden ser difíciles de estimar
  • El ajuste puede verse bien incluso si la distribución no sigue una ley de potencia
  • Es posible que los ajustes no obedezcan las condiciones básicas para las distribuciones de probabilidad, por ejemplo, la normalización.

Si bien el enfoque Log-Log es sencillo de implementar, sus limitaciones lo hacen menos que óptimo. En lugar de ello, podemos recurrir a un enfoque matemáticamente más sólido a través de Máxima verosimilituduna estadística ampliamente utilizada método para inferir la mejor parámetros para un modelo dado algunos datos.

La Máxima Probabilidad consta de 2 pasos clave. Paso 1: obtener una función de verosimilitud. Paso 2: maximiza la probabilidad con respecto a los parámetros de tu modelo.

Paso 1: escribir la función de probabilidad

Probabilidad es un tipo especial de probabilidad. En pocas palabras, Cuantifica la probabilidad de nuestros datos dado un modelo particular.. Podemos expresarlo como la probabilidad conjunta de todos nuestros datos observados. [3]. En el caso de una distribución de Pareto, podemos escribirla de la siguiente manera.

Función de probabilidad para la distribución de Pareto (es decir, un tipo especial de ley de potencia) [4]. Nota: cuando se trabaja con funciones de probabilidad, las observaciones (es decir, x_i) son fijas, mientras que los parámetros del modelo varían. Imagen del autor.

Para facilitar un poco la maximización de la probabilidad, se acostumbra trabajar con el log de verosimilitud (se maximizan por el mismo valor de α).

Derivación de probabilidad logarítmica [4]. Imagen del autor.

Paso 2: Maximizar la probabilidad

Con una función de verosimilitud (log) en la mano, ahora podemos encuadrar la tarea de determinar la mejor elección de parámetros como un problema de optimización. Para encontrar el valor α óptimo según nuestros datos, esto se reduce a establecer la derivada de l(α) con respecto a α igual a cero y luego resolviendo para α. A continuación se proporciona una derivación de esto.

Derivación del estimador de máxima verosimilitud para α [4]. Imagen del autor.

Esto nos proporciona el llamado Estimador de máxima verosimilitud para α. Con esto, podemos sustituir los valores observados de x para estimar el valor α de una distribución de Pareto.

Una vez establecida la base teórica, veamos cómo se ve esto cuando se aplica a datos del mundo real (de mis cuentas de redes sociales).

Un ámbito en el que prevalecen los datos de cola gruesa son las redes sociales. Por ejemplo, un pequeño porcentaje de creadores recibe la mayor parte de la atención, una minoría de blogs de Medium obtiene la mayoría de las lecturas, etc.

Aquí usaremos el ley de potencia Biblioteca de Python para determinar si los datos de mis diversos canales de redes sociales (es decir, Medium, YouTube, LinkedIn) realmente sigue una distribución de ley de potencia. Los datos y el código de estos ejemplos están disponibles en el repositorio de GitHub.

Datos artificiales

Antes de aplicar el enfoque basado en Máxima Verosimilitud a datos confusos del mundo real, veamos qué sucede cuando aplicamos esta técnica a datos artificiales (realmente) generados a partir de distribuciones de Pareto y Log Normal, respectivamente. Esto ayudará a fundamentar nuestras expectativas antes de utilizar el enfoque en datos en los que no conocemos la “verdadera” clase de distribución subyacente.

Primero, importamos algunas bibliotecas útiles.

import numpy as np
import matplotlib.pyplot as plt
import powerlaw
import pandas as pd

np.random.seed(0)

A continuación, generemos datos a partir de distribuciones de Pareto y Log Normal.

# power law data
a = 2
x_min = 1
n = 1_000
x = np.linspace(0, n, n+1)
s_pareto = (np.random.pareto(a, len(x)) + 1) * x_min

# log normal data
m = 10
s = 1
s_lognormal = np.random.lognormal(m, s, len(x)) * s * np.sqrt(2*np.pi)

Para tener una idea de cómo se ven estos datos, resulta útil trazar histogramas. Aquí, trazo un histograma de los valores brutos de cada muestra y el registro de los valores brutos. Esta última distribución hace que sea más fácil distinguir visualmente entre datos de ley de potencia y datos de registro normal.

Histogramas de datos de distribución de la ley de potencia. Imagen del autor.
Histogramas de datos de distribución Log Normal. Imagen del autor.

Como podemos ver en los histogramas anteriores, las distribuciones de valores brutos parecen cualitativamente similares para ambas distribuciones. Sin embargo, podemos ver una marcada diferencia en las distribuciones de registros. Es decir, la distribución logarítmica de la ley de potencia está muy sesgada y no está centrada en la media, mientras que el registro de la distribución logarítmica normal recuerda a una distribución gaussiana.

Ahora podemos usar el ley de potencia biblioteca para ajustar una ley de potencia a cada muestra y estimar los valores para α y x_min. Así es como se ve en nuestro ejemplo de Ley de potencia.

# fit power to power law data
results = powerlaw.Fit(s_pareto)

# printing results
print("alpha = " + str(results.power_law.alpha)) # note: powerlaw lib's alpha definition is different than standard i.e. a_powerlawlib = a_standard + 1
print("x_min = " + str(results.power_law.xmin))
print('p = ' + str(compute_power_law_p_val(results)))

# Calculating best minimal value for power law fit
# alpha = 2.9331912195958676
# x_min = 1.2703447024073973
# p = 0.999

El ajuste hace un trabajo decente al estimar los valores verdaderos de los parámetros (es decir, a=3, x_min=1), como se ve en los valores alfa y x_min impresos arriba. El valor p anterior cuantifica la calidad del ajuste. Una p más alta significa un mejor ajuste (más sobre este valor en la sección 4.1 de la ref. [1]).

Podemos hacer algo similar para la distribución Log Normal.

# fit power to log normal data
results = powerlaw.Fit(s_lognormal)
print("alpha = " + str(results.power_law.alpha)) # note: powerlaw lib's alpha definition is different than standard i.e. a_powerlawlib = a_standard + 1
print("x_min = " + str(results.power_law.xmin))
print('p = ' + str(compute_power_law_p_val(results)))

# Calculating best minimal value for power law fit
# alpha = 2.5508694755027337
# x_min = 76574.4701482522
# p = 0.999

Podemos ver que la muestra Log Normal también se ajusta bien a una distribución de Ley de Potencia (p=0,999). Observe, sin embargo, que el valor x_min está muy al final. Si bien esto puede resultar útil para algunos casos de uso, no nos dice mucho sobre la distribución que mejor se ajusta a todos los datos de la muestra.

Para superar esto, podemos establecer manualmente el valor x_min al mínimo de la muestra y rehacer el ajuste.

# fixing xmin so that fit must include all data
results = powerlaw.Fit(s_lognormal, xmin=np.min(s_lognormal))
print("alpha = " + str(results.power_law.alpha))
print("x_min = " + str(results.power_law.xmin))

# alpha = 1.3087955873576855
# x_min = 2201.318351239509

El método .Fit() también genera automáticamente estimaciones para una distribución Log Normal.

print("mu = " + str(results.lognormal.mu))
print("sigma = " + str(results.lognormal.sigma))

# mu = 10.933481999687547
# sigma = 0.9834599169175509

Los valores estimados de los parámetros Log Normal están cerca de los valores reales (mu=10, sigma=1), por lo que el ajuste hizo un buen trabajo una vez más.

Sin embargo, al corregir x_min, perdimos nuestra métrica de calidad p (por alguna razón, el método no genera valores cuando se proporciona x_min). Entonces esto plantea la pregunta, ¿Qué parámetros de distribución debería seguir? ¿La ley de potencia o el registro normal?

Para responder a esta pregunta, podemos comparar el ajuste de la Ley de potencia con otras distribuciones candidatas mediante Ratios de probabilidad logarítmica (R). Una R positiva implica que la Ley de potencia se ajusta mejor, mientras que una R negativa implica que la distribución alternativa es mejor. Además, cada comparación nos da un valor de significancia (p). Esto se demuestra en el bloque de código siguiente.

distribution_list = ['lognormal', 'exponential', 'truncated_power_law', \
'stretched_exponential', 'lognormal_positive']

for distribution in distribution_list:
R, p = results.distribution_compare('power_law', distribution)
print("power law vs " + distribution +
": R = " + str(np.round(R,3)) +
", p = " + str(np.round(p,3)))

# power law vs lognormal: R = -776.987, p = 0.0
# power law vs exponential: R = -737.24, p = 0.0
# power law vs truncated_power_law: R = -419.958, p = 0.0
# power law vs stretched_exponential: R = -737.289, p = 0.0
# power law vs lognormal_positive: R = -776.987, p = 0.0

Como se muestra arriba, se prefiere cualquier distribución alternativa a la ley de potencia cuando se incluyen todos los datos en la muestra Log Normal. Además, según los índices de probabilidad, los ajustes lognormal y lognormal_positivo funcionan mejor.

Datos del mundo real

Ahora que hemos aplicado el ley de potencia biblioteca de datos donde conocemos la verdad fundamental, probémoslo con datos cuya distribución subyacente se desconoce.

Seguiremos un procedimiento similar al anterior pero con datos del mundo real. Aquí analizaremos los siguientes datos. Seguidores mensuales ganados en mi Medio perfil, ganancias en todos mis YouTube vídeos e impresiones diarias en mi LinkedIn publicaciones del año pasado.

Comenzaremos trazando histogramas.

Los seguidores medios ganaron histogramas. Imagen del autor.
Histogramas de ganancias de vídeos de YouTube. Imagen del autor.
Histogramas de impresiones diarias de LinkedIn. Imagen del autor.

De estas tramas me saltan dos cosas. Unolos tres se parecen más a los histogramas Log Normal que a los histogramas de Ley de potencia que vimos antes. Doslas distribuciones de Medium y YouTube son escasas, lo que significa que es posible que no tengan datos suficientes para sacar conclusiones sólidas.

A continuación, aplicaremos el ajuste de la ley de potencia a las tres distribuciones y estableceremos x_min como el valor más pequeño en cada muestra. Los resultados de esto se imprimen a continuación.

Estimaciones de parámetros de ley de potencia y registro normal para datos empíricos. Imagen del autor.

Para determinar qué distribución es mejor, podemos nuevamente hacer comparaciones directas del ajuste de la Ley de potencia a algunas alternativas. Estos resultados se dan a continuación.

Comparaciones de ajuste de Ley de Potencias y distribuciones alternativas. Imagen del autor.

Utilizando la regla general del límite de significancia de p<0,1, podemos sacar las siguientes conclusiones. Los seguidores medios y las impresiones de LinkedIn se ajustan mejor a una distribución Log Normal, mientras que una Ley de potencia representa mejor las ganancias de YouTube.

Por supuesto, dado que los datos de seguidores de Medium y pendientes de YouTube aquí son limitados (N<100), debemos tomar cualquier conclusión de esos datos con cautela.

Muchas herramientas estadísticas estándar fallan cuando se aplican a datos que siguen una distribución de ley de potencia. En consecuencia, detectar leyes de potencia en datos empíricos puede ayudar a los profesionales a evitar análisis incorrectos y conclusiones engañosas.

Sin embargo, las Leyes de Potencias son un caso extremo del fenómeno más general de colas gordas. En el próximo artículo de esta serie, llevaremos este trabajo un paso más allá y cuantificaremos la cola gruesa para cualquier conjunto de datos determinado mediante 4 prácticas heurísticas.