<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Javi AS</title>
    <description>The latest articles on DEV Community by Javi AS (@javier-aranda).</description>
    <link>https://dev.to/javier-aranda</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F184798%2F1f0fe887-1384-4381-b794-eed920141bc6.jpg</url>
      <title>DEV Community: Javi AS</title>
      <link>https://dev.to/javier-aranda</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/javier-aranda"/>
    <language>en</language>
    <item>
      <title>Scraping de Open Data utilizando GitHub</title>
      <dc:creator>Javi AS</dc:creator>
      <pubDate>Sat, 01 Jun 2024 10:48:01 +0000</pubDate>
      <link>https://dev.to/javier-aranda/scraping-de-open-data-utilizando-github-2np7</link>
      <guid>https://dev.to/javier-aranda/scraping-de-open-data-utilizando-github-2np7</guid>
      <description>&lt;p&gt;El &lt;strong&gt;dato&lt;/strong&gt; se ha convertido en un elemento fundamental para parametrizar el mundo que nos rodea. En esta era de la información surge también el concepto de &lt;strong&gt;Datos Abiertos&lt;/strong&gt; u &lt;strong&gt;Open Data&lt;/strong&gt;, una filosofía que busca de forma libre y para todo el mundo que se pueda consumir distintos tipos de datos sin restricciones de derechos de autor, patentes u otros mecanismos de control.&lt;/p&gt;

&lt;p&gt;Diversos portales orientados a esta práctica, tanto de entidades públicas como privadas, publican y actualizan información de diversa índole con cierta periodicidad. Esto permite a ciudadanos, investigadores y organizaciones &lt;strong&gt;desarrollar aplicaciones o nuevas soluciones&lt;/strong&gt;. A fin de cuentas, el dato se puede considerar un punto de partida sobre el que envolver ciertas capas de abstracción para que le den sentido en un contexto específico.&lt;/p&gt;

&lt;p&gt;En ocasiones, estos datos no están historificados, es decir, se obtienen al momento y cuando se actualizan la información anterior no puede volver a ser consultada. Este post nace de la curiosidad y necesidad de poder visualizar la información en varios puntos temporales para ver su evolución.&lt;/p&gt;

&lt;p&gt;Simon Willison define el &lt;strong&gt;git scraping&lt;/strong&gt;[1] como la técnica para versionar en un repositorio las variaciones de un recurso, como pueda ser la respuesta de un endpoint. Su motivación principal para desarrollar este tipo de sistema fue tener un registro histórico y actualizado sobre incendios en California, proporcionado por Mozilla.&lt;/p&gt;

&lt;p&gt;A raíz de esta idea nace &lt;strong&gt;Flat Data&lt;/strong&gt;[2], de GitHub Next. Este proyecto permite automatizar la captura de datos de un recurso aprovechando la infraestructura que otorga **GitHub **para ejecutar **tareas programadas **y actualizar un repositorio con dicha información.&lt;/p&gt;

&lt;p&gt;Para hacer un análogo del proyecto de Simon Willison, con apoyo del catálogo abierto de incendios activos de la NASA[3] se puede diseñar fácilmente un **scraper para obtener los datos **relativos a incendios en Europa de los últimos 7 días, con una frecuencia de refresco diaria.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Flat

on:
  push:
    branches:
      - main
  workflow_dispatch:
  schedule:
    - cron: '0 0 * * *'

