Experimentación y evidencia: dos visiones opuestas

Anteriormente, hablábamos de estándares de evidencia científica y del problema filosófico de la inferencia inductiva; de cómo Ronald Fisher, hace un siglo, promovió métodos —como los contrastes de hipótesis— que evaden el problema, y adelantábamos que dichos métodos suponen una aproximación frecuentista a la realidad. A continuación abundaremos en el problema metodológico que plantean la medida y la estimación estadística de la (in)certidumbre, y que tiene su raíz en el concepto mismo de probabilidad. Esto da lugar a dos visiones opuestas aunque, como veremos, estrechamente relacionadas, lo que en estadística se denomina frecuentismo vs. bayesianismo.

Sigue leyendo Experimentación y evidencia: dos visiones opuestas, mi última colaboración en el Cuaderno de Cultura Científica.

simmer 4.2.1

The 4.2.1 release of simmer, the Discrete-Event Simulator for R, is on CRAN with quite interesting new features and fixes. As discussed in the mailing list, there is a way to handle the specific case in which an arrival is rejected because a queue is full:

library(simmer)

reject <- trajectory() %>%
  log_("kicked off...")

patient <- trajectory() %>%
  seize("nurse", continue=FALSE, reject=reject) %>%
  log_("nurse seized") %>%
  timeout(5) %>%
  release("nurse") %>%
  log_("nurse released")

env <- simmer() %>%
  add_resource("nurse", 1, 0) %>%
  add_generator("patient", patient, at(0, 1)) %>%
  run()
## 0: patient0: nurse seized
## 1: patient1: kicked off...
## 5: patient0: nurse released

But as Tom Lawton pointed out, until now, there was no way of handling any alternative path for an arrival that was preempted and “kicked off” from a resource. This mechanism has been implemented into the new handle_unfinished() activity:

patient <- trajectory() %>%
  handle_unfinished(reject) %>%
  seize("nurse") %>%
  log_("nurse seized") %>%
  timeout(5) %>%
  release("nurse") %>%
  log_("nurse released")

env <- simmer() %>%
  add_resource("nurse", 1, 0, preemptive=TRUE, queue_size_strict=TRUE) %>%
  add_generator("LowPrio_patient", patient, at(0), priority=0) %>%
  add_generator("HighPrio_patient", patient, at(1), priority=10) %>%
  run()
## 0: LowPrio_patient0: nurse seized
## 1: HighPrio_patient0: nurse seized
## 1: LowPrio_patient0: kicked off...
## 6: HighPrio_patient0: nurse released

Note that such a mechanism is more general, because it also covers the first scenario:

env <- simmer() %>%
  add_resource("nurse", 1, 0) %>%
  add_generator("patient", patient, at(0, 1)) %>%
  run()
## 0: patient0: nurse seized
## 1: patient1: kicked off...
## 5: patient0: nurse released

Whenever rejection (or preemption) happens and it is catched by the appropriate handler, the new getter get_seized() may be useful to know which resource was abandoned.

Finally, the readership may find interesting the new section about the implementation of state-dependent service rates in the Queueing Systems vignette. See below for a complete list of changes.

