Fitting
Muestras y ajuste de distribuciones
Ajuste de datos a una distribución
Encontrar la función de distribución que mejor representa una muestra de datos es una tarea común en estadística y modelado de datos. Esto se conoce como ajuste de distribuciones y es útil en muchos campos, como la inferencia estadística, la simulación y el modelado predictivo.
Puede decirse que, para encontrar la mejor función de distribución, existe un metodo básico o clásico y luego, con la evolución tecnológica, aparecen metodos más automatizados y eficientes para hacer el mismo trabajo.
Los estadísticos hoy en día prefieren enfoques prácticos y automatizados para esta tarea, usando software y scripts en Python o en R que permiten iterar rápidamente entre varias distribuciones y métricas de bondad de ajuste. En investigaciones y aplicaciones más avanzadas, es común emplear herramientas de modelado Bayesiano o técnicas de optimización específicas para distribuciones en casos donde la elección de distribución tenga un impacto crítico en los resultados.
Método clásico para encontrar la mejor función de distribución
Análisis exploratorio de los datos: Visualiza la forma de la muestra con un histograma, un gráfico de densidad (KDE), o un boxplot.
Observa medidas de centralidad (media, mediana) y dispersión (desviación estándar, rango intercuartílico) para tener una idea de la forma de la distribución.Selección de posibles distribuciones: Basándote en la forma de la muestra, elige algunas distribuciones candidatas (por ejemplo, normal, exponencial, gamma, lognormal, beta).
Utiliza el conocimiento sobre los datos: por ejemplo, si los datos son positivos, es poco probable que una distribución normal sea apropiada.Ajuste de las distribuciones y cálculo de parámetros: Ajusta cada distribución candidata a los datos para estimar sus parámetros, usando métodos de máxima verosimilitud o mínimos cuadrados.
Evaluación de la bondad de ajuste: Calcula medidas de bondad de ajuste, como el estadístico de la prueba de Kolmogorov-Smirnov, el error cuadrático medio, o el valor de la log-verosimilitud para comparar distribuciones.
Utiliza pruebas formales o visualizaciones (gráfico Q-Q) para evaluar qué tan bien se ajusta cada distribución.
Muestras, distribuciones e inferencias
En el análisis de datos y la estadística aplicada, seleccionar la distribución estadística que mejor representa una muestra de datos es un paso fundamental para realizar inferencias precisas y hacer predicciones fiables. Cada conjunto de datos presenta características únicas que pueden ajustarse mejor a una distribución específica, y elegir incorrectamente dicha distribución puede llevar a errores significativos en el modelado y en la interpretación de los resultados. Por esta razón, una parte importante del análisis estadístico consiste en identificar cuál de las numerosas distribuciones disponibles (como normal, exponencial, gamma, beta, entre otras) se ajusta mejor a una muestra dada.
Históricamente, seleccionar la mejor distribución implicaba conocimiento especializado y cálculos manuales, donde los estadísticos elegían y evaluaban visual y matemáticamente posibles ajustes de distribución. Sin embargo, el crecimiento en la cantidad y diversidad de datos en múltiples disciplinas ha hecho de este enfoque algo poco práctico.
Actualmente, existe una amplia variedad de distribuciones estadísticas y criterios de ajuste que pueden ser utilizados para modelar los datos, y este proceso se ha facilitado enormemente con la ayuda de herramientas computacionales.
Con el desarrollo de lenguajes y librerías de programación estadística, como `Python` y sus paquetes estadísticos, ahora es posible automatizar la selección de la distribución más adecuada, haciendo el análisis de datos más accesible y preciso para investigadores y profesionales.
Ajuste de distribuciones con python
`Python` ha emergido como uno de los lenguajes de programación más utilizados en ciencia de datos, gracias a su flexibilidad y la potencia de sus librerías especializadas. Dos de las librerías más relevantes para el ajuste de distribuciones en `Python` son `scipy.stats` y `fitter`.
`scipy.stats`** es un paquete robusto y versátil que forma parte de `SciPy`, una biblioteca científica de Python ampliamente utilizada en la comunidad científica y académica. Este paquete proporciona una gran variedad de distribuciones estadísticas y métodos de ajuste, así como pruebas de hipótesis y métricas de bondad de ajuste. Si bien `scipy.stats` permite a los usuarios ajustar datos a diferentes distribuciones y realizar comparaciones, el proceso puede ser laborioso cuando se desean probar múltiples distribuciones, ya que implica realizar manualmente el ajuste y evaluación de cada una.
`fitter` es una librería de Python diseñada específicamente para facilitar el ajuste y la comparación de múltiples distribuciones de manera automática. Utilizando `fitter`, los usuarios pueden ajustar una muestra de datos a varias distribuciones al mismo tiempo y seleccionar automáticamente la mejor distribución en función de criterios predefinidos, como el error cuadrático medio (SSE) o el criterio de información de Akaike (AIC). Esta automatización permite identificar rápidamente cuál distribución representa mejor una muestra de datos, lo que ahorra tiempo y reduce la posibilidad de errores en el proceso de selección.
La capacidad de ajustar automáticamente múltiples distribuciones a los datos es particularmente útil en análisis exploratorios, donde los analistas pueden no tener un conocimiento previo de la distribución que sigue la variable de interés. Herramientas como `fitter` han hecho posible que los analistas puedan enfocarse en la interpretación de resultados y en la toma de decisiones basadas en datos sin la necesidad de realizar ajustes manuales y repetitivos. Además, la sinergia entre `fitter` y `scipy.stats` permite a los analistas aprovechar el amplio conjunto de distribuciones disponibles en `scipy.stats` mientras automatizan el proceso de selección de la mejor distribución usando `fitter`.
Metodo avanzado de ajuste con python fitter
Para ajustar distribuciones en Python es comenzar con una herramienta automatizada como fitter
para hacer una selección inicial, seguida en algunos casos por un ajuste fino o una validación detallada con scipy.stats
. Esta metodología permite un balance entre eficiencia y precisión:
Primera fase (selección automática): La mayoría de los estadísticos y analistas de datos optan por herramientas como
fitter
o métodos similares porque permiten probar rápidamente múltiples distribuciones y determinar cuál tiene un mejor ajuste según criterios como el SSE o el AIC. Esto es particularmente útil en la etapa de exploración de datos, donde no siempre se tiene una suposición clara sobre la distribución subyacente.Segunda fase (ajuste fino y validación): Luego de identificar una o más distribuciones con un buen ajuste,
scipy.stats
es una herramienta valiosa para el ajuste detallado y la validación. Los estadísticos suelen utilizarla para:
Refinar los parámetros de la distribución ajustada.
Realizar pruebas de hipótesis (como la prueba de Kolmogorov-Smirnov) para validar la adecuación de la distribución seleccionada.
Visualizar comparaciones detalladas entre las distribuciones ajustadas y los datos reales, lo que facilita la detección de pequeñas discrepancias.
Metodos más avanzados y especializados
Para análisis avanzados en los que la elección de una distribución precisa tiene un impacto significativo, como en investigaciones científicas y financieras, existen técnicas especializadas. Aquí te detallo dos enfoques más sofisticados que están ganando relevancia actualmente: modelado bayesiano y técnicas de optimización.
1. Modelado Bayesiano
El modelado bayesiano es una potente herramienta en estadística, especialmente para casos donde hay incertidumbre en torno a la selección de una distribución o sus parámetros. En el contexto de elegir una distribución adecuada para una muestra de datos, el modelado bayesiano permite incorporar conocimiento previo sobre la posible forma de la distribución y actualizar ese conocimiento a medida que se observa más información. Esto se hace mediante el uso de distribuciones a priori y distribuciones a posteriori, que reflejan el conocimiento antes y después de observar los datos. El modelado Bayesiano propone el siguiente procedimiento:
Definición de Priori: Se elige una distribución a priori para cada parámetro del modelo. Por ejemplo, si estamos ajustando una distribución normal, se pueden definir distribuciones a priori para la media y la desviación estándar basadas en el conocimiento existente o en suposiciones razonables.
Cálculo de la Distribución Posterior: Una vez que se han observado los datos, se usa el Teorema de Bayes para actualizar las distribuciones a priori y obtener una distribución a posteriori que refleje la probabilidad de los parámetros dada la muestra de datos.
Inferencia Bayesiana: Usando la distribución a posteriori, podemos estimar los parámetros más probables de la distribución de ajuste o realizar pruebas de hipótesis bayesianas para evaluar cuál de varias distribuciones es más probable.
Las herramientas más utilizadas para el modelado bayesiano son las siguientes:
PyMC3/PyMC y Stan son librerías populares para realizar modelado bayesiano en Python. Permiten definir modelos complejos y calcular las distribuciones posteriores mediante métodos de muestreo de Monte Carlo, como el algoritmo de muestreo de Hamiltoniano (HMC).
2. Técnicas de Optimización
La optimización se utiliza en el ajuste de distribuciones para encontrar los parámetros que minimizan la diferencia entre la distribución modelada y los datos. Para problemas complejos, donde el ajuste a múltiples distribuciones o la identificación de distribuciones mixtas es crucial, se emplean técnicas de optimización más avanzadas, como las siguientes:
Algoritmos de Máxima Verosimilitud: Gradient Descent (descenso de gradiente): Se utiliza para encontrar el valor óptimo de los parámetros ajustando la distribución a los datos a través de múltiples iteraciones.
L-BFGS-B (Limited-memory Broyden–Fletcher–Goldfarb–Shanno with Box constraints): Es una extensión de los métodos de descenso de gradiente diseñada para problemas con restricciones en los parámetros. Funciona bien para distribuciones con parámetros acotados.
Algoritmos Evolutivos y Metaheurísticos: Algoritmos Genéticos y Enjambre de Partículas: Son útiles para problemas de ajuste donde los parámetros tienen una gran cantidad de combinaciones posibles. Permiten explorar el espacio de búsqueda y, aunque son menos precisos que el ajuste paramétrico, pueden identificar distribuciones mixtas o complejas en los datos.
Las herramientas más utilizadas para emplear estas técnicas de ajuste son:
SciPy tiene varios métodos de optimización integrados que son útiles para el ajuste de distribuciones.
Optuna y Scikit-Optimize (skopt) ofrecen optimización bayesiana en Python.
DEAP (Distributed Evolutionary Algorithms in Python) es útil para implementar algoritmos evolutivos.
Ejemplo de Flujo Avanzado de Trabajo
Ajuste Inicial con Fitter: Comenzar el proceso de selección de distribución probando múltiples opciones con
fitter
para obtener una selección preliminar de distribuciones candidatas.Refinamiento Paramétrico con SciPy: Utilizar métodos de máxima verosimilitud en
scipy.stats
para ajustar parámetros con precisión y evaluar la calidad del ajuste.Modelado Bayesiano con PyMC3: Si se dispone de conocimiento previo sobre la distribución o los parámetros, realizar un ajuste bayesiano para incluir esa información, logrando un ajuste más robusto y considerando la incertidumbre de los datos.
Validación con Optimización Bayesiana o Metaheurística: Si el ajuste es complejo, emplear optimización bayesiana o algoritmos evolutivos para refinar el ajuste final, asegurando que el modelo elegido sea el óptimo global para representar los datos.
Este flujo asegura una evaluación integral y robusta de las posibles distribuciones, permitiendo tanto una selección eficiente como un ajuste preciso que respalde el análisis posterior.
Ajuste inicial con fitter
Al ser este el primer paso es importante entender que tan bien iniciamos cualquier analisis de este tipo ya que el ajuste, refinamiento y optimización posterior será tanto más bueno como mejor sea el paso inicial. Por eso es importante profundizar en este tema, a continuación.
Cada distribución tiene asociados distintos criterios de bondad de ajuste que nos ayudan a evaluar qué tan bien se ajusta a los datos observados. Aquí está una breve explicación de cada métrica y cómo influye en la selección de la mejor distribución:
sumsquare_error
: Este es el error cuadrático acumulado entre la distribución ajustada y los datos. Cuanto menor sea este valor, mejor se ajusta la distribución a los datos.aic
(Criterio de Información de Akaike): Es una medida de la calidad del modelo en términos de la probabilidad de la distribución ajustada, penalizando la complejidad del modelo (número de parámetros). Un valor de AIC más bajo sugiere un modelo mejor ajustado sin sobreajustar.bic
(Criterio de Información Bayesiano): Similar al AIC pero penaliza más fuertemente la complejidad del modelo. Es útil en situaciones donde se busca evitar modelos excesivamente complejos.kl_div
(Divergencia de Kullback-Leibler): Indica la distancia entre la distribución teórica ajustada y la distribución de datos observados.inf
sugiere que no se calculó en este ajuste, probablemente porque la implementación enfitter
no la tiene disponible para todas las distribuciones.ks_statistic
yks_pvalue
: Miden la bondad de ajuste mediante la prueba de Kolmogorov-Smirnov, que compara las distribuciones acumuladas de los datos observados y ajustados. Un valor bajo enks_statistic
y un valor alto enks_pvalue
indican un buen ajuste.
Ejemplo
Supongamos que trabajamos en un análisis financiero y tenemos una muestra de datos que representa la variabilidad diaria de los rendimientos de una cartera de inversiones. La distribución de los rendimientos en los mercados financieros suele tener colas gruesas, por lo que no necesariamente se ajustará bien a distribuciones normales. Queremos encontrar la distribución estadística que mejor representa estos datos para simular escenarios futuros y calcular métricas de riesgo con precisión.
Este ejemplo se comparte en un jupyter notebook en github.
Para disponer de una muestra de datos para analizar generamos la misma con spcipy.stats de manera que genere datos a partir de una distribución t pero con colas largas, mediante el siguiente código:
# Simulamos un conjunto de datos complejo con colas gruesas utilizando una distribución t-Student
np.random.seed(42)
data = stats.t.rvs(df=3, loc=0, scale=1, size=1000)
Luego graficamos los datos generados para analizar y los mismos se pueden observar en la figura corresondiente.
Paso 1: Ajuste inicial con Fitter
Una vez que disponemos los datos de la muestra, utilizamos fitter para observar las distribuciones que mejor ajustan.
# Usamos fitter para encontrar la mejor distribución
f = Fitter(data)
f.fit()
f.summary(plot=True)
Así obtenemos los resultados y la grafica que se observa en la figura correspondiente, con la consecuente interpretación. Con estos resultados, la elección de la mejor distribución se reduce principalmente a nct
y jf_skew_t
, ya que ambas tienen buenos resultados en varias métricas:
nct
tiene el menorsumsquare_error
y uno de los valores de BIC más bajos, por lo que es una opción fuerte.jf_skew_t
tiene el AIC más bajo, buenos valores deks_statistic
yks_pvalue
, lo que indica que también se ajusta bien y es simple.
Es importante tener una distribución con buena representación visual y un ajuste preciso, podrías probar ambos modelos en visualizaciones de histogramas y curvas de densidad para ver cuál captura mejor las características de tus datos.
Paso 2: Refinamiento Paramétrico con SciPy
Ahora que tenemos algunas distribuciones candidatas (nct
, jf_skew_t
, genhyperbolic
, etc.), en el siguiente paso usaremos scipy.stats
para hacer un ajuste más detallado y obtener los parámetros exactos de estas distribuciones en la muestra. Esto nos permitirá comparar sus densidades ajustadas con el histograma de los datos. Esto también permite una visualización precisa y una comparación directa.
# 1: Ajustar la distribución `nct`
params_nct = stats.nct.fit(data)
# 2: Ajustar la distribución `t` como un aproximado de `jf_skew_t`
# (en scipy.stats no existe jf_skew_t, pero podemos comparar con `t`)
params_t = stats.t.fit(data)
# 3: Generar la densidad ajustada para cada distribución
x = np.linspace(min(data), max(data), 1000)
pdf_nct = stats.nct.pdf(x, *params_nct)
pdf_t = stats.t.pdf(x, *params_t)
Explicación del Código
Ajuste con
stats.nct.fit
: Se ajusta la distribuciónnct
a los datos. Esta función devuelve los parámetros denct
que mejor se adaptan a la muestra.Ajuste con
stats.t.fit
: Dado quejf_skew_t
no está implementado enscipy.stats
, utilizamost
como aproximación. Aunque no es idéntica, lat
también modela colas pesadas y puede servir como proxy.Generación de la densidad ajustada: Calculamos las densidades (
pdf
) para ambos ajustes en un rango de valores (x
) que cubre los datos. Estas densidades nos permiten visualizar qué tan bien cada distribución se ajusta al histograma de los datos.
Interpretación
Si una de las curvas (por ejemplo,
nct
ot
) se ajusta mejor visualmente al histograma, entonces esa sería la mejor candidata.La distribución
nct
es una opción más flexible quet
ya que incluye una parametrización adicional, lo cual puede adaptarse mejor a algunas muestras de datos.Este ajuste también nos permite analizar cómo se comportan los datos en las colas (extremos) y en el centro, lo cual es crucial para muchas aplicaciones prácticas.
Los pasos 3 y 4 se realizarán en apartados posteriores.
Ejemplo: Análisis de calidad del aire
Otro ejemplo muy sencillo y acotado que es representativo del trabajo de análisis de datos y su representación por ajuste una distribución de probabilidad es el análisis de la calidad del aire en ciudades. Este tipo de análisis es crucial para entender y mitigar los efectos de la contaminación en la salud pública. Este tipo de estudios consta mínimamente de los siguientes pasos:
Recopilación de Datos: Se recogen datos sobre la concentración de diferentes contaminantes (como dióxido de nitrógeno, dióxido de azufre, partículas PM2.5, etc.) en diferentes ubicaciones de la ciudad a lo largo del tiempo.
Ajuste a Distribuciones: Los datos recopilados se ajustan a diferentes distribuciones de probabilidad (por ejemplo, distribuciones log-normal o exponenciales) para modelar la variabilidad y tendencias de la contaminación.
Análisis y Predicciones: Con los modelos ajustados, los científicos y responsables de políticas pueden analizar patrones, hacer predicciones sobre niveles futuros de contaminación y evaluar la efectividad de medidas de control.
Toma de Decisiones: Los resultados del análisis se utilizan para tomar decisiones informadas sobre políticas ambientales, como la implementación de zonas de bajas emisiones, restricciones de tráfico y mejoras en la infraestructura de transporte público.
Se desarrollan aquí de manera simulada los puntos 1 y 2 del estudio. Esta simulación se efectúa en python en un jupyter notebook, que se comparte en github. Utilizaremos datos simulados para las concentraciones de partículas PM2.5 y ajustaremos estos datos a una distribución log-normal, que es común en la modelación de contaminantes del aire.
Descripción del Código para resolver el problema
Este codigo está escrito en python en un jupyter notebook compartido en github.
Simulación de Datos:
Simulamos datos de concentraciones de PM2.5 usando una distribución log-normal.Descubrimiento de la Mejor Distribución Ajustada:
Probamos varias distribuciones (normal, exponencial, log-normal, gamma, beta) para encontrar la que mejor se ajuste a los datos.
Ajustamos cada distribución a los datos y calculamos el error cuadrático (SSE) entre los datos ajustados y los datos reales.
Seleccionamos la distribución con el SSE más bajo como la mejor.Visualización:
Visualizamos el histograma de los datos simulados junto con la mejor distribución ajustada.
Imprimimos el nombre de la mejor distribución y sus parámetros.
Este código descubrir cuál distribución se ajusta mejor a los datos simulados y visualizar el ajuste. Las graficas pueden verse en la figura correspondiente como así también los resultados:
Mejor Distribución: expon
Parámetros de la Mejor Distribución: (2.4768463748768963, 43.71068782002568)
Como puede verse en el jupyter notebook este problema se resuelve facilmente usando la librería scipy.stats y probando con varias distribuciones de la misma para ver cual ajusta mejor.
Sin embargo el problema podría haberse resuelto con la librería "Fitter" sin necesidad de ir probando con varias distribuciones. Esto también se muestra escrito en el mismo jupyter notebook y en las imagenes de los graficos corrspondientes de este apartado. En esta segunda opción de resolución puede interpretarse que la distribucón log-normal gana por lejos.
Sintesis de ajuste de distribuciones
El análisis de ajuste de distribuciones es en sí mismo todo un tema de estudio en estadística. Se trata de estudios que requieren de tiempo tanto de especialistas como de recursos computacionales. Se ha presentado en este apartado un paneo de como realizar este tipo de estudios y que luego son materia de estudios especificos dentro del mundo de la estadística y en función del caso.