jobs:
  scheduled:
    runs-on: ubuntu-latest
    steps:
      - name: Setup deno
        uses: denoland/setup-deno@main
        with:
          deno-version: v1.10.x
      - name: Check out repo
        uses: actions/checkout@v2
      - name: Fetch data
        uses: githubocto/flat@v3
        with:
          http_url: "https://firms.modaps.eosdis.nasa.gov/data/active_fire/modis-c6.1/csv/MODIS_C6_1_Europe_7d.csv"
          downloaded_filename: "europe_fire_7d.csv"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Antes de que se ejecute, conviene revisar que en las GitHub Actions del repositorio se den &lt;strong&gt;permisos de escritura para evitar un error 403&lt;/strong&gt; a la hora de hacer commit del contenido. Desde una URL &lt;a href="https://github.com/%7BUSERNAME%7D/%7BREPOSITORY%7D/settings/actions"&gt;https://github.com/{USERNAME}/{REPOSITORY}/settings/actions&lt;/a&gt; podemos configurar estos permisos haciendo scroll hasta el final, como se indica en la siguiente imagen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx0277xvv45w6f0tcw256.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx0277xvv45w6f0tcw256.png" alt="Configuración de escritura para workflows en las GH Actions" width="800" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Una vez ejecutada la GitHub Action, en el repositorio aparecerá esta información y de manera automática se irá refrescando, &lt;strong&gt;manteniendo versiones anteriores para su consulta por cualquier usuario en cualquier momento&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fc3h8qdhfpditz32x5p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fc3h8qdhfpditz32x5p.png" alt="Repositorio de ejemplo de Flat Data" width="800" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;El código de referencia se encuentra disponible en este enlace: &lt;a href="https://github.com/javi-aranda/flat-data-example/"&gt;https://github.com/javi-aranda/flat-data-example/&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Referencias:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[1] Git Scraping: &lt;a href="https://simonwillison.net/2020/Oct/9/git-scraping/"&gt;https://simonwillison.net/2020/Oct/9/git-scraping/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;[2] Flat Data: &lt;a href="https://githubnext.com/projects/flat-data"&gt;https://githubnext.com/projects/flat-data&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;[3] Catálogo de incendios de la NASA: &lt;a href="https://firms.modaps.eosdis.nasa.gov/active_fire/#firms-txt"&gt;https://firms.modaps.eosdis.nasa.gov/active_fire/#firms-txt&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>scraping</category>
      <category>github</category>
      <category>opendata</category>
      <category>spanish</category>
    </item>
    <item>
      <title>PELUSA: Detectando phishing mediante Machine Learning</title>
      <dc:creator>Javi AS</dc:creator>
      <pubDate>Wed, 11 Oct 2023 18:26:07 +0000</pubDate>
      <link>https://dev.to/javier-aranda/pelusa-detectando-phishing-mediante-machine-learning-3iia</link>
      <guid>https://dev.to/javier-aranda/pelusa-detectando-phishing-mediante-machine-learning-3iia</guid>
      <description>&lt;p&gt;El &lt;strong&gt;phishing&lt;/strong&gt; es una técnica utilizada para suplantar sitios legítimos incitando a usuarios finales a introducir credenciales, tarjetas de pago u otros datos sensibles. A día de hoy sigue siendo una de las &lt;strong&gt;amenazas principales&lt;/strong&gt; en materia de seguridad informática. Muchos usuarios no son expertos en su detección, y es comprensible dado que cada vez son más sofisticados.&lt;/p&gt;

&lt;p&gt;Los mecanismos más comunes a través de los cuáles se propaga un phishing suelen ser los &lt;strong&gt;SMS&lt;/strong&gt; (indicando cancelaciones de tarjetas de pago o extractos bancarios que requieren revisiones con urgencia, o un pago para desbloquear un paquete retenido en aduanas...) y el &lt;strong&gt;correo electrónico&lt;/strong&gt; (cargos pendientes a Hacienda, etc.).&lt;/p&gt;

&lt;h2&gt;
  
  
  Contexto
&lt;/h2&gt;

&lt;p&gt;Por lo general, los ciberdelincuentes utilizan técnicas como &lt;em&gt;typosquatting&lt;/em&gt; para intentar engañar al ojo humano, al que le puede costar diferenciar &lt;code&gt;https://google.com&lt;/code&gt; de &lt;code&gt;https://gooogle.com&lt;/code&gt;. Algunos se aprovechan de subdominios muy largos para parecer reales, al estilo &lt;code&gt;http://tramites.mi-area-de-gestion-privada.nombredebanco.&amp;lt;nombre-de-web&amp;gt;.com&lt;/code&gt;, si se da el caso de que los atacantes infectan un sitio existente y aprovechan para plantar ahí su página falsa. Otros pueden emplear &lt;strong&gt;acortadores de enlace&lt;/strong&gt;, muy comunes en la propagación por SMS, y los más espabilados pueden intentar usar &lt;em&gt;punycode&lt;/em&gt; [1] para que al mostrar el enlace en la barra de navegación no se diferencie a simple vista del original, aunque sean realmente distintos.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_7sn7eZj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sadwciqcmk99zuppqb27.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_7sn7eZj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sadwciqcmk99zuppqb27.png" alt="Al entrar en https://www.xn--80ak6aa92e.com/ nos aparece en el navegador una web aparentemente de Apple" width="735" height="310"&gt;&lt;/a&gt;&lt;br&gt;
En el ejemplo de arriba, la página web que se está mostrando realmente es &lt;code&gt;https://www.xn--80ak6aa92e.com/&lt;/code&gt;, pero en la barra de navegación parece &lt;code&gt;https://apple.com/&lt;/code&gt;, incluyendo certificado SSL. Este dominio está registrado con caracteres cirílicos correspondientes al alfabeto ruso, y los navegadores los muestran de forma similar a los caracteres del alfabeto latín al que estamos acostumbrados.&lt;/p&gt;