New features:

  • New handle_unfinished() activity sets a drop-out trajectory for unfinished arrivals, i.e., those dropped from a resource (due to preemption, resource shrinkage or a rejected seize) or those that leave a trajectory (#178 addressing #177).
  • New release_all() and release_selected_all() activities automatically retrieve the amount of resources seized and release it (#180 addressing #25).
  • New get_seized() and get_seized_selected() getters allow an arrival to retrieve the amount of resources seized (#180 addressing #179).
  • New stop_if() activity sets a conditional breakpoint (#181 addressing #100).

Minor changes and fixes:

  • Fix performance issues in data sources (#176).
  • Update CITATION.
  • Fix monitored activity for preempted arrivals (as part of #178).
  • Fix seizes/releases with a null amount (as part of #180).
  • Rename internal status codes (as part of #181).
  • Provide more context on error or warning (as part of #181).
  • Extend the Queueing Systems vignette with a section about state-dependent service rates.
  • Fix performance issues in getters (#183).

Cómo comprobar tus contraseñas

Ayer saltó la noticia de que circula una colección de 773 millones de pares email-contraseña denominada «Collection #1». Troy Hunt, creador del servicio Have I Been Pwned (HIBP), describía cómo, tras la oportuna limpieza y deduplicación de datos, esta colección añadía unas 20 millones de nuevas contraseñas a HIBP para hacer un total de algo más de 550 millones de contraseñas únicas entre todas las filtraciones que ha ido incorporando con el tiempo.

Al final, parece que esta filtración proviene de muchas fuentes distintas que tienen años de antigüedad, por lo que no habría de qué preocuparse en principio. No obstante, la alarma me ha servido para volver a pasarme por HIBP —un servicio en el que puedes registrar tu email para recibir un aviso si aparece en alguna filtración—, y he podido comprobar que han añadido la muy interesante funcionalidad de buscar contraseñas de manera segura para comprobar si están en su base de datos de filtraciones.

La cosa funciona de la siguiente manera. Cogemos una contraseña que queramos consultar (por ejemplo, 123456) y le pasamos la función hash SHA-1:

SHA1(123456) = 7c4a8d09ca3762af61e59520943dc26494f8941b

En principio, no podemos volver a «123456» a partir de ese churro, pero tampoco sería seguro que sepan que andamos preguntando por ese hash. Así que lo que hacemos es coger los primeros 5 caracteres y se los pasamos a la API de HIBP (así: 7c4a8), y la API nos devuelve todos los hashes que empiezan por esos 5 caracteres (que son muchos, típicamente cientos). Y en esa lista, ya manejable, nosotros podemos comprobar si el resto del hash (en definitiva, la contraseña que queremos consultar) está ahí.

Esto es exactamente lo que hace el formulario online (lo he comprobado), con el JavaScript que tiene detrás, de modo que es seguro utilizarlo.

123456, cómo no…

Si aun así no os fiais, en tres líneas de Bash se puede implementar lo mismo:

#!/bin/bash
read -s -p "Password: " PASS; echo
PASS=$(echo -n $PASS | sha1sum - | cut -d" " -f1)
wget "https://api.pwnedpasswords.com/range/${PASS:0:5}" -q -O - | grep -i "${PASS:5}"

Si ese grep saca algo… malo.

The difference that matters: Paul Romer sobre ciencia y software libre

Me permito dejar por aquí un extracto de este artículo de Paul Romer que resume perfectamente el valor del modelo de software libre y cómo se parece al de la ciencia:

This technical engineering dimension is not the only one we should use to compare the proprietary and open models. There is an independent social dimension, where the metrics assess the interactions between people. Does it increase trust? Does it increase the importance that people attach to a reputation for integrity?

It is along this social dimension that open source unambiguously dominates the proprietary model. Moreover, at a time when trust and truth are in retreat, the social dimension is the one that matters. […]

Membership in an open source community is like membership in the community of science. There is a straightforward process for finding a true answer to any question. People disagree in public conversations. They must explain clearly and listen to those who response with equal clarity. Members of the community pay more attention to those who have been right in the past, and to those who enhance their reputation for integrity by admitting in public when they are wrong. They shun those who mislead. There is no court of final appeal. The only recourse is to the facts.

It’s a messy process but it works, the only one in all of human history that ever has. No other has ever achieved consensus at scale without recourse to coercion.

In science, anyone can experiment. In open source, anyone can access the facts of the code. Linus Torvalds may supervise a hierarchy that decides what goes into the Linux kernel, but anyone can see what’s there. Because the communities of science and open source accept facts as the ultimate source of truth and use the same public system for resolving disagreements about the facts, they foster the same norms of trust grounded in individual integrity.

El legado de Fisher y la crisis de la ciencia

En 2005, John Ioannidis, prestigioso profesor de medicina de la Universidad de Stanford, publicó uno de los artículos más citados e influyentes de la literatura científica: Why Most Published Research Findings are False (Por qué la mayor parte de los resultados de investigación son falsos). Posteriormente, se acuñó el término “crisis de replicabilidad” para referirse al hecho de que un gran número de estudios científicos (especialmente en ciencias sociales y medicina) no han podido ser replicados, algo fundamental en ciencia. Este problema ha saltado a la opinión pública en diversas ocasiones, como cuando en mayo de 2016 una encuesta de la revista Nature desvelaba que el 90% de los científicos reconocen que esta crisis existe.

Sigue leyendo El legado de Fisher y la crisis de la ciencia, mi última colaboración en el Cuaderno de Cultura Científica.