Introducción
En este desafío, se le proporciona una lista de números de punto flotante no negativos extraídos independientemente de alguna distribución de probabilidad. Su tarea es inferir esa distribución de los números. Para que el desafío sea factible, solo tiene cinco distribuciones para elegir.
U
, la distribución uniforme en el intervalo [0,1].T
, la distribución triangular en el intervalo [0,1] con el modo c = 1/2.B
, la distribución beta en el intervalo [0,1] con los parámetros α = β = 1/2.E
, la distribución exponencial en el intervalo [0, ∞) con tasa λ = 2.G
, la distribución gamma en el intervalo [0, ∞) con los parámetros k = 3 y θ = 1/6.
Tenga en cuenta que todas las distribuciones anteriores tienen una media exacta de 1/2.
La tarea
Su entrada es una matriz de números de punto flotante no negativos, de longitud entre 75 y 100 inclusive. Su salida será una de las letras UTBEG
, en función de cuál de las distribuciones anteriores se adivinan los números.
Reglas y puntuación
Puede dar un programa completo o una función. Las lagunas estándar no están permitidas.
En este repositorio , hay cinco archivos de texto, uno para cada distribución, cada uno de exactamente 100 líneas de largo. Cada línea contiene una lista delimitada por comas de 75 a 100 flotadores dibujados independientemente de la distribución y truncados a 7 dígitos después del punto decimal. Puede modificar los delimitadores para que coincidan con el formato de matriz nativo de su idioma. Para calificar como respuesta, su programa debe clasificar correctamente al menos 50 listas de cada archivo . La puntuación de una respuesta válida es el recuento de bytes + el número total de listas mal clasificadas . El puntaje más bajo gana.
Respuestas:
Julia,
6062 bytes +252 errores =8264Esto es bastante simple. La varianza para las distribuciones es en su mayoría diferente: es 1/4 para exponencial, 1/8 para beta, 1/12 para gamma y uniforme, y 1/24 para triangular. Como tal, si usamos la varianza (aquí se usa
std
para la desviación estándar, la raíz cuadrada de la varianza) para determinar la distribución probable, solo tenemos que hacer más para distinguir gamma de uniforme; para eso, buscamos un valor mayor que 1 (usandoany(k.>1)
); dicho esto, verificamos tanto exponencial como gamma, ya que mejora el rendimiento general.Para guardar un byte, se indexa la cadena en
"EGTBU"
lugar de evaluar directamente una cadena dentro de los condicionales.Para la prueba, guarde los archivos txt en un directorio (manteniendo los nombres tal como están) y ejecute Julia REPL en ese directorio. Luego, adjunte la función a un nombre como
y use el siguiente código para automatizar las pruebas (esto se leerá del archivo, se convertirá en una matriz de matrices, usará la función y la salida para cada falta de coincidencia):
La salida consistirá en filas que contienen el caso que no coincide, la distribución correcta -> la distribución determinada y la varianza calculada (por ejemplo,
13 G->E 0.35008999281668357
significa que la 13ª fila en G.txt, que debería ser una distribución gamma, se determina como exponencial distribución, con una desviación estándar de 0.35008999 ...)Después de cada archivo, también muestra el número de discrepancias para ese archivo, y luego al final también muestra las discrepancias totales (y debería leer 2 si se ejecuta como se indica arriba). Por cierto, debe tener 1 falta de coincidencia para G.txt y 1 falta de coincidencia para U.txt
fuente
R,
202 192 184 182 162154 bytes + 0 erroresEsto se basa en la fórmula bayesiana P (D = d | X = x) = P (X = x | D = d) * P (D = d) / P (X = x), donde D es la distribución y X es la muestra aleatoria Escogemos la d tal que P (D = d | X = x) es la mayor de las 5.
Supongo que un anterior plano (es decir, P (D = di) = 1/5 para i en [1,5]), lo que significa que P (D = d) en el numerador es el mismo en todos los casos (y el denominador sería ser el mismo en todos los casos de todos modos), por lo que podemos golf todo menos P (x = X | D = d), que (excepto la distribución triangular) se simplifica a funciones nativas en R.
sin golf:
Tenga en cuenta que la versión no golfizada no es exactamente equivalente a la versión golfizada porque al deshacerse del denominador se evita el caso de Inf / Inf que ocurre si permite que la distribución beta esté sobre el intervalo cerrado [0,1] en lugar de (0, 1) - como lo hacen los datos de muestra. Una declaración if adicional manejaría eso, pero dado que es solo para fines ilustrativos, probablemente no valga la pena agregar la complejidad que no está en el corazón del algoritmo.
Gracias @Alex A. por reducciones de código adicionales. Especialmente para cual.max!
fuente
{
y el anterior al cierre}
, y aliasprod
, por ejemploP=prod
, luego haciendoP(dunif(x))
, etc. La función no necesita un nombre para ser un envío válido, por lo que puede eliminarp=
. Además, excelente trabajo. :)which.max(c(u,r,b,e,g))
en lugar dec(u,r,b,e,g)==max(c(u,r,b,e,g))
.function(x){c("U","T","B","E","G")[which.max(lapply(list(dunif(x),sapply(x,function(y)max(0,2-4*abs(.5-y))),dbeta(x,.5,.5),dexp(x,2),dgamma(x,3,6)),prod))]}
CJam, 76
El código fuente tiene 43 bytes de largo y clasifica erróneamente 33 listas.
Verificación
Idea
Es fácil diferenciar la distribución exponencial y gamma de las restantes, ya que son las únicas distribuciones que toman valores mayores que 1 .
Para decidir entre gamma , exponencial y otros, observamos el segundo valor más alto de la muestra.
Si se encuentra en [1.5, ∞) , suponemos gamma .
Si se encuentra en [1, 1.5) , suponemos exponencial .
Si se encuentra en [0, 1) , tenemos tres posibilidades restantes.
Las distribuciones restantes se pueden diferenciar por el porcentaje de valores de muestra que se encuentran cerca de la media ( 0.5 ).
Dividimos la longitud de la muestra por el recuento de valores que se encuentran en (0.3, 0.7) y observamos el cociente resultante.
Si se encuentra en (1, 2] , suponemos triangular .
Si se encuentra en (2, 3] , suponemos uniforme .
Si se encuentra en (3, ∞) , suponemos beta .
Código
fuente
Matlab,
428328bytes + 33 mal clasificadosEste programa básicamente compara el CDF real con uno estimado dados los datos, y luego calcula la distancia media entre esos dos: creo que la imagen explica más:
Los datos que se muestran en esta imagen aquí muestran con bastante claridad que pertenece a la distribución turquesa, ya que está bastante cerca de esa, así que eso es básicamente lo que está haciendo mi programa. Probablemente se pueda jugar un poco más. Para mí eso fue ante todo un desafío conceptual, no muy golfista.
Este enfoque también es independiente de los archivos PDF elegidos, funcionaría para cualquier conjunto de distribuciones.
El siguiente código (no protegido) debería mostrar cómo se hace. La versión de golf está abajo.
Versión totalmente golfizada:
fuente
Perl, 119 bytes + 8 clasificaciones erróneas = 127
Hice un pequeño árbol de decisiones sobre tres características:
Invocado con
perl -F, -lane -e '...'
. No estoy seguro de si debo agregar una penalización por los parámetros no estándar. Si las comas fueran espacios, supongo que podría haber escapado sin -F,La salida ligeramente formateada (sin el indicador -l) es:
fuente
Python, 318 bytes + 35 clasificaciones erróneas
Idea: la distribución se adivina en función del valor p de la prueba de Kolmogorov-Smirnov.
Prueba
fuente