&lt;p&gt;Entender cómo funciona este tipo de ataques desde "el lado oscuro" puede ayudar a crear mecanismos para facilitar su detección. Con este propósito en mente, he dedicado varias semanas a desarrollar un proyecto relacionado con esto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Presentando PELUSA
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;PELUSA&lt;/strong&gt;, acrónimo para &lt;strong&gt;Predictive Engine for Legitimate &amp;amp; Unverified Site Assessment&lt;/strong&gt;, es una aplicación que utiliza Machine Learning para clasificar un enlace como malicioso o legítimo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3K2bmosY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uwsuj80gwmgonweseb0g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3K2bmosY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uwsuj80gwmgonweseb0g.png" alt="Pelusa website" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para el entrenamiento del modelo, he utilizado un conjunto de datos de elaboración propia. Gracias a un fichero de sitios activos catalogados de &lt;strong&gt;PhishTank&lt;/strong&gt; y a una serie de muestras seleccionadas de forma aleatoria de varias colecciones de &lt;strong&gt;Kaggle&lt;/strong&gt; he obtenido 30.000 webs, la mitad clasificadas como maliciosas y la mitad seguras para navegar. Sobre dicho conjunto he aplicado un analizador estático, escrito en Python, para extraer características como pueda ser la &lt;strong&gt;longitud del dominio&lt;/strong&gt;, si utiliza algún &lt;strong&gt;acortador de enlace&lt;/strong&gt;, la presencia de &lt;strong&gt;palabras sospechosas&lt;/strong&gt; en la URL, etc.&lt;/p&gt;

&lt;p&gt;Tras obtener las características más relevantes y dividir el conjunto de datos en entrenamiento y test, probé con varios modelos, entre los que despuntaban &lt;strong&gt;Random Forest&lt;/strong&gt; [2] y &lt;strong&gt;XGBoost&lt;/strong&gt; con un 94% de precisión frente a un modelo de Regresión Logística con el que solo tenía un 84% de precisión. Finalmente decidí utilizar Random Forest porque su tiempo de entrenamiento era algo más corto y ofrecía resultados similares. Este clasificador, a diferencia de otros que dependen de un solo modelo para tomar decisiones, se basa en una &lt;strong&gt;estrategia de "sabiduría colectiva"&lt;/strong&gt;, combinando las predicciones de múltiples modelos individuales para producir una predicción general más sólida y precisa.&lt;/p&gt;

&lt;p&gt;Una vez finalizado el entrenamiento del modelo, al pasarle las características extraídas de varios enlaces, tanto legítimos como maliciosos, devolvió unas &lt;strong&gt;predicciones correctas&lt;/strong&gt;. Sin embargo, hay casos en los que cualquier URL que tenga un número largo de caracteres puede ser detectado como malicioso. Este tipo de comportamientos es normal dado el tamaño de entrenamiento y las características disponibles, y quiero mejorarlo en el futuro.&lt;/p&gt;

&lt;h2&gt;
  
  
  Próximos planes
&lt;/h2&gt;

