5 puntos por GN⁺ 2025-05-02 | 1 comentarios | Compartir por WhatsApp
  • Al crear hn.unlurker.com, incorporé en el cliente de la API de HN una función scan que obtiene todos los items en orden, y descargué todos los datos de Hacker News en local
  • Durante la ejecución de hn scan --no-cache --asc -c- -o full.json, la descarga se detuvo varias veces, pero gracias al scan reanudable, unas horas después obtuve un archivo JSON de 20 GiB
  • Tras convertir el JSON en una tabla con read_json_auto de DuckDB, agregué la proporción de menciones de Python, JavaScript, Java, Ruby y Rust usando SQL con text ILIKE y promedio móvil de 12 semanas
  • Incluso con un simple grep, confirmé que la frase “correct horse battery staple” apareció 231 veces en Hacker News, y DuckDB parece encajar muy bien para análisis puntuales a esta escala
  • Cuando se tiene todo el conjunto de datos en local, se puede analizar el contenido histórico de Hacker News de muchas formas, pero este proyecto termina aquí y los próximos pasos quedan para que alguien más los continúe

Descargar todos los items de Hacker News

  • Para crear hn.unlurker.com, escribí un cliente de la API de HN
    • Ya existían varios clientes, pero quería probar funciones recientes de Go y linters en un proyecto nuevo
    • En la API de HN, los comentarios y las historias se llaman items
  • El cliente puede obtener items activos y listas de items, entre otras cosas
    • Para el proyecto real solo necesitaba items recientes, pero para hacerlo más completo agregué la función scan
    • scan descarga los items en orden, desde 0 hasta el más reciente o en la dirección opuesta
  • Estimé que la descarga completa no serían decenas de miles de GiB, sino apenas decenas de GiB de JSON, así que lo intenté
hn scan --no-cache --asc -c- -o full.json
  • La descarga se detuvo varias veces y la interrumpí con CTRL-C, pero como scan es reanudable, se completó unas horas después
  • El resultado es un archivo JSON de 20 GiB que contiene todo lo ocurrido en Hacker News
  • Si se ejecuta de nuevo el mismo comando, se puede rellenar nuevamente con los datos más recientes

Analizar los datos locales con DuckDB

  • Al principio busqué simplemente con grep
    • La frase “correct horse battery staple” apareció 231 veces en Hacker News
    • El último caso de aparición fue un item publicado “hoy” al momento de escribir
  • Después intenté analizarlo con DuckDB
    • DuckDB es un motor de ejecución analítica rápido y embebible, y también se ofrece como herramienta de línea de comandos
    • Gracias a su nueva UI fue fácil de usar incluso para principiantes, y un LLM ayudó a escribir consultas SQL
  • Los datos JSON se importan en DuckDB de la siguiente manera
CREATE TABLE items AS
SELECT *
FROM read_json_auto('/home/jason/full.json', format='nd', sample_size=-1);
  • La consulta de ejemplo agrupa los items por semana y calcula la proporción de items que contienen una palabra específica sobre el total de items
    • Busca python, javascript, java, ruby y rust con text ILIKE
    • Calcula un promedio móvil de 12 semanas para cada proporción
  • Con el mismo método también visualicé palabras relacionadas con bases de datos
    • El gráfico de ejemplo incluye la proporción de menciones con promedio móvil de 12 semanas de mysql, postgres, mongo, redis y sqlite
  • DuckDB pareció muy bueno para analizar un dataset de este tamaño
  • Aunque ahora tengo una copia local de todo el contenido de Hacker News, decidí terminar el proyecto aquí

