Proyecto de Curso - Uso de modelos de aprendizaje automático que puedan predecir las fechas de migración de aves migratorias que llegan a Costa Rica utilizando los registros de avistamientos de eBird.¶
Curso Aprendizaje Automático aplicado a datos de Biodiversidad
Integrantes:
- José Abelardo Sánchez Cardoza - jabelardo.sc@gmail.com
- Cynthia María Tercero Rojas - cmtercero@gmail.com
Instructora:
- Emilia Zeledón
Asistente:
- Bejanmín Johnson
Agosto 29, 2024
Introducción¶
Anualmente más de 340 especies de aves migran desde Canadá y Estados Unidos hacia México, Centroamérica, Suramérica y el Caribe (Román, 2023). De estas, se sabe que al menos 220 especies pasan por Costa Rica (Sánchez, 2009) Las aves migratorias son especies que se desplazan para encontrar condiciones más favorables para la reproducción y la alimentación. Este comportamiento migratorio les permite sobrevivir en diversos ambientes y aprovechar los recursos en diferentes estaciones del año.
El fenómeno migratorio del hemisferio norte tiene lugar durante dos épocas del año: primavera y otoño. Contar con información sobre las fechas de desplazamiento de las aves migratorias es de interés para la conservación, ya que permite a los biólogos y ecologistas entender mejor los patrones y las necesidades de hábitat de estas especies. También ayuda en la planificación de estrategias para mitigar los impactos del cambio climático y la pérdida de hábitat. Además, proporciona datos importantes para estudiar la biodiversidad y los ecosistemas, contribuyendo a la gestión sostenible de las poblaciones de aves y sus hábitats.
Entrenar modelos de aprendizaje automático con registros históricos de avistamientos es crucial porque permite a los modelos aprender patrones de migración y comportamiento específicos de diversas especies, mejorando la precisión en la predicción de futuros desplazamientos y avistamientos. Además, estos registros proporcionan una base de datos extensa y diversa que ayuda a los modelos a ser extendidos para considerar diferentes condiciones ambientales, geográficas y variaciones estacionales, ampliando la posibilidad de predicción con combinación con otras variables complejas.
El proyecto que realizamos tiene por objetivo demostrar que los modelos de aprendizaje automático pueden ser utilizados para la predicción de fechas de avistamiento de aves migratorias, partiendo de información de observaciones pasadas registradas en plataformas de ciencia ciudadana.
Antecedentes¶
La predicción de las fechas de avistamiento de aves migratorias es importante para la conservación de los ecosistemas, ya que permite a la comunidad científica anticipar y mitigar el impacto del cambio climático y otros factores ambientales en las rutas migratorias y en las poblaciones de aves.
Bajo la premisa anterior, podemos citar el artículo escrito por André Cyr y Jaques Larivee: A Checklist Approach for Monitoring Neotropical Migrant Birds: Twenty-year Trends in Birds of Quebec Using EPOQ (Finch, 1992), que describe, cómo una de las primeras bases de datos con observaciones de avistamientos en Québec, en el período comprendido de 1970 a 1989, fue utilizada para monitorear aves migratorias en Canadá.
Por otra parte, el uso de la tecnología ha jugado un papel crucial, para asistir el proceso del monitoreo y rastreo de rutas de las aves migratorias, en este contexto podemos citar una de las investigaciones realizada en esta área: el uso de los primeros geo-localizadores de nivel de luz en miniatura descrito en el artículo: Ten years tracking the migrations of small landbirds: Lessons learned in the golden age of bio-logging (McKinnon, 2018).
Adicionalmente, con el auge y evolución de algoritmos para el procesamiento de datos y de manera específica: la inteligencia artificial, han surgido diversas iniciativas que partiendo de registros de observaciones de ciencia ciudadana y de la información proporcionada por el uso de sensores en aves migratorias, nos permiten tener mayor información sobre el comportamiento de las aves migratorias y de alguna manera predecir las rutas y fechas de migración, en este contexto se destaca el proyecto BirdFlow (Fuentes, 2023).
BirdFlow es una herramienta de inteligencia artificial desarrollada para llenar los vacíos en los datos de migración de aves proporcionados por eBird (eBird.org), una plataforma de ciencia ciudadana. Dado que eBird ofrece solo instantáneas de observaciones de aves en lugar de sus movimientos continuos, el equipo detrás de BirdFlow, con el apoyo de supercomputadoras como Bridges-2, ha utilizado estos datos junto con información de seguimiento por GPS para predecir rutas migratorias, tiempos y conectividad de aves. Al entrenar el modelo de AI con el vasto conjunto de datos de eBird y validarlo con datos de migración reales, BirdFlow ha mostrado prometedoras coincidencias con los patrones de aves rastreadas. Esta herramienta tiene el potencial de avanzar en la ecología de migración, conservación, vigilancia de enfermedades y otras áreas, a pesar de desafíos como la calidad y distribución desigual de los datos.
Objetivo del proyecto¶
Este proyecto tiene por objetivo aplicar dos modelos de aprendizaje automático supervisado para predecir si una especie de ave migratoria estará o no presente en una ubicación geográfica en una fecha determinada, partiendo del registro de sus avistamientos en años anteriores.
El modelo debe optimizar el uso de las características disponibles, como fechas, frecuencia y ubicaciones de observación, para generar predicciones útiles. Esto permitirá a los responsables de la conservación adaptar sus estrategias a los cambios en los patrones migratorios, mejorar la gestión de hábitats y proteger mejor a las especies migratorias.
Descripción del conjunto de datos utilizados¶
Como fuente de datos para realizar este proyecto utilizamos el dataset de eBird publicado por el Sistema Global de Información sobre Biodiversidad (GBIF, 2024). Delimitamos el conjunto de datos para trabajar con los avistamientos registrados en Costa Rica, como ubicación geográfica, durante los meses de Julio, Agosto y Septiembre, desde el año 2009 al 2023, como espacio temporal. Además, seleccionamos aleatoriamente un grupo de 20 especies migratorias que listamos en la Tabla 1:
Nombre Científico | Familia | Observaciones | |
---|---|---|---|
1 | Archilochus colubris | Trochilidae | |
2 | Cardellina pusilla | Parulidae | |
3 | Empidonax flaviventris | Tiranidae | |
4 | Empidonax traillii | Tiranidae | |
5 | Empidonax virescens | Tiranidae | |
6 | Geothlypis formosa | Parulidae | |
7 | Geothlypis philadelphia | Parulidae | |
8 | Mniotilta varia | Parulidae | |
9 | Piranga rubra | Cardinalidae | |
10 | Protonotaria citrea | Parulidae | |
11 | Setophaga coronata | Parulidae | |
12 | Setophaga magnolia | Parulidae | |
13 | Setophaga pensylvanica | Parulidae | |
14 | Setophaga petechia | Parulidae | |
15 | Setophaga ruticilla | Parulidae | |
16 | Setophaga tigrina | Parulidae | Infrecuente |
17 | Setophaga virens | Parulidae | Es ave de paso |
18 | Tyrannus tyrannus | Tiranidae | Es ave de paso |
19 | Vireo flavifrons | Vireonidae | |
20 | Vireo olivaceus | Vireonidae | Es ave de paso |
Tabla 1 - Listado de especies a analizar.
Los parámetros utilizados para obtener el dataset se muestran en la Figura 1. (Dataset, 2024)
Figura 1 - Parámetros para delimitación del Dataset.
La delimitación del dataset permite elaborar y probar el modelo con un conjunto de datos reducido. El modelo, sin embargo, es totalmente escalable para usarse con otras ubicaciones geográficas, rangos de fecha o especies, siempre y cuando se obtenga el dataset adecuado.
El dataset cuenta con 50 variables que se describen brevemente en la Tabla 2. Las variables utilizan el estándar Simple Darwin Core (TDWG, 2023) y una descripción detallada puede encontrarse en el sitio Web oficial: https://dwc.tdwg.org/list/. De estas variables seleccionamos diez, destacadas en la siguiente tabla. Aunque no todas las variables se utilizarán en el modelo, consideramos importantes contar con ellas para posibles ampliaciones del proyecto.
Id | Nombre | Tipo | Descripción | Modelo |
---|---|---|---|---|
1 | gbifID | int64 | ID Interno | No |
2 | datasetKey | object | Key Interno del Dataset | No |
3 | occurrenceID | object | ID de la ocurrencia | No |
4 | kingdom | object | Reino | No |
5 | phylum | object | Nombre científico completo del filo | No |
6 | class | object | Clase | No |
7 | order | object | Orden | No |
8 | family | object | Familia | No |
9 | genus | object | Género | No |
10 | species | object | Especie | No |
11 | infraspecificEpithet | float64 | Nombre el epíteto terminal. | No |
12 | taxonRank | object | El rango taxonómico del nombre más específico en el nombre científico. | No |
13 | scientificName | object | El nombre científico completo, con información de autoría y fecha si se conoce. | No |
14 | verbatimScientificName | object | Nombre científico | Si |
15 | verbatimScientificNameAuthorship | float64 | Autor / Deprecado? | No |
16 | countryCode | object | Código del País | Si |
17 | locality | object | Localidad dentro del país | No |
18 | stateProvince | object | Estado o provincial (en caso de que se deseara predecir para una ubicación geográfica más pequeña) | Si |
19 | occurrenceStatus | object | Presente / Ausente | No |
20 | individualCount | float64 | Cantidad de Individuos | Si |
21 | publishingOrgKey | object | N/A | No |
22 | decimalLatitude | float64 | Latitud donde ocurrió la observación | Si |
23 | decimalLongitude | float64 | Longitud donde ocurrió la observación | Si |
24 | coordinateUncertaintyInMeters | float64 | La distancia horizontal (en metros) desde la Latitud y Longitud que describen el círculo más pequeño que contiene el registro. | No |
25 | coordinatePrecision | float64 | Una representación decimal de la precisión de las coordenadas dadas en Latitud y Longitud | No |
26 | elevation | float64 | Elevación | No |
27 | elevationAccuracy | float64 | Exactitud de la elevación | No |
28 | depth | float64 | Profundidad | No |
29 | depthAccuracy | float64 | Exactitud de la profundidad | No |
30 | eventDate | object | Fecha en formato: YYYY-MM-DD | Si |
31 | day | int64 | Día (del 1 a 31) que se realizó la observación | Si |
32 | month | int64 | Mes (del 1 a 12) en que se realizó la observación | Si |
33 | year | int64 | Año en que se realizó la observación | Si |
34 | taxonKey | int64 | N/A | No |
35 | speciesKey | int64 | N/A | No |
36 | basisOfRecord | object | HUMAN_OBSERVATION / Todos los registros | No |
37 | institutionCode | object | Código de la institución | No |
38 | collectionCode | object | De qué colección proviene el registro (Ebird, Ebird Centromérica) | No |
39 | catalogNumber | object | Un identificador (preferiblemente único) para el registro dentro del conjunto o colección de datos. | No |
40 | recordNumber | float64 | Un identificador dado a la Ocurrencia en el momento en que se registró. | No |
41 | identifiedBy | float64 | Una lista (concatenada y separada) de nombres de personas, grupos u organizaciones que asignaron el Taxón al sujeto. | No |
42 | dateIdentified | float64 | La fecha en la que se determinó que el sujeto representaba al Taxón. | No |
43 | license | object | Código de la licencia de uso del registro | No |
44 | rightsHolder | float64 | Una persona u organización que posee o gestiona derechos sobre el recurso. | No |
45 | recordedBy | object | Una lista (concatenada y separada) de nombres de personas, grupos u organizaciones responsables de registrar la ocurrencia original. | No |
46 | typeStatus | float64 | Un tipo nomenclatural (estado de tipo, nombre científico tipificado, publicación) aplicado al tema. | No |
47 | establishmentMeans | float64 | Declaración sobre si un organismo ha sido introducido en un lugar y tiempo determinados a través de la actividad directa o indirecta de los humanos modernos. | No |
48 | lastInterpreted | object | N/A | No |
49 | mediaType | float64 | N/A | No |
50 | issue | object | N/A | No |
Tabla 2 – Variables del Dataset.
Análisis exploratorio y visualización de datos¶
El dataset obtenido tiene cerca de 380MB de datos y 35,041 registros de observaciones para el rango de años y meses seleccionados, que corresponden con los meses de arribo y/o paso de aves migratorias en Costa Rica. Para afectos del modelo, delimitamos la cantidad de variables a considerar, quedando las siguientes: ['verbatimScientificName', 'year', 'month', 'day', 'individualCount']. Renombramos ‘verbatimScientificName' a ‘species’ y 'individualCount' como ‘count’:
<class 'pandas.core.frame.DataFrame'>
Index: 35041 entries, 29 to 728533
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 species 35041 non-null object
1 count 34338 non-null float64
2 day 35041 non-null int64
3 month 35041 non-null int64
4 year 35041 non-null int64
dtypes: float64(1), int64(3), object(1)
memory usage: 1.6+ MB
Utilizamos este subconjunto de datos para predecir si una especie estará presente en una fecha determinada, dentro de los meses de Julio, Agosto y Septiembre. La variable conteo (count) de especies es un dato importante para predecir, por ejemplo, la cantidad de individuos que podrían observarse, sin embargo, el objetivo del proyecto es predecir la presencia o no de la especie. Para esto, más que la cantidad de individuos nos interesa la cantidad de observaciones realizadas para la especie por día, mes y año. Los valores nulos de la variable representan avistamientos donde la cantidad de individuos no ha sido reportada, solamente su presencia. Para todos los casos, transformamos el valor en 1, lo que indica que la especie estaba presente en esa fecha.
Con base en lo anterior, agrupamos los datos por especie, para contar cuántes veces ha sido reportada en el pasado por día mes y año. La información está distribuida de la siguiente forma:
Id - Especie Registros
01 - Archilochus colubris.....................60
02 - Cardellina pusilla.....................1816
03 - Empidonax flaviventris.................1950
04 - Empidonax traillii......................534
05 - Empidonax virescens.....................216
06 - Geothlypis formosa......................190
07 - Geothlypis philadelphia.................583
08 - Mniotilta varia........................6253
09 - Piranga rubra...........................845
10 - Protonotaria citrea....................1299
11 - Setophaga coronata........................5
12 - Setophaga magnolia.......................19
13 - Setophaga pensylvanica.................1754
14 - Setophaga petechia....................10356
15 - Setophaga ruticilla....................1788
16 - Setophaga tigrina.........................6
17 - Setophaga virens........................176
18 - Tyrannus tyrannus......................1037
19 - Vireo flavifrons........................183
20 - Vireo olivaceus........................5971
Nuestra variable objetivo es “count”, es decir, partiendo de la especie y su historia de observaciones para las fechas comprendidas en el trimestre de Julio, Agosto y Septiembre, el modelo deberá predecir si la especie estará presente o no en una fecha futura para esos mismos meses.
Un aspecto importante que detectamos en la exploración de datos es que, para todas las especies, observamos pocos registros para los años más antiguos, como se puede apreciar en la Figura 2. Creemos que esto podría crear una desviación o imprecisión al entrenar el modelo de predicción. Este comportamiento de los datos obedece a diversos factores: sub-registro, mayor cantidad de observadores y más recientemente, la disponibilidad del portal eBird y aplicaciones móviles que facilitan el registro, entre otros.
Figura 2 – Cantidad de observaciones para Setophaga petechia.
Implementación del Modelo de Predicción¶
Para desarrollar el modelo de aprendizaje automático que permita predecir la presencia de una especie migratoria para una fecha determinada, proponemos un enfoque de aprendizaje supervisado abordado como un problema de clasificación, ya que el resultado esperado es un valor discreto, es decir, si la especie estará presente (1) o no (0) para la fecha seleccionada. Esto implica que el modelo debe aprender a identificar patrones y correlaciones entre los avistamientos y las fechas correspondientes para predecir nuevas observaciones.
De los modelos de clasificación supervisados seleccionamos Decision Tree Classifier y Random Forest Classifier. Para predecir la presencia de aves migratorias, el Decision Tree Classifier es útil porque puede identificar y visualizar patrones de decisiones basados en características como el año, el mes y el día, facilitando la comprensión de cómo estas variables afectan la migración. Por su lado, Random Forest Classifier, al combinar múltiples árboles de decisión, ofrece una mayor precisión y robustez al manejar la variabilidad y el ruido en los datos, lo que mejora la capacidad del modelo para generalizar sobre diferentes períodos de migración. Ambos modelos permiten capturar la complejidad de los patrones de migración, ayudando a prever eventos de presencia con mayor fiabilidad.
El proceso de implementación de estos modelos consideró varios pasos: primero, la preparación y limpieza de los datos y el manejo de los valores faltantes (nulos). Luego la identificación y selección de las variables independientes y la variable objetivo. Posteriormente la proyección del dataset para entrenamiento y análisis por especie, por medio de iteraciones sobre el mismo. El siguiente paso fue entrenar los modelos utilizando los algoritmos de clasificación seleccionados para aprender a partir de los datos históricos. Finalmente se evaluaron los resultados con cada especie mediante técnicas de validación cruzada y métricas de rendimiento como la precisión, el recall y F1-score para asegurar que los modelos generalizan bien y ofrece predicciones confiables.
Resultados¶
Luego de entrenar los modelos de aprendizaje, hicimos varios ejercicios con diferentes fechas, incluso meses completos obteniendo resultados interesantes. A continuación presentamos el resultado de la ejecución de los modelos Decision Tree Classifier (DTC) y Random Forest Classifier (RFC) para las fechas 21 y 30 de Julio, Agosto y Septiembre respectivamente, para cada especie. Las columnas %Acc representan el score de predicción del modelo con respecto a los datos suministrados y el resultado obtenido. Para simplificar, hemos puesto la palabra “si” si se anticipa que la especie estará presente para esa fecha. Este ejercicio utilizó, para ambos algoritmos, un 20% de los datos para efectos de entrenamiento. Realizamos el mismo ejercicio usando el 30% de datos y, aunque el resultado de la predicción fue exactamente igual, los porcentajes de exactitud (accuracy) mejoraron un poco al pasar de 20 a 30%.
Especie Fecha %Acc.DTC Presente %Acc. RFC Presente
Archilochus colubris 21/07/2024 93.53% - 94.60% -
30/07/2024 93.53% - 94.60% -
21/08/2024 93.53% - 94.60% -
30/08/2024 93.53% - 94.60% -
21/09/2024 93.53% - 94.60% -
30/09/2024 93.53% - 94.60% -
Cardellina pusilla 21/07/2024 96.59% - 96.93% -
30/07/2024 96.59% - 96.93% -
21/08/2024 96.59% - 96.93% -
30/08/2024 96.59% - 96.93% -
21/09/2024 96.59% sí 96.93% sí
30/09/2024 96.59% sí 96.93% sí
Empidonax flaviventris 21/07/2024 95.32% - 96.49% -
30/07/2024 95.32% sí 96.49% sí
21/08/2024 95.32% - 96.49% -
30/08/2024 95.32% sí 96.49% sí
21/09/2024 95.32% sí 96.49% sí
30/09/2024 95.32% sí 96.49% sí
Empidonax traillii 21/07/2024 92.22% - 93.08% -
30/07/2024 92.22% - 93.08% -
21/08/2024 92.22% sí 93.08% sí
30/08/2024 92.22% sí 93.08% sí
21/09/2024 92.22% sí 93.08% sí
30/09/2024 92.22% - 93.08% -
Empidonax virescens 21/07/2024 94.74% - 96.05% -
30/07/2024 94.74% - 96.05% -
21/08/2024 94.74% - 96.05% -
30/08/2024 94.74% - 96.05% -
21/09/2024 94.74% - 96.05% -
30/09/2024 94.74% sí 96.05% sí
Geothlypis formosa 21/07/2024 92.86% - 94.22% -
30/07/2024 92.86% - 94.22% -
21/08/2024 92.86% - 94.22% -
30/08/2024 92.86% - 94.22% -
21/09/2024 92.86% - 94.22% -
30/09/2024 92.86% - 94.22% sí
Geothlypis philadelphia 21/07/2024 94.20% - 94.48% -
30/07/2024 94.20% - 94.48% -
21/08/2024 94.20% - 94.48% -
30/08/2024 94.20% - 94.48% -
21/09/2024 94.20% sí 94.48% sí
30/09/2024 94.20% sí 94.48% sí
Mniotilta varia 21/07/2024 97.60% - 98.10% -
30/07/2024 97.60% - 98.10% -
21/08/2024 97.60% sí 98.10% sí
30/08/2024 97.60% sí 98.10% sí
21/09/2024 97.60% sí 98.10% sí
30/09/2024 97.60% sí 98.10% sí
Piranga rubra 21/07/2024 94.66% - 96.36% -
30/07/2024 94.66% - 96.36% -
21/08/2024 94.66% - 96.36% -
30/08/2024 94.66% - 96.36% -
21/09/2024 94.66% sí 96.36% sí
30/09/2024 94.66% sí 96.36% sí
Protonotaria citrea 21/07/2024 91.49% - 92.98% -
30/07/2024 91.49% - 92.98% -
21/08/2024 91.49% sí 92.98% sí
30/08/2024 91.49% sí 92.98% sí
21/09/2024 91.49% sí 92.98% sí
30/09/2024 91.49% sí 92.98% sí
Setophaga coronata 21/07/2024 99.64% - 99.64% -
30/07/2024 99.64% - 99.64% -
21/08/2024 99.64% - 99.64% -
30/08/2024 99.64% - 99.64% -
21/09/2024 99.64% - 99.64% -
30/09/2024 99.64% - 99.64% -
Setophaga magnolia 21/07/2024 98.19% - 98.56% -
30/07/2024 98.19% - 98.56% -
21/08/2024 98.19% - 98.56% -
30/08/2024 98.19% - 98.56% -
21/09/2024 98.19% - 98.56% -
30/09/2024 98.19% - 98.56% -
Setophaga pensylvanica 21/07/2024 95.69% - 96.38% -
30/07/2024 95.69% - 96.38% -
21/08/2024 95.69% - 96.38% -
30/08/2024 95.69% sí 96.38% sí
21/09/2024 95.69% sí 96.38% sí
30/09/2024 95.69% sí 96.38% sí
Setophaga petechia 21/07/2024 96.83% - 96.88% sí
30/07/2024 96.83% sí 96.88% sí
21/08/2024 96.83% sí 96.88% sí
30/08/2024 96.83% sí 96.88% sí
21/09/2024 96.83% sí 96.88% sí
30/09/2024 96.83% sí 96.88% sí
Setophaga ruticilla 21/07/2024 92.01% - 93.10% -
30/07/2024 92.01% - 93.10% -
21/08/2024 92.01% sí 93.10% sí
30/08/2024 92.01% sí 93.10% sí
21/09/2024 92.01% sí 93.10% sí
30/09/2024 92.01% sí 93.10% sí
Setophaga tigrina 21/07/2024 100.00% - 100.00% -
30/07/2024 100.00% - 100.00% -
21/08/2024 100.00% - 100.00% -
30/08/2024 100.00% - 100.00% -
21/09/2024 100.00% - 100.00% -
30/09/2024 100.00% - 100.00% -
Setophaga virens 21/07/2024 96.66% - 96.66% -
30/07/2024 96.66% - 96.66% -
21/08/2024 96.66% - 96.66% -
30/08/2024 96.66% - 96.66% -
21/09/2024 96.66% sí 96.66% sí
30/09/2024 96.66% sí 96.66% sí
Tyrannus tyrannus 21/07/2024 94.31% - 95.44% -
30/07/2024 94.31% - 95.44% -
21/08/2024 94.31% - 95.44% -
30/08/2024 94.31% - 95.44% -
21/09/2024 94.31% sí 95.44% sí
30/09/2024 94.31% sí 95.44% sí
Vireo flavifrons 21/07/2024 95.59% - 95.25% -
30/07/2024 95.59% - 95.25% -
21/08/2024 95.59% - 95.25% -
30/08/2024 95.59% - 95.25% -
21/09/2024 95.59% - 95.25% -
30/09/2024 95.59% - 95.25% -
Vireo olivaceus 21/07/2024 97.74% - 98.10% -
30/07/2024 97.74% - 98.10% -
21/08/2024 97.74% sí 98.10% sí
30/08/2024 97.74% sí 98.10% sí
21/09/2024 97.74% sí 98.10% sí
30/09/2024 97.74% sí 98.10% sí
Aunque para la gran mayoría de las fechas ambos modelos coinciden con la predicción, detectamos algunos casos donde difieren, lo que podría deberse al algoritmo de clasificación empleado, el tamaño de la muestra y los conjuntos de entrenamiento, así como la forma en que el algoritmo trabaja con la dispersión o ausencia de datos.
Para probar la efectividad de los modelos no basta con validar si la especie fue reportada o no en eBird para estas fechas, ya que la predicción no pretende saber si será reportada o no, sino si estará o no presente en la región geográfica seleccionada para esas fechas. Lo anterior implica que la validación del modelo posiblemente requiera salir a observar en las fechas donde se pronostica la presencia de la especie. Esto representa una limitante debido a que el área geográfica es enorme, por lo que una mejora al modelo, en este caso, sería tratar de predecir con mayor detalle la ubicación geográfica donde se anticipa que la especie podría estar presente, considerando dónde ha sido reportada anteriormente.
Conclusiones¶
A partir de análisis del proyecto concluimos que:
Los algoritmos de aprendizaje automático pueden ser de utilidad para predecir si una especie de ave migratoria puede o no estar presente en un país determinado, teniendo como datos de entrenamientos registros de avistamientos históricos.
La predicción está condicionada a la riqueza de los datos que sean utilizados para entrenar los modelos.
Para el conjunto de datos utilizados el modelo de aprendizaje automático Random Forest Classifier resultó ser más preciso.
Trabajos futuros¶
El dataset con el que hemos trabajado incluye otras variables que podrían ser de interés para ampliar y mejorar el modelo de predicción. Por ejemplo, las coordenadas geográficas de cada observación (decimalLatitude y decimalLongitude). Estas podrían ser usadas para predecir posibles lugares de avistamiento, en combinación con las fechas. Otra variable es stateProvince, que contiene información sobre la provincia donde se realizó la observación, lo que podría usarse para delimitar mejor la región geográfica. Adicionalmente, la variable relacionda con la altura (elevation) que podría usarse para predecir los avistamientos asociados con la altitud de un lugar.
También se puede considerar la combinación de este dataset con otros dataset que permitan crear modelos más complejos y que incluyan variables del clima (temperatura, precipitación, vientos), los puntos de calor (quemas), proximidad con poblaciones urbanas, áreas de cultivo.
Referencias¶
Dataset, G. (21 de Agosto de 2024). Fonte: Global Biodiversity Information Facility: https://doi.org/10.15468/dl.pdqqdz
Finch, D. &. (1992). Status and Management of Neotropical Migratory Birds. The Journal of Wildlife Management.
Fuentes, M. &. (2023). BirdFlow: Learning seasonal bird movements from eBird data. Methods in Ecology and Evolution. 14. 10.1111/2041-210X.14052. , 923-938.
GBIF. (29 de Agosto de 2024). GBIF Occurrence - eBird Dataset. Fonte: GBIF.org: https://www.gbif.org/occurrence/search?dataset\_key=4fa7b334-ce0d-4e88-aaae-2e0c138d049e
McKinnon, E. &. (2018). Ten years tracking the migrations of small landbirds: Lessons learned in the golden age of bio-logging. The Auk. Vol 135 10.1642/AUK-17-202.1., 834-856.
Román, V. (14 de Octubre de 2023). El cambio climático está alterando a las aves migratorias de América Latina. Fonte: Infobae: https://www.infobae.com/america/medio-ambiente/2023/10/14/el-cambio-climatico-esta-alterando-a-las-aves-migratorias-de-america-latina/
Sánchez, J. E. (2009). BirdLife International (BirdLife Conservation Series No. 16). Em Important Bird Areas Americas - Priority sites for biodiversity conservation. Quito, Ecuador.
TDWG. (13 de September de 2023). Simple Darwin Core. Fonte: Darwin Core: https://dwc.tdwg.org/simple/
# Redbioma
# Curso Aprendizaje Automático aplicado a datos de Biodiversidad
# Proyecto: Modelo para predicción de llegada de especies migratorias
# José Abelardo Sánchez Cardoza – jabelardo.sc@gmail.com
# Cynthia María Tercero Rojas – cmtercero@gmail.com
#
# DataSet
# Se ha extraido un subconjunto de registros de 20 especies migratorias entre
# los meses de julio, agosto y septiembre. La región geográfica es Costa Rica.
# El dataset tiene registros históricos de 15 años (2009 a 2023)
# El dataset se encuentra en el archivo /content/0076714-240626123714530.csv
#
# GBIF.org (21 August 2024) GBIF Occurrence Download https://doi.org/10.15468/dl.pdqqdz
#
Librerías del proyecto y definición de variables¶
En la siguiente sección se importan las librerías que serán utlizadas en el proyecto
# Importamos las librerías a utilizar en el proyecto
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report
from sklearn.exceptions import UndefinedMetricWarning
from rich.console import Console
from rich.text import Text
import warnings
# Definición de variables generales que usaremos en el proyecto.
# Los datos analizados serán para un rango de años entre el 2009 y 2023 inclusive.
# entre las fechas del 01-Jul al 30-Sep de cada año.
years = np.arange(2009, 2024).tolist() # Genera el rango de años
months = [7, 8, 9] # Genera los meses de junio, julio y agosto
days = np.arange(1, 32) # Genera los días del 1 al 31 (incluye meses que no tienen 31 días)
# Carga y procesamiento de archivo
# Archivo CSV de entrada, separado por tabs
file = '/content/0076714-240626123714530.csv'
# Trabajaremos con las variables: Especie, Año, Mes, Día y conteo
cols = ['verbatimScientificName', 'year', 'month', 'day', 'individualCount']
# Leemos el archivo
tmpdf = pd.read_csv(file, delimiter='\t', usecols=cols)
# Extraemos la información para los años y los meses seleccionados
dfsrc = tmpdf[tmpdf['year'].isin(years) & tmpdf['month'].isin(months)]
dfsrc = dfsrc.rename(columns={'individualCount': 'count'})
dfsrc = dfsrc.rename(columns={'verbatimScientificName': 'species'})
Análisis Exploratorio de Datos¶
Exploramos el dataframe. Se identifican cierta cantidad de registros null en individualCount. Para estos casos se pondrá el valor de 0 (no observado)
Reemplazo de valores nulos
Agrupación de avistamientos
# Exploramos el dataframe. Se identifican cierta cantidad de registros null
# en individualCount. Para estos casos se pondrá el valor de 0 (no observado)
dfsrc.info()
<class 'pandas.core.frame.DataFrame'> Index: 35041 entries, 29 to 728533 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 species 35041 non-null object 1 count 34338 non-null float64 2 day 35041 non-null int64 3 month 35041 non-null int64 4 year 35041 non-null int64 dtypes: float64(1), int64(3), object(1) memory usage: 1.6+ MB
# Reemplazamos valores nulos por 0. Dado que solo una columna tiene valores nulos
# aplicamos el reemplazo indistintamente.
dfsrc = dfsrc.fillna(1) # Los valores null en 1, dado que estos reportes solo indican presencia, no cantidad
dfsrc.info()
<class 'pandas.core.frame.DataFrame'> Index: 35041 entries, 29 to 728533 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 species 35041 non-null object 1 count 35041 non-null float64 2 day 35041 non-null int64 3 month 35041 non-null int64 4 year 35041 non-null int64 dtypes: float64(1), int64(3), object(1) memory usage: 1.6+ MB
# Agrupamos los avistamientos por especie, año, mes y día, contando el número de avistamientos
# por especie. Nota, en un avistamiento pueden haber muchos individuos. Se ignora el número de
# individuos porque crea desviación.
dfflt = dfsrc
dfflt['count'] = 1
#dfsrc.groupby(['species','year', 'month', 'day'], as_index=False)['count'].count()
dfflt = dfflt.sort_values(by='species')
dfflt.info()
<class 'pandas.core.frame.DataFrame'> Index: 35041 entries, 568867 to 585558 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 species 35041 non-null object 1 count 35041 non-null int64 2 day 35041 non-null int64 3 month 35041 non-null int64 4 year 35041 non-null int64 dtypes: int64(4), object(1) memory usage: 1.6+ MB
allspecies = dfflt['species'].unique()
print(allspecies)
['Archilochus colubris' 'Cardellina pusilla' 'Empidonax flaviventris' 'Empidonax traillii' 'Empidonax virescens' 'Geothlypis formosa' 'Geothlypis philadelphia' 'Mniotilta varia' 'Piranga rubra' 'Protonotaria citrea' 'Setophaga coronata' 'Setophaga magnolia' 'Setophaga pensylvanica' 'Setophaga petechia' 'Setophaga ruticilla' 'Setophaga tigrina' 'Setophaga virens' 'Tyrannus tyrannus' 'Vireo flavifrons' 'Vireo olivaceus']
# Revisamos la cantidad de registro por especie
cantidad_por_especie = dfflt.groupby('species').size().reset_index(name='count')
c = 0
print("Id - Especie Registros")
for index, row in cantidad_por_especie.iterrows():
c = c +row['count']
print(f"{index+1:02d} - {row['species'].ljust(38,'.')}{str(row['count']).rjust(5,'.')}")
Id - Especie Registros 01 - Archilochus colubris.....................60 02 - Cardellina pusilla.....................1816 03 - Empidonax flaviventris.................1950 04 - Empidonax traillii......................534 05 - Empidonax virescens.....................216 06 - Geothlypis formosa......................190 07 - Geothlypis philadelphia.................583 08 - Mniotilta varia........................6253 09 - Piranga rubra...........................845 10 - Protonotaria citrea....................1299 11 - Setophaga coronata........................5 12 - Setophaga magnolia.......................19 13 - Setophaga pensylvanica.................1754 14 - Setophaga petechia....................10356 15 - Setophaga ruticilla....................1788 16 - Setophaga tigrina.........................6 17 - Setophaga virens........................176 18 - Tyrannus tyrannus......................1037 19 - Vireo flavifrons........................183 20 - Vireo olivaceus........................5971
# Crea una lista para almacenar las filas de la matriz. Estará conformada por las
# columnas: 'year', 'month', 'day', 'count' por ejemplo:
# 2009, 7, 10, 0
# 2009, 8, 11, 0
# 2010, 9, 23, 0
# 2015, 8, 14, 0
# Esta matriz será poblada con la suma del conteo de observaciones de cada especie.
# Con esto crearemos un dataframe de trabajo.
emptydf = []
for year in years:
for month in months:
for day in days:
# Solo agregar días válidos para cada mes
if month == 7 and day > 31:
continue # Junio tiene 30 días
elif month == 8 and day > 31:
continue # Agosto tiene 31 días
elif month == 9 and day > 30:
continue # Julio tiene 31 días
emptydf.append([year, month, day, 0])
# Como parte de la exploración de datos, graficamos la cantidad de observaciones
# por especie y año
for species in allspecies:
# Creamos un dataframe por especie usando la lista creada en el paso anterior
df = pd.DataFrame(emptydf, columns=["year", "month", "day", "count"])
# Obtenemos un dataframe al filtrar el conjunto de datos por la especie
dfspe = dfflt[dfflt['species'] == species]
# Hacemos merge del dataframe vacio (df) y el dataframe de la especie (dfspe)
df_tmp = pd.merge(df, dfspe, on=['year', 'month', 'day'], how='left', suffixes=('_target', '_source'))
df_tmp['count_target'] = df_tmp['count_source'].fillna(df_tmp['count_target'])
df_tmp = df_tmp.rename(columns={'count_target': 'count'})
df = df_tmp[['year', 'month', 'day', 'count']]
# Convierte la lista en un DataFrame de pandas
dfplt = df.groupby(['year', 'month'], as_index=False)['count'].sum()
# Grafico de Barra por especie
# Mapea los números de los meses a sus nombres
dfplt['month'] = dfplt['month'].map({7: 'Julio', 8: 'Agosto', 9: 'Septiembre'})
# Grafica la cantidad de observaciones por año, mes y especie
sns.set(style="whitegrid")
plt.figure(figsize=(10, 5))
ax = sns.barplot(x='year', y='count', hue='month', data=dfplt)
for p in ax.patches:
ax.annotate(f'{int(p.get_height())}', # Convertir la altura en entero
(p.get_x() + p.get_width() / 2., p.get_height()),
ha='center', va='center', fontsize=6, color='black', xytext=(0, 5),
textcoords='offset points')
# Personalizar la gráfica
plt.title('Cantidad de Observaciones por Mes y Año para la especie ' + species)
plt.xlabel('Año')
plt.ylabel('Cantidad de Observaciones')
plt.legend(title='Mes')
plt.xticks(rotation=45) # Rotar las etiquetas del eje X si es necesario para mayor claridad
# Mostrar la gráfica
plt.show()
Implementación del Modelo: Decision Tree Classifier¶
En esta sección se implementa el primer modelo predictivo seleccionado
# Iteramos sobre todas las especies para obtener un dataframe por especie que
# incluya la cantidad de veces que la especie fue reportada por día. Hay que
# hacer notar, que el dataframe actual incluye el conteo de todas las obsevaciones
# por día, pero no incluye fechas donde la especie no fue observada, por lo que
# debemos incluir esas fecha. Para esto crearmos un nuevo dataframe por especie.
def dtcModel( dates, verbose ):
# Resultado de la predicción para la fecha 'fec' con Decissión Tree Classifier
dtcresult = []
if verbose:
console = Console()
header_text = Text("\n\tMODELO DECISION TREE CLASSIFIER\n\n", style="bold underline")
console.print(header_text)
# Para todas las especies
for species in allspecies:
# Creamos un dataframe por especie usando la lista creada en el paso anterior
df = pd.DataFrame(emptydf, columns=["year", "month", "day", "count"])
# Obtenemos un dataframe al filtrar el conjunto de datos por la especie
dfspe = dfflt[dfflt['species'] == species]
# Hacemos merge del dataframe vacio (df) y el dataframe de la especie (dfspe)
df_tmp = pd.merge(df, dfspe, on=['year', 'month', 'day'], how='left', suffixes=('_target', '_source'))
df_tmp['count_target'] = df_tmp['count_source'].fillna(df_tmp['count_target'])
df_tmp = df_tmp.rename(columns={'count_target': 'count'})
df = df_tmp[['year', 'month', 'day', 'count']]
# ------------------------------- Modelo Predictivo-------------------------------
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=UndefinedMetricWarning)
if verbose:
print("Predicción para la especie:",species)
# Seleccionamos características (X) y la variable objetivo (y)
X = df[['year', 'month', 'day']]
y = df['count']
# Dividimos los datos en conjuntos de entrenamiento y prueba
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Entrenamos un modelo de árbol de decisión
model = DecisionTreeClassifier(random_state=42)
model.fit(X_train.values, y_train)
# Hacemos predicciones con el conjunto de prueba
y_pred = model.predict(X_test.values)
# Evaluamos el modelo
accuracy = accuracy_score(y_test, y_pred)
if verbose:
report = classification_report(y_test, y_pred)
print("------------------------------------------------------------------------------")
print(f"Accuracy: {accuracy:.2f}")
print("Classification Report:\n", report)
print("------------------------------------------------------------------------------")
# ------------------------------- Probamos el modelo -------------------------------
# Iteramos para todas las fechas
for fec in dates:
prediction = model.predict([fec])
if verbose:
print("Para la fecha", fec, "la especie:", species, f"{'si' if prediction[0] == 1 else 'no'}", "será vista.")
print("------------------------------------------------------------------------------\n"*2)
dtcresult.append([species, accuracy,prediction[0],fec])
return dtcresult
Implementación del Modelo: Random Forest Classifier¶
En esta sección se implementa el segundo modelo predictivo seleccionado
# Iteramos sobre todas las especies para obtener un dataframe por especie que
# incluya la cantidad de veces que la especie fue reportada por día. Hay que
# hacer notar, que el dataframe actual incluye el conteo de todas las obsevaciones
# por día, pero no incluye fechas donde la especie no fue observada, por lo que
# debemos incluir esas fecha. Para esto crearmos un nuevo dataframe por especie.
def rfcModel( dates, verbose ):
# Resultado de la predicción para la fecha 'fec' con Random Forest Classifier
rfcresult = []
if verbose:
console = Console()
header_text = Text("\n\tMODELO RANDOM FOREST CLASSIFIER\n\n", style="bold underline")
console.print(header_text)
for species in allspecies:
# Creamos un dataframe por especie usando la lista creada en el paso anterior
df = pd.DataFrame(emptydf, columns=["year", "month", "day", "count"])
# Obtenemos un dataframe al filtrar el conjunto de datos por la especie
dfspe = dfflt[dfflt['species'] == species]
# Hacemos merge del dataframe vacío (df) y el dataframe de la especie (dfspe)
df_tmp = pd.merge(df, dfspe, on=['year', 'month', 'day'], how='left', suffixes=('_target', '_source'))
df_tmp['count_target'] = df_tmp['count_source'].fillna(df_tmp['count_target'])
df_tmp = df_tmp.rename(columns={'count_target': 'count'})
df = df_tmp[['year', 'month', 'day', 'count']]
# ------------------------------- Modelo Predictivo-------------------------------
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=UndefinedMetricWarning)
if verbose:
print("Predicción para la especie:",species)
# Seleccionamos características (X) y la variable objetivo (y)
X = df[['year', 'month', 'day']]
y = df['count']
# Dividimos los datos en conjuntos de entrenamiento y prueba
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Entrenamos un modelo de Random Forest
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
# Hacemos predicciones con el conjunto de prueba
y_pred = model.predict(X_test)
# Evaluamos el modelo
accuracy = accuracy_score(y_test, y_pred)
if verbose:
report = classification_report(y_test, y_pred)
print("------------------------------------------------------------------------------")
print(f"Accuracy: {accuracy:.2f}")
print("Classification Report:\n", report)
print("------------------------------------------------------------------------------")
# ------------------------------- Probamos el modelo -------------------------------
# Convertir la fecha de predicción a un DataFrame con las mismas columnas que X_train
for fec in dates:
fec_df = pd.DataFrame([fec], columns=['year', 'month', 'day'])
prediction = model.predict(fec_df)
if verbose:
print("Para la fecha", fec, "la especie:", species, f"{'si' if prediction[0] == 1 else 'no'}", "será vista.")
print("------------------------------------------------------------------------------\n"*2)
rfcresult.append([species,accuracy,prediction[0],fec])
return rfcresult
# Resultados obtenidos por la ejecución de los modelos para predecir la
# presencia de las especies en una fecha determinada.
# Fechas en que se hará predicción
dates = []
#dates = [[2024, 7, 15], [2024, 7, 30], [2024, 8, 15], [2024, 8, 30], [2024, 9, 15], [2024, 9, 30]]
#dates = [[2024, 7, 15],[2024, 8, 15],[2024, 9, 15]]
dates = [[2024, 7, 21],[2024, 7, 30],[2024, 8, 21],[2024, 8, 30],[2024, 9, 21],[2024, 9, 30]]
# Crear una lista vacía para almacenar las fechas
# Generar las fechas del 1 al 31 de julio de 2024
#for i in range(1, 32):
# dates.append([2024, 7, i])
# Generar las fechas del 1 al 31 de agosto de 2024
#for i in range(1, 32):
# dates.append([2024, 8, i])
# Generar las fechas del 1 al 30 de septiembre de 2024
#for i in range(1, 31):
# dates.append([2024, 9, i])
# Definir el texto con formato
console = Console()
header_text = Text("\n\tRESULTADO DE LA PREDICCIÓN\n\n", style="bold underline")
console.print(header_text)
# Determinar el ancho de las columnas
spc_width = 25 # Ancho para la columna de especie
val_width = 10 # Ancho para las columnas de valores
dtcresult = dtcModel( dates, False )
rfcresult = rfcModel( dates, False )
# Encabezado
print(f"{'Especie':<{spc_width}} {'Fecha':<{val_width}} {'%Acc. DTC':>{val_width}} {'Presente':>{val_width}} {'%Acc. RFC':>{val_width}} {'Presente':>{val_width}}")
esp = None
for item1, item2 in zip(dtcresult, rfcresult):
spc = item1[0]
if spc != esp:
esp = spc
else:
spc = ""
fec = f"{item1[3][2]:02d}/{item1[3][1]:02d}/{item1[3][0]}"
scr1 = f"{item1[1] * 100:.2f}%"
prd1 = "sí" if item1[2] == 1 else "-"
scr2 = f"{item2[1] * 100:.2f}%"
prd2 = "sí" if item2[2] == 1 else "-"
print(f"{spc:<{spc_width}} {fec:<{val_width}} {scr1:>{val_width}} {prd1:>{val_width}} {scr2:>{val_width}} {prd2:>{val_width}}")
RESULTADO DE LA PREDICCIÓN
Especie Fecha %Acc. DTC Presente %Acc. RFC Presente Archilochus colubris 01/07/2024 93.53% - 94.60% - 02/07/2024 93.53% - 94.60% - 03/07/2024 93.53% - 94.60% - 04/07/2024 93.53% - 94.60% - 05/07/2024 93.53% - 94.60% - 06/07/2024 93.53% - 94.60% - 07/07/2024 93.53% - 94.60% - 08/07/2024 93.53% - 94.60% - 09/07/2024 93.53% - 94.60% - 10/07/2024 93.53% - 94.60% - 11/07/2024 93.53% - 94.60% - 12/07/2024 93.53% - 94.60% - 13/07/2024 93.53% - 94.60% - 14/07/2024 93.53% - 94.60% - 15/07/2024 93.53% - 94.60% - 16/07/2024 93.53% - 94.60% - 17/07/2024 93.53% - 94.60% - 18/07/2024 93.53% - 94.60% - 19/07/2024 93.53% - 94.60% - 20/07/2024 93.53% - 94.60% - 21/07/2024 93.53% - 94.60% - 22/07/2024 93.53% - 94.60% - 23/07/2024 93.53% - 94.60% - 24/07/2024 93.53% - 94.60% - 25/07/2024 93.53% - 94.60% - 26/07/2024 93.53% - 94.60% - 27/07/2024 93.53% - 94.60% - 28/07/2024 93.53% - 94.60% - 29/07/2024 93.53% - 94.60% - 30/07/2024 93.53% - 94.60% - 31/07/2024 93.53% - 94.60% - Cardellina pusilla 01/07/2024 96.59% - 96.93% - 02/07/2024 96.59% - 96.93% - 03/07/2024 96.59% - 96.93% - 04/07/2024 96.59% - 96.93% - 05/07/2024 96.59% - 96.93% - 06/07/2024 96.59% - 96.93% - 07/07/2024 96.59% - 96.93% - 08/07/2024 96.59% - 96.93% - 09/07/2024 96.59% - 96.93% - 10/07/2024 96.59% - 96.93% - 11/07/2024 96.59% - 96.93% - 12/07/2024 96.59% - 96.93% - 13/07/2024 96.59% - 96.93% - 14/07/2024 96.59% - 96.93% - 15/07/2024 96.59% - 96.93% - 16/07/2024 96.59% - 96.93% - 17/07/2024 96.59% - 96.93% - 18/07/2024 96.59% - 96.93% - 19/07/2024 96.59% - 96.93% - 20/07/2024 96.59% - 96.93% - 21/07/2024 96.59% - 96.93% - 22/07/2024 96.59% - 96.93% - 23/07/2024 96.59% - 96.93% - 24/07/2024 96.59% - 96.93% - 25/07/2024 96.59% - 96.93% - 26/07/2024 96.59% - 96.93% - 27/07/2024 96.59% - 96.93% - 28/07/2024 96.59% - 96.93% - 29/07/2024 96.59% - 96.93% - 30/07/2024 96.59% - 96.93% - 31/07/2024 96.59% - 96.93% - Empidonax flaviventris 01/07/2024 95.32% - 96.49% - 02/07/2024 95.32% - 96.49% - 03/07/2024 95.32% - 96.49% - 04/07/2024 95.32% - 96.49% - 05/07/2024 95.32% - 96.49% - 06/07/2024 95.32% - 96.49% - 07/07/2024 95.32% - 96.49% - 08/07/2024 95.32% - 96.49% - 09/07/2024 95.32% - 96.49% - 10/07/2024 95.32% - 96.49% - 11/07/2024 95.32% - 96.49% - 12/07/2024 95.32% - 96.49% - 13/07/2024 95.32% - 96.49% - 14/07/2024 95.32% - 96.49% - 15/07/2024 95.32% - 96.49% - 16/07/2024 95.32% - 96.49% - 17/07/2024 95.32% - 96.49% - 18/07/2024 95.32% - 96.49% - 19/07/2024 95.32% - 96.49% - 20/07/2024 95.32% - 96.49% - 21/07/2024 95.32% - 96.49% - 22/07/2024 95.32% - 96.49% - 23/07/2024 95.32% - 96.49% - 24/07/2024 95.32% - 96.49% - 25/07/2024 95.32% - 96.49% - 26/07/2024 95.32% - 96.49% - 27/07/2024 95.32% - 96.49% - 28/07/2024 95.32% - 96.49% - 29/07/2024 95.32% - 96.49% - 30/07/2024 95.32% sí 96.49% sí 31/07/2024 95.32% sí 96.49% - Empidonax traillii 01/07/2024 92.22% - 93.08% - 02/07/2024 92.22% - 93.08% - 03/07/2024 92.22% - 93.08% - 04/07/2024 92.22% - 93.08% - 05/07/2024 92.22% - 93.08% - 06/07/2024 92.22% - 93.08% - 07/07/2024 92.22% - 93.08% - 08/07/2024 92.22% - 93.08% - 09/07/2024 92.22% - 93.08% - 10/07/2024 92.22% - 93.08% - 11/07/2024 92.22% - 93.08% - 12/07/2024 92.22% - 93.08% - 13/07/2024 92.22% - 93.08% - 14/07/2024 92.22% - 93.08% - 15/07/2024 92.22% - 93.08% - 16/07/2024 92.22% - 93.08% - 17/07/2024 92.22% - 93.08% - 18/07/2024 92.22% - 93.08% - 19/07/2024 92.22% - 93.08% - 20/07/2024 92.22% - 93.08% - 21/07/2024 92.22% - 93.08% - 22/07/2024 92.22% - 93.08% - 23/07/2024 92.22% - 93.08% - 24/07/2024 92.22% - 93.08% - 25/07/2024 92.22% - 93.08% - 26/07/2024 92.22% - 93.08% - 27/07/2024 92.22% - 93.08% - 28/07/2024 92.22% - 93.08% - 29/07/2024 92.22% - 93.08% - 30/07/2024 92.22% - 93.08% - 31/07/2024 92.22% - 93.08% - Empidonax virescens 01/07/2024 94.74% - 96.05% - 02/07/2024 94.74% - 96.05% - 03/07/2024 94.74% - 96.05% - 04/07/2024 94.74% - 96.05% - 05/07/2024 94.74% - 96.05% - 06/07/2024 94.74% - 96.05% - 07/07/2024 94.74% - 96.05% - 08/07/2024 94.74% - 96.05% - 09/07/2024 94.74% - 96.05% - 10/07/2024 94.74% - 96.05% - 11/07/2024 94.74% - 96.05% - 12/07/2024 94.74% - 96.05% - 13/07/2024 94.74% - 96.05% - 14/07/2024 94.74% - 96.05% - 15/07/2024 94.74% - 96.05% - 16/07/2024 94.74% - 96.05% - 17/07/2024 94.74% - 96.05% - 18/07/2024 94.74% - 96.05% - 19/07/2024 94.74% - 96.05% - 20/07/2024 94.74% - 96.05% - 21/07/2024 94.74% - 96.05% - 22/07/2024 94.74% - 96.05% - 23/07/2024 94.74% - 96.05% - 24/07/2024 94.74% - 96.05% - 25/07/2024 94.74% - 96.05% - 26/07/2024 94.74% - 96.05% - 27/07/2024 94.74% - 96.05% - 28/07/2024 94.74% - 96.05% - 29/07/2024 94.74% - 96.05% - 30/07/2024 94.74% - 96.05% - 31/07/2024 94.74% - 96.05% - Geothlypis formosa 01/07/2024 92.86% - 94.22% - 02/07/2024 92.86% - 94.22% - 03/07/2024 92.86% - 94.22% - 04/07/2024 92.86% - 94.22% - 05/07/2024 92.86% - 94.22% - 06/07/2024 92.86% - 94.22% - 07/07/2024 92.86% - 94.22% - 08/07/2024 92.86% - 94.22% - 09/07/2024 92.86% - 94.22% - 10/07/2024 92.86% - 94.22% - 11/07/2024 92.86% - 94.22% - 12/07/2024 92.86% - 94.22% - 13/07/2024 92.86% - 94.22% - 14/07/2024 92.86% - 94.22% - 15/07/2024 92.86% - 94.22% - 16/07/2024 92.86% - 94.22% - 17/07/2024 92.86% - 94.22% - 18/07/2024 92.86% - 94.22% - 19/07/2024 92.86% - 94.22% - 20/07/2024 92.86% - 94.22% - 21/07/2024 92.86% - 94.22% - 22/07/2024 92.86% - 94.22% - 23/07/2024 92.86% - 94.22% - 24/07/2024 92.86% - 94.22% - 25/07/2024 92.86% - 94.22% - 26/07/2024 92.86% - 94.22% - 27/07/2024 92.86% - 94.22% - 28/07/2024 92.86% - 94.22% - 29/07/2024 92.86% - 94.22% - 30/07/2024 92.86% - 94.22% - 31/07/2024 92.86% - 94.22% - Geothlypis philadelphia 01/07/2024 94.20% - 94.48% - 02/07/2024 94.20% - 94.48% - 03/07/2024 94.20% - 94.48% - 04/07/2024 94.20% - 94.48% - 05/07/2024 94.20% - 94.48% - 06/07/2024 94.20% - 94.48% - 07/07/2024 94.20% - 94.48% - 08/07/2024 94.20% - 94.48% - 09/07/2024 94.20% - 94.48% - 10/07/2024 94.20% - 94.48% - 11/07/2024 94.20% - 94.48% - 12/07/2024 94.20% - 94.48% - 13/07/2024 94.20% - 94.48% - 14/07/2024 94.20% - 94.48% - 15/07/2024 94.20% - 94.48% - 16/07/2024 94.20% - 94.48% - 17/07/2024 94.20% - 94.48% - 18/07/2024 94.20% - 94.48% - 19/07/2024 94.20% - 94.48% - 20/07/2024 94.20% - 94.48% - 21/07/2024 94.20% - 94.48% - 22/07/2024 94.20% - 94.48% - 23/07/2024 94.20% - 94.48% - 24/07/2024 94.20% - 94.48% - 25/07/2024 94.20% - 94.48% - 26/07/2024 94.20% - 94.48% - 27/07/2024 94.20% - 94.48% - 28/07/2024 94.20% - 94.48% - 29/07/2024 94.20% - 94.48% - 30/07/2024 94.20% - 94.48% - 31/07/2024 94.20% - 94.48% - Mniotilta varia 01/07/2024 97.60% - 98.10% - 02/07/2024 97.60% - 98.10% - 03/07/2024 97.60% - 98.10% - 04/07/2024 97.60% - 98.10% - 05/07/2024 97.60% - 98.10% - 06/07/2024 97.60% - 98.10% - 07/07/2024 97.60% - 98.10% - 08/07/2024 97.60% - 98.10% - 09/07/2024 97.60% - 98.10% - 10/07/2024 97.60% - 98.10% - 11/07/2024 97.60% - 98.10% - 12/07/2024 97.60% - 98.10% - 13/07/2024 97.60% - 98.10% - 14/07/2024 97.60% - 98.10% - 15/07/2024 97.60% - 98.10% - 16/07/2024 97.60% sí 98.10% sí 17/07/2024 97.60% - 98.10% - 18/07/2024 97.60% - 98.10% - 19/07/2024 97.60% - 98.10% - 20/07/2024 97.60% - 98.10% - 21/07/2024 97.60% - 98.10% - 22/07/2024 97.60% - 98.10% - 23/07/2024 97.60% - 98.10% - 24/07/2024 97.60% - 98.10% - 25/07/2024 97.60% - 98.10% - 26/07/2024 97.60% - 98.10% - 27/07/2024 97.60% - 98.10% - 28/07/2024 97.60% - 98.10% - 29/07/2024 97.60% - 98.10% - 30/07/2024 97.60% - 98.10% - 31/07/2024 97.60% - 98.10% - Piranga rubra 01/07/2024 94.66% - 96.36% - 02/07/2024 94.66% - 96.36% - 03/07/2024 94.66% - 96.36% - 04/07/2024 94.66% - 96.36% - 05/07/2024 94.66% - 96.36% - 06/07/2024 94.66% - 96.36% - 07/07/2024 94.66% - 96.36% - 08/07/2024 94.66% - 96.36% - 09/07/2024 94.66% - 96.36% - 10/07/2024 94.66% - 96.36% - 11/07/2024 94.66% - 96.36% - 12/07/2024 94.66% - 96.36% - 13/07/2024 94.66% - 96.36% - 14/07/2024 94.66% - 96.36% - 15/07/2024 94.66% - 96.36% - 16/07/2024 94.66% - 96.36% - 17/07/2024 94.66% - 96.36% - 18/07/2024 94.66% - 96.36% - 19/07/2024 94.66% - 96.36% - 20/07/2024 94.66% - 96.36% - 21/07/2024 94.66% - 96.36% - 22/07/2024 94.66% - 96.36% - 23/07/2024 94.66% - 96.36% - 24/07/2024 94.66% - 96.36% - 25/07/2024 94.66% - 96.36% - 26/07/2024 94.66% - 96.36% - 27/07/2024 94.66% - 96.36% - 28/07/2024 94.66% - 96.36% - 29/07/2024 94.66% - 96.36% - 30/07/2024 94.66% - 96.36% - 31/07/2024 94.66% - 96.36% - Protonotaria citrea 01/07/2024 91.49% - 92.98% - 02/07/2024 91.49% - 92.98% - 03/07/2024 91.49% - 92.98% - 04/07/2024 91.49% - 92.98% - 05/07/2024 91.49% - 92.98% - 06/07/2024 91.49% - 92.98% - 07/07/2024 91.49% - 92.98% - 08/07/2024 91.49% - 92.98% - 09/07/2024 91.49% - 92.98% - 10/07/2024 91.49% - 92.98% - 11/07/2024 91.49% - 92.98% - 12/07/2024 91.49% - 92.98% - 13/07/2024 91.49% - 92.98% - 14/07/2024 91.49% - 92.98% - 15/07/2024 91.49% - 92.98% - 16/07/2024 91.49% - 92.98% - 17/07/2024 91.49% - 92.98% - 18/07/2024 91.49% - 92.98% - 19/07/2024 91.49% - 92.98% - 20/07/2024 91.49% - 92.98% - 21/07/2024 91.49% - 92.98% - 22/07/2024 91.49% - 92.98% - 23/07/2024 91.49% - 92.98% - 24/07/2024 91.49% - 92.98% - 25/07/2024 91.49% - 92.98% - 26/07/2024 91.49% - 92.98% - 27/07/2024 91.49% - 92.98% - 28/07/2024 91.49% - 92.98% - 29/07/2024 91.49% - 92.98% - 30/07/2024 91.49% - 92.98% - 31/07/2024 91.49% - 92.98% - Setophaga coronata 01/07/2024 99.64% - 99.64% - 02/07/2024 99.64% - 99.64% - 03/07/2024 99.64% - 99.64% - 04/07/2024 99.64% - 99.64% - 05/07/2024 99.64% - 99.64% - 06/07/2024 99.64% - 99.64% - 07/07/2024 99.64% - 99.64% - 08/07/2024 99.64% - 99.64% - 09/07/2024 99.64% - 99.64% - 10/07/2024 99.64% - 99.64% - 11/07/2024 99.64% - 99.64% - 12/07/2024 99.64% - 99.64% - 13/07/2024 99.64% - 99.64% - 14/07/2024 99.64% - 99.64% - 15/07/2024 99.64% - 99.64% - 16/07/2024 99.64% - 99.64% - 17/07/2024 99.64% - 99.64% - 18/07/2024 99.64% - 99.64% - 19/07/2024 99.64% - 99.64% - 20/07/2024 99.64% - 99.64% - 21/07/2024 99.64% - 99.64% - 22/07/2024 99.64% - 99.64% - 23/07/2024 99.64% - 99.64% - 24/07/2024 99.64% - 99.64% - 25/07/2024 99.64% - 99.64% - 26/07/2024 99.64% - 99.64% - 27/07/2024 99.64% - 99.64% - 28/07/2024 99.64% - 99.64% - 29/07/2024 99.64% - 99.64% - 30/07/2024 99.64% - 99.64% - 31/07/2024 99.64% - 99.64% - Setophaga magnolia 01/07/2024 98.19% - 98.56% - 02/07/2024 98.19% - 98.56% - 03/07/2024 98.19% - 98.56% - 04/07/2024 98.19% - 98.56% - 05/07/2024 98.19% - 98.56% - 06/07/2024 98.19% - 98.56% - 07/07/2024 98.19% - 98.56% - 08/07/2024 98.19% - 98.56% - 09/07/2024 98.19% - 98.56% - 10/07/2024 98.19% - 98.56% - 11/07/2024 98.19% - 98.56% - 12/07/2024 98.19% - 98.56% - 13/07/2024 98.19% - 98.56% - 14/07/2024 98.19% - 98.56% - 15/07/2024 98.19% - 98.56% - 16/07/2024 98.19% - 98.56% - 17/07/2024 98.19% - 98.56% - 18/07/2024 98.19% - 98.56% - 19/07/2024 98.19% - 98.56% - 20/07/2024 98.19% - 98.56% - 21/07/2024 98.19% - 98.56% - 22/07/2024 98.19% - 98.56% - 23/07/2024 98.19% - 98.56% - 24/07/2024 98.19% - 98.56% - 25/07/2024 98.19% - 98.56% - 26/07/2024 98.19% - 98.56% - 27/07/2024 98.19% - 98.56% - 28/07/2024 98.19% - 98.56% - 29/07/2024 98.19% - 98.56% - 30/07/2024 98.19% - 98.56% - 31/07/2024 98.19% - 98.56% - Setophaga pensylvanica 01/07/2024 95.69% - 96.38% - 02/07/2024 95.69% - 96.38% - 03/07/2024 95.69% - 96.38% - 04/07/2024 95.69% - 96.38% - 05/07/2024 95.69% - 96.38% - 06/07/2024 95.69% - 96.38% - 07/07/2024 95.69% - 96.38% - 08/07/2024 95.69% - 96.38% - 09/07/2024 95.69% - 96.38% - 10/07/2024 95.69% - 96.38% - 11/07/2024 95.69% - 96.38% - 12/07/2024 95.69% - 96.38% - 13/07/2024 95.69% - 96.38% - 14/07/2024 95.69% - 96.38% - 15/07/2024 95.69% - 96.38% - 16/07/2024 95.69% - 96.38% - 17/07/2024 95.69% - 96.38% - 18/07/2024 95.69% - 96.38% - 19/07/2024 95.69% - 96.38% - 20/07/2024 95.69% - 96.38% - 21/07/2024 95.69% - 96.38% - 22/07/2024 95.69% - 96.38% - 23/07/2024 95.69% - 96.38% - 24/07/2024 95.69% - 96.38% - 25/07/2024 95.69% - 96.38% - 26/07/2024 95.69% - 96.38% - 27/07/2024 95.69% - 96.38% - 28/07/2024 95.69% - 96.38% - 29/07/2024 95.69% - 96.38% - 30/07/2024 95.69% - 96.38% - 31/07/2024 95.69% - 96.38% - Setophaga petechia 01/07/2024 96.83% - 96.88% - 02/07/2024 96.83% sí 96.88% sí 03/07/2024 96.83% sí 96.88% sí 04/07/2024 96.83% sí 96.88% sí 05/07/2024 96.83% sí 96.88% sí 06/07/2024 96.83% sí 96.88% sí 07/07/2024 96.83% sí 96.88% sí 08/07/2024 96.83% sí 96.88% sí 09/07/2024 96.83% sí 96.88% sí 10/07/2024 96.83% - 96.88% - 11/07/2024 96.83% - 96.88% - 12/07/2024 96.83% sí 96.88% sí 13/07/2024 96.83% sí 96.88% sí 14/07/2024 96.83% sí 96.88% sí 15/07/2024 96.83% sí 96.88% sí 16/07/2024 96.83% sí 96.88% sí 17/07/2024 96.83% - 96.88% - 18/07/2024 96.83% - 96.88% - 19/07/2024 96.83% sí 96.88% sí 20/07/2024 96.83% sí 96.88% sí 21/07/2024 96.83% - 96.88% sí 22/07/2024 96.83% sí 96.88% sí 23/07/2024 96.83% sí 96.88% sí 24/07/2024 96.83% sí 96.88% sí 25/07/2024 96.83% sí 96.88% sí 26/07/2024 96.83% sí 96.88% sí 27/07/2024 96.83% - 96.88% - 28/07/2024 96.83% - 96.88% - 29/07/2024 96.83% sí 96.88% sí 30/07/2024 96.83% sí 96.88% sí 31/07/2024 96.83% - 96.88% - Setophaga ruticilla 01/07/2024 92.01% - 93.10% - 02/07/2024 92.01% - 93.10% - 03/07/2024 92.01% - 93.10% - 04/07/2024 92.01% - 93.10% - 05/07/2024 92.01% - 93.10% - 06/07/2024 92.01% - 93.10% - 07/07/2024 92.01% - 93.10% - 08/07/2024 92.01% - 93.10% - 09/07/2024 92.01% - 93.10% - 10/07/2024 92.01% - 93.10% - 11/07/2024 92.01% - 93.10% - 12/07/2024 92.01% - 93.10% - 13/07/2024 92.01% - 93.10% - 14/07/2024 92.01% - 93.10% - 15/07/2024 92.01% - 93.10% - 16/07/2024 92.01% - 93.10% - 17/07/2024 92.01% - 93.10% - 18/07/2024 92.01% - 93.10% - 19/07/2024 92.01% - 93.10% - 20/07/2024 92.01% - 93.10% - 21/07/2024 92.01% - 93.10% - 22/07/2024 92.01% - 93.10% - 23/07/2024 92.01% - 93.10% - 24/07/2024 92.01% - 93.10% - 25/07/2024 92.01% - 93.10% - 26/07/2024 92.01% - 93.10% - 27/07/2024 92.01% - 93.10% - 28/07/2024 92.01% - 93.10% - 29/07/2024 92.01% - 93.10% - 30/07/2024 92.01% - 93.10% - 31/07/2024 92.01% - 93.10% - Setophaga tigrina 01/07/2024 100.00% - 100.00% - 02/07/2024 100.00% - 100.00% - 03/07/2024 100.00% - 100.00% - 04/07/2024 100.00% - 100.00% - 05/07/2024 100.00% - 100.00% - 06/07/2024 100.00% - 100.00% - 07/07/2024 100.00% - 100.00% - 08/07/2024 100.00% - 100.00% - 09/07/2024 100.00% - 100.00% - 10/07/2024 100.00% - 100.00% - 11/07/2024 100.00% - 100.00% - 12/07/2024 100.00% - 100.00% - 13/07/2024 100.00% - 100.00% - 14/07/2024 100.00% - 100.00% - 15/07/2024 100.00% - 100.00% - 16/07/2024 100.00% - 100.00% - 17/07/2024 100.00% - 100.00% - 18/07/2024 100.00% - 100.00% - 19/07/2024 100.00% - 100.00% - 20/07/2024 100.00% - 100.00% - 21/07/2024 100.00% - 100.00% - 22/07/2024 100.00% - 100.00% - 23/07/2024 100.00% - 100.00% - 24/07/2024 100.00% - 100.00% - 25/07/2024 100.00% - 100.00% - 26/07/2024 100.00% - 100.00% - 27/07/2024 100.00% - 100.00% - 28/07/2024 100.00% - 100.00% - 29/07/2024 100.00% - 100.00% - 30/07/2024 100.00% - 100.00% - 31/07/2024 100.00% - 100.00% - Setophaga virens 01/07/2024 96.66% - 96.66% - 02/07/2024 96.66% - 96.66% - 03/07/2024 96.66% - 96.66% - 04/07/2024 96.66% - 96.66% - 05/07/2024 96.66% - 96.66% - 06/07/2024 96.66% - 96.66% - 07/07/2024 96.66% - 96.66% - 08/07/2024 96.66% - 96.66% - 09/07/2024 96.66% - 96.66% - 10/07/2024 96.66% - 96.66% - 11/07/2024 96.66% - 96.66% - 12/07/2024 96.66% - 96.66% - 13/07/2024 96.66% - 96.66% - 14/07/2024 96.66% - 96.66% - 15/07/2024 96.66% - 96.66% - 16/07/2024 96.66% - 96.66% - 17/07/2024 96.66% - 96.66% - 18/07/2024 96.66% - 96.66% - 19/07/2024 96.66% - 96.66% - 20/07/2024 96.66% - 96.66% - 21/07/2024 96.66% - 96.66% - 22/07/2024 96.66% - 96.66% - 23/07/2024 96.66% - 96.66% - 24/07/2024 96.66% - 96.66% - 25/07/2024 96.66% - 96.66% - 26/07/2024 96.66% - 96.66% - 27/07/2024 96.66% - 96.66% - 28/07/2024 96.66% - 96.66% - 29/07/2024 96.66% - 96.66% - 30/07/2024 96.66% - 96.66% - 31/07/2024 96.66% - 96.66% - Tyrannus tyrannus 01/07/2024 94.31% - 95.44% - 02/07/2024 94.31% sí 95.44% - 03/07/2024 94.31% - 95.44% - 04/07/2024 94.31% - 95.44% - 05/07/2024 94.31% - 95.44% - 06/07/2024 94.31% - 95.44% - 07/07/2024 94.31% - 95.44% - 08/07/2024 94.31% - 95.44% - 09/07/2024 94.31% - 95.44% - 10/07/2024 94.31% - 95.44% - 11/07/2024 94.31% - 95.44% - 12/07/2024 94.31% - 95.44% - 13/07/2024 94.31% - 95.44% - 14/07/2024 94.31% - 95.44% - 15/07/2024 94.31% - 95.44% - 16/07/2024 94.31% - 95.44% - 17/07/2024 94.31% - 95.44% - 18/07/2024 94.31% - 95.44% - 19/07/2024 94.31% - 95.44% - 20/07/2024 94.31% - 95.44% - 21/07/2024 94.31% - 95.44% - 22/07/2024 94.31% - 95.44% - 23/07/2024 94.31% - 95.44% - 24/07/2024 94.31% - 95.44% - 25/07/2024 94.31% - 95.44% - 26/07/2024 94.31% - 95.44% - 27/07/2024 94.31% - 95.44% - 28/07/2024 94.31% - 95.44% - 29/07/2024 94.31% - 95.44% - 30/07/2024 94.31% - 95.44% - 31/07/2024 94.31% - 95.44% - Vireo flavifrons 01/07/2024 95.59% - 95.25% - 02/07/2024 95.59% - 95.25% - 03/07/2024 95.59% - 95.25% - 04/07/2024 95.59% - 95.25% - 05/07/2024 95.59% - 95.25% - 06/07/2024 95.59% - 95.25% - 07/07/2024 95.59% - 95.25% - 08/07/2024 95.59% - 95.25% - 09/07/2024 95.59% - 95.25% - 10/07/2024 95.59% - 95.25% - 11/07/2024 95.59% - 95.25% - 12/07/2024 95.59% - 95.25% - 13/07/2024 95.59% - 95.25% - 14/07/2024 95.59% - 95.25% - 15/07/2024 95.59% - 95.25% - 16/07/2024 95.59% - 95.25% - 17/07/2024 95.59% - 95.25% - 18/07/2024 95.59% - 95.25% - 19/07/2024 95.59% - 95.25% - 20/07/2024 95.59% - 95.25% - 21/07/2024 95.59% - 95.25% - 22/07/2024 95.59% - 95.25% - 23/07/2024 95.59% - 95.25% - 24/07/2024 95.59% - 95.25% - 25/07/2024 95.59% - 95.25% - 26/07/2024 95.59% - 95.25% - 27/07/2024 95.59% - 95.25% - 28/07/2024 95.59% - 95.25% - 29/07/2024 95.59% - 95.25% - 30/07/2024 95.59% - 95.25% - 31/07/2024 95.59% - 95.25% - Vireo olivaceus 01/07/2024 97.74% - 98.10% - 02/07/2024 97.74% - 98.10% - 03/07/2024 97.74% - 98.10% - 04/07/2024 97.74% - 98.10% - 05/07/2024 97.74% - 98.10% - 06/07/2024 97.74% - 98.10% - 07/07/2024 97.74% - 98.10% - 08/07/2024 97.74% - 98.10% - 09/07/2024 97.74% - 98.10% - 10/07/2024 97.74% - 98.10% - 11/07/2024 97.74% - 98.10% - 12/07/2024 97.74% - 98.10% - 13/07/2024 97.74% - 98.10% - 14/07/2024 97.74% - 98.10% - 15/07/2024 97.74% - 98.10% - 16/07/2024 97.74% - 98.10% - 17/07/2024 97.74% - 98.10% - 18/07/2024 97.74% - 98.10% - 19/07/2024 97.74% - 98.10% - 20/07/2024 97.74% - 98.10% - 21/07/2024 97.74% - 98.10% - 22/07/2024 97.74% - 98.10% - 23/07/2024 97.74% - 98.10% - 24/07/2024 97.74% - 98.10% - 25/07/2024 97.74% - 98.10% - 26/07/2024 97.74% - 98.10% - 27/07/2024 97.74% - 98.10% - 28/07/2024 97.74% - 98.10% - 29/07/2024 97.74% - 98.10% - 30/07/2024 97.74% - 98.10% - 31/07/2024 97.74% - 98.10% -