&lt;p&gt;En la parte de mi tiempo libre que dedico a trabajar en PELUSA, pienso en nuevas características que incorporar al analizador para elaborar un conjunto de datos aún más completo, y que ya detallaré en próximas iteraciones. Algunas de estas ideas incluyen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fecha de creación y expiración del dominio.&lt;/li&gt;
&lt;li&gt;Validar si el dominio de una URL se encuentra indexado en motores de búsqueda.&lt;/li&gt;
&lt;li&gt;Qué registros DNS hay asociados al dominio.&lt;/li&gt;
&lt;li&gt;Si la web dispone de SSL, así como la confianza de la Entidad Certificadora (CA) que emita el certificado.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cómo usar PELUSA
&lt;/h2&gt;

&lt;p&gt;En este momento, PELUSA &lt;strong&gt;funciona únicamente de forma local&lt;/strong&gt;. Mediante &lt;strong&gt;Docker&lt;/strong&gt; se pueden desplegar fácilmente tanto un Frontend [3] escrito en React como el Backend [4], que utiliza FastAPI y PostgreSQL para almacenar las predicciones realizadas. De esta forma, el Backend queda desacoplado para que se pueda integrar con otras herramientas y así tener un apoyo extra en la detección de phishing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusiones
&lt;/h2&gt;

&lt;p&gt;Las &lt;strong&gt;brechas de seguridad&lt;/strong&gt; que múltiples compañías sufren día a día terminan exponiendo muchos datos que los ciberdelincuentes pueden aprovechar para dirigir &lt;strong&gt;ataques personalizados&lt;/strong&gt;, por eso hay que tener especial cuidado cuando introducimos datos, ya sea a través del móvil, ordenador, tablet o cualquier dispositivo. Internet es un ente que crece por momentos. No hay consenso real en cuántos sitios nuevos aparecen cada día, ya que las estimaciones varían entre 200.000 [5] a 500.000. Las probabilidades de que ninguno termine siendo utilizado por ciberdelincuentes son remotas, por lo que disponer de herramientas que ayuden de forma automática a realizar esta labor puede aportar un grado extra de seguridad.&lt;/p&gt;

&lt;h2&gt;
  
  
  Referencias
&lt;/h2&gt;

&lt;p&gt;[1] &lt;a href="https://fraudwatch.com/what-is-punycode-phishing-part-1/"&gt;https://fraudwatch.com/what-is-punycode-phishing-part-1/&lt;/a&gt;&lt;br&gt;
[2] &lt;a href="https://es.wikipedia.org/wiki/Random_forest"&gt;https://es.wikipedia.org/wiki/Random_forest&lt;/a&gt;&lt;br&gt;
[3] &lt;a href="https://github.com/javi-aranda/pelusa-react"&gt;https://github.com/javi-aranda/pelusa-react&lt;/a&gt;&lt;br&gt;
[4] &lt;a href="https://github.com/javi-aranda/pelusa-server"&gt;https://github.com/javi-aranda/pelusa-server&lt;/a&gt;&lt;br&gt;
[5] &lt;a href="https://www.statsfind.com/how-many-websites-are-there-in-the-world-a-daily-calculator/"&gt;https://www.statsfind.com/how-many-websites-are-there-in-the-world-a-daily-calculator/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>cybersecurity</category>
      <category>spanish</category>
    </item>
    <item>
      <title>HyperLogLog | Un algoritmo para contarlos (aproximadamente) a todos</title>
      <dc:creator>Javi AS</dc:creator>
      <pubDate>Wed, 04 Oct 2023 21:08:19 +0000</pubDate>
      <link>https://dev.to/javier-aranda/hyperloglog-un-algoritmo-para-contarlos-aproximadamente-a-todos-2pof</link>
      <guid>https://dev.to/javier-aranda/hyperloglog-un-algoritmo-para-contarlos-aproximadamente-a-todos-2pof</guid>
      <description>&lt;p&gt;Imagina que trabajas en el equipo de ingeniería de una aplicación con un gran volumen de usuarios y tienes que obtener métricas de forma rápida sobre cuántos usuarios únicos tienes en un día. Veamos cómo resolver este caso de uso.&lt;/p&gt;