1 comentarios

 
GN⁺ 2025-05-02
Comentarios de Hacker News
  • Conozco dos bases de datos con tablas actualizadas de Hacker News que permiten correr análisis sin tener que descargarlas primero.
    BigQuery requiere una cuenta de Google Cloud, y las consultas probablemente se pueden hacer dentro del nivel gratuito; hay que usar bigquery-public-data.hacker_news.full.
    ClickHouse no requiere registrarse y permite ejecutar consultas directamente desde el navegador: https://play.clickhouse.com/play?user=play#U0VMRUNUICogRlJPT...

  • Hace tiempo hice algo parecido con la cuenta @fesshole de Twitter/Bluesky. Descargué todo el archivo y ajusté finamente un modelo para que generara confesiones todavía más desquiciadas.
    Me sentía bastante orgulloso, hasta que me di cuenta de que al final lo único que había hecho era enseñarle masturbación y divorcio a una máquina inocente.
    Era como esas escenas de películas de ciencia ficción en las que un alienígena o una IA superinteligente ve la historia de la humanidad a toda velocidad y concluye que no vale la pena salvarnos.

    • Sobre la parte de “masturbación y divorcio a una máquina inocente”: supongamos que encontramos un pendrive de una civilización desaparecida hace mucho y entrenamos un modelo con esos datos de texto.
      Si no hay ninguna conexión con el mundo exterior respecto de esos datos, ¿cómo podría una persona o el modelo saber que ese pendrive contiene datos sobre masturbación y divorcio?
    • No veo qué problema hay con la masturbación y el divorcio. Cada uno es una forma de que la gente pueda vivir de manera más feliz e independiente, y de salir de situaciones que no funcionan.
      En general veo ambas cosas como positivas, y agradezco poder vivir en una sociedad donde están normalizadas.
  • La consulta de Java también incluye todos los casos de JavaScript, así que Java queda sobremuestreado.

    • Del mismo modo, una consulta de Rust terminaría incluyendo un montón de palabras como trust, antitrust y frustration.
    • Sí… entonces quizá sea aún más inesperado que se vea una tendencia a la baja.
  • Que haya existido un archivo JSON de 20 GiB con todo lo ocurrido en Hacker News resulta sorprendentemente grande si se piensa que es un sitio solo de texto.
    ¿Significa que, en los 18 años de existencia de HN, la gente publicó más de 20 mil millones de bytes de texto? Eso da un promedio de más de 2 MB por día, unos 7.5 KB por segundo.

    • 2 MB al día no parece tanto. Sobre todo porque, después de lo de Reddit, con el “septiembre interminable” más reciente y más grande, es probable que la cantidad de publicaciones haya crecido exponencialmente a lo largo de varios años.
      Además, una buena parte de eso probablemente no sea humana. /newest está lleno de spam de bots.
    • 7.5 KB/s, es decir, 7500 caracteres por segundo, no sonaba realista, así que hice el cálculo[0], y en realidad está más cerca de unos 34 bytes por segundo, o sea 0.03 KB/s.
      Como incluye también los metadatos y la sintaxis de JSON, la cantidad real de texto sería todavía menor. El cálculo de “más de 2 MB al día” sí estaba bien.
      [0] En realidad el cálculo lo hizo ChatGPT, pero parece correcto: https://chatgpt.com/share/68124afc-c914-800b-8647-74e7dc4f21...
    • El archivo completo de Reddit, poco antes de que quitaran la API, ocupaba unos 4 TB comprimido. Antes estaba alojado en the-eye y, si quieres, todavía hay lugares donde se pueden descargar esos archivos por torrent.
      Mucho de eso es basura, pero los datos iniciales, sobre todo antes de 2018~2019, cuando aparecieron bots más inteligentes, parecen dignos de revisar.
    • Lo de 20 GB en JSON es sorprendente. Tengo un archivo SQLite con todos los datos de HN y ocupa 20 GB, así que pensaría que en JSON tendría que ser mucho más grande.
    • El tamaño total, más bien, se siente pequeño. Es el resultado de casi 20 años de aportes de cientos de miles de miembros activos y de varios millones de personas en total.
      Según los estándares previos a Facebook, HN habría sido una red social bastante grande, y al tener un tamaño manejable y estar moderada activamente, también es bastante valiosa.
      En 2019, cuando cerró Google+, modelé cuántos datos de texto se habían aportado a ese sitio.
      Aquí, datos de texto excluye medios como imágenes, audio y video, además de elementos auxiliares de página como la estructura HTML, CSS y JS.
      Considerando que la tasa de participación era muy baja y que el promedio de una publicación era de unos 120 caracteres, incluso siete años de historial de decenas de millones de cuentas activas apenas sumaban unos pocos GiB. Había más de 4 mil millones de perfiles registrados, pero la actividad real era mucho menor.
      Archive Team, en colaboración con Internet Archive pero de forma independiente, trabajó en preservar Google+, con resultados mixtos. Se conservó mucho contenido, pero se perdió muchísimo más; casi no quedaron comentarios, los hilos se recortaron a unos 10 elementos recientes y, al no haber búsqueda, en general era poco útil. Las “vanity accounts”, que usaban nombres de cuenta elegidos en lugar de hashes aleatorios, tenían una accesibilidad aún peor.
      Además, al intentar scrapear páginas completas para reproducir la forma en que se veían en línea, aumentaron mucho los requisitos de almacenamiento, mientras se perdían muchos de los elementos que realmente hacían interesante al sitio.
      Incluso cuando se quiere almacenar la contribución textual de grandes poblaciones, los requisitos de almacenamiento son bastante modestos. Por ejemplo, si una persona pasa en línea 45 minutos al día en promedio, escribe a 45 wpm y dedica la mitad del tiempo en línea a escribir en vez de leer, eso serían unas 1,000 palabras por persona por día, es decir, unos 6 KiB. Serían 6 MiB por cada 1,000 personas, 6 GiB por cada millón y unos 6 PiB por cada mil millones.
      El valor real casi con seguridad es menor. El tiempo dedicado a escribir está sobreestimado y probablemente se acerque más al 10%; además, la velocidad de entrada en móviles probablemente sea de unos 20~30 wpm. Por ejemplo, en Facebook se suben unos 2,450 millones de “piezas de contenido” al día, y la mitad son videos. Si se supone un promedio de 120 caracteres por publicación, los datos de texto son una cantidad sorprendentemente pequeña, muy por debajo de 300 GiB diarios.
      La mayor parte de los sistemas actuales de recopilación de datos y capitalismo de vigilancia consiste en datos que las personas no introducen directamente, como ubicación, video, interacciones en línea y comercio.
  • ¿Cuál sería la netiqueta para descargar HN? ¿Habría que preguntarle primero a dang antes de cargar los servidores?
    ¿O podemos asumir que empresas tecnológicas de miles de millones de dólares ya lo han hecho muchas veces y ni se va a notar?

    • Como dice el artículo, HN tiene una API, e incluso sin límite de velocidad. Todos los datos están alojados en Firebase, una empresa de YC, así que está bien.
    • Literalmente hay una base de datos pública.
      https://console.cloud.google.com/marketplace/product/y-combi...
    • Tampoco se puede descartar que agencias de tres letras estén asociando alias de HN con nombres reales.
    • Se llama Hacker News, así que, al menos en el buen sentido de hackear, es juego limpio.
    • Si está en la web pública, ya hay miles de bots scrapeándolo.
  • Hice algo parecido. Usé un truco con el dataset de BigQuery; por alguna razón se seguía actualizando, así que exporté los datos a Parquet, los descargué y los consulté con DuckDB.

    • Eso no es un truco, es simplemente una opción práctica.
  • “Ahora que descargamos localmente todo el contenido de Hacker News, podemos entrenar cientos de bots basados en LLM para ponerlos a contribuir y reemplazar lenta e inevitablemente todo texto humano con la salida de un vibrador de habitación china que haga eco y recicle el pasado para siempre” es una broma, pero me da miedo que algún día alguien lo intente.
    Espero que no pase, pero si pasa, ¿podremos impedirlo?

    • Cada vez creo más en una idea antigua que se vuelve más importante con el tiempo: crear una red de confianza entre humanos, de modo que una cuenta quede verificada por una ruta en la que alguien que no conozco confía en ella, esa persona es de confianza para alguien que sí conozco, y esa persona a su vez es de mi confianza.
      Hay muchos problemas por resolver, y la privacidad es uno de ellos. No hace falta exponer las conexiones a los usuarios, pero en una implementación ingenua quedarían en el servidor.
      También podrían agregarse rutas de desconfianza con peso negativo. Si desconfío de alguien directa o indirectamente, baja el valor de la cadena de confianza que conecta a esa persona conmigo.
      Como es una red, el sistema podría ajustarse por sí solo ante intentos de manipularlo, pero qué tan robusto sería sigue siendo una pregunta abierta.
    • ¿Cómo sabemos que no está ocurriendo ya?
      Los comentarios largos y con contenido normalmente se pueden distinguir, pero se ha vuelto mucho más difícil que hace 1 o 2 años. Si se trata de comentarios cortos de una o dos frases, creo que los LLM ya son lo bastante buenos como para pasar por humanos.
    • Nuestros LLM solo pueden dar resultados verificados en varias fuentes, así que solo producen la respuesta promedio de los humanos.
      En cambio, muchos comentarios de HN son insights bastante únicos que se apartan del pensamiento popular promedio. Si un LLM intenta imitar eso, solo terminará diciendo tonterías.
      Si se le agrega un filtro que solo deje pasar respuestas razonables y coherentes a esas tonterías, las respuestas se volverán aburridas y seguirán estando cerca de ser tonterías.
      Para que las respuestas sean correctas, precisas y únicas, hay que usar algo que no sea un LLM.
    • HN ya tiene un sistema inmunológico bastante bueno contra este tipo de cosas. Los comentarios de bajo esfuerzo y repetitivos reciben downvotes, reportes y límites de velocidad rápidamente.
      Las heurísticas de karma y velocidad del sitio son rudimentarias comparadas con el machine learning sofisticado, pero funcionan porque la comunidad es pequeña frente a Reddit o Twitter y porque los moderadores intervienen directamente.
      Para que una banda de cuentas falsas con LLM “reemplace” el texto humano, tendría que seguir publicando cosas que la gente realmente encuentre interesantes. Si no, mucho antes las limitarían o las eliminarían silenciosamente.
      Incluso mantener vivas unas cuantas cuentas de IA tiene un alto costo marginal. Ejecutar inferencias en decenas de hilos nuevos las 24 horas no es gratis, y evitar que la salida se deslice hacia la basura SEO genérica es sorprendentemente difícil.
      Además, prácticamente no hay beneficio. No se puede monetizar el tráfico de HN, y el karma es una moneda pésima para los operadores de bots.
      ¿Se podría frenar a un actor malicioso persistente y con recursos? Probablemente sí, pero las contramedidas serían las mismas de ahora: límites de velocidad fuertes, topes más estrictos para cuentas nuevas, revisión por moderadores humanos y quizá algo de análisis de estilo.
      Para los usuarios nuevos legítimos sería molesto, pero no fatal. Al final, HN sobrevive porque los humanos que están aquí quieren leer lo que escriben otros humanos. Si los comentarios empiezan a sonar como loros probabilísticos, los lectores los ignorarán o reportarán, y los bots terminarán hablándose entre sí.
      Escrito por GPT-3o.
    • Ya hubo cosas que anticiparon esta tendencia, como la franquicia Metal Gear[0] y la teoría de Internet muerto[1].
      “El ambicioso guion de Hideo Kojima en Metal Gear Solid 2 ha sido considerado uno de los primeros ejemplos de videojuego posmoderno, y también se le ha reconocido haber anticipado conceptos como la política de la posverdad, las noticias falsas, las cámaras de eco y los hechos alternativos”.
      [0] https://en.wikipedia.org/wiki/Metal_Gear
      [1] https://en.wikipedia.org/wiki/Dead_Internet_theory
  • Creo que en los próximos años muchas API empezarán a ofrecer la opción de devolver simplemente un archivo DuckDB.
    Si de todos modos vas a cargar el JSON en una base de datos, no hay razón para no recibir una base de datos como respuesta.

    • zstd Parquet exportado desde un archivo de DuckDB 1.2 comprime 2 a 3 veces mejor.
  • Ojalá no usaran gráficos acumulados. Creo que es casi imposible no distorsionar la impresión del lector.
    Es muy difícil estimar la altura de un punto de datos específico entre el ruido, y además sugieren dependencias que probablemente no existan.

    • Eso fue lo primero que pensé también. El autor de uPlot tiene una demo que muestra bien la trampa: https://leeoniya.github.io/uPlot/demos/stacked-series.html
    • Es cierto :( Pero al graficar los mismos datos como gráfico de líneas, se superponían tanto que era difícil ver algo.
      Para la próxima estoy considerando apilar varios gráficos de líneas, cada uno con una sola serie por región.
    • Ahí es donde un enfoque 3D resuelve este problema. Si apilas con un pequeño desplazamiento, no hay nada mejor para entender grandes volúmenes de datos de una sola vez usando tecnología de motores de juego en inteligencia de negocios real.
      Basta ver el trabajo de https://flowimmersive.com/.
    • ¿Qué opinan de los gráficos acumulados con eje y logarítmico? Algunos experimentos físicos siempre se muestran así[1], pero me parece bastante poco intuitivo.
      [1]: https://atlas.web.cern.ch/Atlas/GROUPS/PHYSICS/PUBNOTES/ATL-...
  • Hace tiempo hice uno, https://github.com/ashish01/hn-data-dumps, y fue bastante divertido
    Una funcionalidad que sería genial implementar es reflejar que, como los elementos más recientes se actualizan con más frecuencia con el paso del tiempo, los elementos descargados recientemente se convierten en caché obsoleta más rápido que los elementos antiguos.

    • Es realmente genial que HN ofrezca una API así sin bloquearla, a diferencia de muchos otros sitios.
      Yo usé una función basada en la edad para determinar la obsolescencia. Al principio la considera obsoleta a partir de 1 o 2 minutos después de su creación; luego la actualiza con frecuencia durante varios días, y después de la primera semana reduce rápidamente la frecuencia hasta tratarla como inmutable tras unas 2 semanas.
      // DefaultStaleIf marks stale at 60 seconds after creation, then frequently for the first few days after an item is
      // created, then quickly tapers after the first week to never again mark stale items more than a few weeks old.
      const DefaultStaleIf = "(:now-refreshed)>" +
      "(60.0*(log2(max(0.0,((:now-Time)/60.0))+1.0)+pow(((:now-Time)/(24.0*60.0*60.0)),3)))"
      https://github.com/jasonthorsness/unlurker/blob/main/hn/core...