&lt;p&gt;La potencia que proporciona un marco matemático y el análisis y diseño de algoritmos a la programación permite resolver problemas de todo tipo, como pudiera ser la &lt;strong&gt;estimación de la cardinalidad&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;El problema de estimación de la cardinalidad trata de averiguar el número de &lt;strong&gt;elementos distintos en un conjunto&lt;/strong&gt; o flujo de datos donde puedan existir elementos repetidos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ztkoWh16--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o3qokxpo05z104vldojn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ztkoWh16--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o3qokxpo05z104vldojn.png" alt="Una representación sencilla de varios conjuntos de datos y su correspondiente cardinalidad." width="547" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  El problema, desde la base
&lt;/h2&gt;

&lt;p&gt;Podemos ejemplificar este problema considerando que tenemos un listado con todas las palabras de un libro, y queremos saber cuántas palabras distintas hay en él.&lt;/p&gt;

&lt;p&gt;Una solución, intuitiva a primera vista, sería inicializar una estructura de datos vacía, iterar sobre el conjunto de palabras que tenemos e ir añadiendo a nuestra estructura nueva las palabras si no se encuentran ya en dicha estructura. Finalmente, la longitud de este nuevo conjunto será el número de elementos únicos del primer listado.&lt;/p&gt;

&lt;p&gt;Esta solución tiene un problema, que radica en la &lt;strong&gt;escalabilidad&lt;/strong&gt;. Si en lugar de disponer un solo libro tuviéramos que realizar esta operación sobre la totalidad de libros de la Biblioteca Británica (más de 170 millones de ejemplares), este algoritmo requeriría una gran cantidad de memoria para almacenar la nueva estructura. En términos de &lt;strong&gt;complejidad de memoria&lt;/strong&gt;, necesitamos &lt;em&gt;&lt;strong&gt;O(n)&lt;/strong&gt;&lt;/em&gt;, ya que incrementaría de forma lineal mientras más datos de entrada tenemos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Una primera aproximación: Flajolet-Martin
&lt;/h2&gt;

&lt;p&gt;En &lt;strong&gt;1984&lt;/strong&gt;, Philippe &lt;strong&gt;Flajolet&lt;/strong&gt; y G. Nigel &lt;strong&gt;Martin&lt;/strong&gt; proponen una alternativa en su artículo &lt;em&gt;&lt;strong&gt;“Probabilistic Counting Algorithms for Data Base Applications [1]”&lt;/strong&gt;&lt;/em&gt;. Esta solución, conocida como el algoritmo Flajolet-Martin, funciona, en resumidas cuentas, de la siguiente forma:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Creamos un &lt;strong&gt;vector de bits&lt;/strong&gt; de longitud &lt;em&gt;L&lt;/em&gt;, de forma que &lt;em&gt;2^L &amp;gt; n&lt;/em&gt;, donde &lt;em&gt;n&lt;/em&gt; es la longitud del conjunto de datos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Una función &lt;strong&gt;hash&lt;/strong&gt; transforma cada elemento del flujo de datos en un número binario uniforme. La función de hash es &lt;em&gt;(ax + b) mod L&lt;/em&gt;; donde &lt;em&gt;a&lt;/em&gt; y &lt;em&gt;b&lt;/em&gt; son números enteros, &lt;em&gt;x&lt;/em&gt; el elemento de entrada del flujo de datos, y &lt;em&gt;L&lt;/em&gt; es el límite de rango de la función hash que definido en el punto anterior.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Se cuenta el &lt;strong&gt;número de ceros consecutivos&lt;/strong&gt;, al que llamaremos &lt;em&gt;k&lt;/em&gt;, &lt;strong&gt;al final del número binario producido&lt;/strong&gt;. En nuestro vector de bits establecemos el bit &lt;em&gt;k&lt;/em&gt;-ésimo a 1.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Repetimos&lt;/strong&gt; el proceso con cada elemento del flujo de datos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Obtenemos el índice del primer 0&lt;/strong&gt; en el vector de bits, al que llamaremos &lt;em&gt;R&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Estimamos la cardinalidad&lt;/strong&gt; con la fórmula &lt;em&gt;2^R / Φ&lt;/em&gt;. El símbolo &lt;em&gt;Φ&lt;/em&gt; representa un factor de corrección con valor &lt;em&gt;Φ = 0.77351…&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;El algoritmo Flajolet-Martin &lt;strong&gt;se ejecuta con varias funciones hash diferentes y se calcula la media de los resultados&lt;/strong&gt; aproximados, ya que una sola ejecución podría inducir errores si los datos no están compensados al ser hasheados.&lt;/p&gt;

&lt;p&gt;La mejora de rendimiento de esta solución es evidente, ya que su complejidad en memoria es de &lt;em&gt;&lt;strong&gt;O(log(n))&lt;/strong&gt;&lt;/em&gt;, en lugar de &lt;em&gt;O(n)&lt;/em&gt; como la primera sugerencia.&lt;/p&gt;

&lt;h2&gt;
  
  
  LogLog entra en escena
&lt;/h2&gt;

&lt;p&gt;Casi 20 años después, en el Simposio Europeo de Algoritmos de 2003, &lt;strong&gt;Flajolet&lt;/strong&gt; y Marianne &lt;strong&gt;Durand&lt;/strong&gt; presentan &lt;em&gt;&lt;strong&gt;“Loglog Counting of Large Cardinalities [2]”&lt;/strong&gt;&lt;/em&gt; como mejora a este algoritmo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LogLog&lt;/strong&gt; añade el concepto de “&lt;strong&gt;bucketing&lt;/strong&gt;”, por el que se divide el número binario producido por la función de hash en varios grupos de bits. De cada grupo, se toma el número de ceros consecutivos al final y se calcula la mediana. Para obtener la cardinalidad estimada de todo el conjunto de datos, se realiza la media de todas las medianas. &lt;strong&gt;Esto mejora la complejidad en memoria a&lt;/strong&gt; &lt;em&gt;&lt;strong&gt;O(log log n)&lt;/strong&gt;&lt;/em&gt;, de ahí el nombre del algoritmo.&lt;/p&gt;

&lt;p&gt;Esta revisión presenta mejoras al evitar tener que ser ejecutada con distintas funciones de hash para reducir márgenes de error. En el artículo donde se presenta LogLog, una ejecución del algoritmo estimó que, teniendo como datos de entrada &lt;strong&gt;todas las palabras de todas las obras de Shakespeare, se estimaban alrededor de 30.897 palabras&lt;/strong&gt; únicas. &lt;strong&gt;El dato real es de 28.239 palabras&lt;/strong&gt; distintas, dando un &lt;strong&gt;error relativo del 9.4%&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;En el mismo artículo se detalla la implementación de &lt;strong&gt;SuperLogLog&lt;/strong&gt; como una optimización sobre LogLog, que además de contar los ceros consecutivos, tiene en cuenta los siguientes bits. Mediante esta estimación mejorada, obtiene &lt;strong&gt;resultados más precisos en conjuntos pequeños&lt;/strong&gt;, donde más flojea LogLog.&lt;/p&gt;

&lt;h2&gt;
  
  
  Un algoritmo casi óptimo: HyperLogLog
&lt;/h2&gt;

&lt;p&gt;No es hasta pocos años después, ya en &lt;strong&gt;2007&lt;/strong&gt;, cuando &lt;strong&gt;Flajolet&lt;/strong&gt; y otros investigadores evolucionan el concepto y describen &lt;em&gt;&lt;strong&gt;“HyperLogLog: the analysis of a near-optimal cardinality estimation algorithm [3]”&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HyperLogLog (HLL)&lt;/strong&gt; mejora a todo lo anterior, aplicando complejos mecanismos matemáticos y estadísticos que le permiten contar con un error relativo del 2% para cardinalidades superiores a 10⁹. Es considerado casi óptimo, y fue una auténtica revolución cuando se presentó.&lt;/p&gt;

&lt;h2&gt;
  
  
  Casos de uso
&lt;/h2&gt;

&lt;p&gt;A día de hoy, ¿hay empresas y servicios que utilicen HLL? Veamos varios ejemplos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Trino&lt;/strong&gt; (anteriormente conocido como Presto), un motor de consulta SQL orientado a Big Data desarrollado originalmente por &lt;strong&gt;Facebook&lt;/strong&gt; [4].&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Redis&lt;/strong&gt;, el popular motor de base de datos en memoria, implementa HLL con un &lt;strong&gt;error estándar de 0.81%&lt;/strong&gt; [5].&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Amazon Redshift&lt;/strong&gt;, el servicio de Data Warehouse en de Amazon Web Services [6].&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Otros algoritmos de cardinalidad y conclusiones
&lt;/h2&gt;

&lt;p&gt;LogLog ha servido como inspiración para otros algoritmos de estimaciones de cardinalidad. En 2006 se presenta &lt;strong&gt;B-LogLog-EC&lt;/strong&gt; [7], orientado al conteo de tráfico IP. Una revisión de HLL llamada &lt;strong&gt;HyperLogLog++ (HLL++)&lt;/strong&gt; fue presentada por Google en 2013 [8], supliendo algunos de los puntos flacos que tenía HLL, y que en la actualidad es utilizado por &lt;strong&gt;Google Analytics 4&lt;/strong&gt; [9]. No es hasta 2016 que &lt;strong&gt;LogLog-Beta&lt;/strong&gt; [10] aparece en un artículo en arXiv, cuya implementación optimizaría aún más los resultados producidos por HLL y HLL++.&lt;/p&gt;

&lt;p&gt;En un entorno en el que se generan grandes cantidades de datos por segundo, este tipo de algoritmos son muy útiles para obtener métricas actualizadas en tiempo real como puedan ser los visitantes diarios a una página web, para estimar cuántas palabras únicas hay en la literatura mundial o para detectar anomalías en un dispositivo IoT que emita señales constantemente.&lt;/p&gt;

&lt;p&gt;Referencias:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;[1] Probabilistic Counting Algorithms for Data Base Applications: &lt;a href="https://algo.inria.fr/flajolet/Publications/FlMa85.pdf"&gt;https://algo.inria.fr/flajolet/Publications/FlMa85.pdf&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[2] LogLog Counting of Large Cardinalities: &lt;a href="https://algo.inria.fr/flajolet/Publications/DuFl03-LNCS.pdf"&gt;https://algo.inria.fr/flajolet/Publications/DuFl03-LNCS.pdf&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[3] HyperLogLog: the analysis of a near-optimal cardinality estimation algorithm: &lt;a href="https://algo.inria.fr/flajolet/Publications/FlFuGaMe07.pdf"&gt;https://algo.inria.fr/flajolet/Publications/FlFuGaMe07.pdf&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[4] HyperLogLog in Presto: A significantly faster way to handle cardinality estimation: &lt;a href="https://engineering.fb.com/2018/12/13/data-infrastructure/hyperloglog/"&gt;https://engineering.fb.com/2018/12/13/data-infrastructure/hyperloglog/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[5] HyperLogLog | Redis: &lt;a href="https://redis.io/docs/data-types/probabilistic/hyperloglogs/"&gt;https://redis.io/docs/data-types/probabilistic/hyperloglogs/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[6] Using HyperLogLog sketches in Amazon Redshift: &lt;a href="https://docs.aws.amazon.com/en_gb/redshift/latest/dg/hyperloglog-overview.html"&gt;https://docs.aws.amazon.com/en_gb/redshift/latest/dg/hyperloglog-overview.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[7] LOGLOG counting for the estimation of IP traffic: &lt;a href="https://dmtcs.episciences.org/3503/pdf"&gt;https://dmtcs.episciences.org/3503/pdf&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[8] HyperLogLog in Practice: Algorithmic Engineering of a State of The Art Cardinality Estimation Algorithm: &lt;a href="https://static.googleusercontent.com/media/research.google.com/es//pubs/archive/40671.pdf"&gt;https://static.googleusercontent.com/media/research.google.com/es//pubs/archive/40671.pdf&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[9] Unique count approximation in Google Analytics: &lt;a href="https://developers.google.com/analytics/blog/2022/hll?hl=en"&gt;https://developers.google.com/analytics/blog/2022/hll?hl=en&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[10] LogLog-Beta and More: A New Algorithm for Cardinality Estimation Based on LogLog Counting: &lt;a href="https://arxiv.org/ftp/arxiv/papers/1612/1612.02284.pdf"&gt;https://arxiv.org/ftp/arxiv/papers/1612/1612.02284.pdf&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Este post fue publicado antes en &lt;a href="https://medium.com/p/2b1dacd14b33"&gt;Medium&lt;/a&gt;&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>computerscience</category>
      <category>bigdata</category>
      <category>spanish</category>
    </item>
  </channel>
</rss>
