Prueba de Validación

Introducción
Las pruebas de validación de números pseudoaleatorios permiten verificar si una secuencia generada cumple con las propiedades estadísticas de la aleatoriedad. La prueba de Kolmogorov-Smirnov compara la distribución acumulada de los números generados con la distribución teórica uniforme. Los Run tests analizan la secuencia de números para detectar patrones o repeticiones, evaluando la independencia entre ellos. La prueba Poker examina grupos de dígitos para verificar si las frecuencias de combinaciones siguen las esperadas en un comportamiento aleatorio. Estas pruebas ayudan a determinar la calidad y confiabilidad de un generador de números pseudoaleatorios.

1. Prueba de Kolmogorov-Smirnov

Es una prueba no paramétrica que mide la máxima diferencia entre la distribución acumulada empírica de los datos y la distribución acumulada teórica (en este caso, uniforme).
Permite verificar si los números generados siguen efectivamente la distribución uniforme esperada.
Uso en R:
x <- runif(1000) ks.test(x, “punif”, 0, 1)

Ejemplo: Pruebas estadísticas para validez de los geneadores de números Pseudoaleatorios (GNP)
Para la validez estadística de los GNP, vamos a generar 50 números Pseudoaleatorios con el método congruencial lineal mixto. probaremos la aleatoriedad mediante la prueba χ2 y la prueba de kolmogorov-Smirnoff , y para la prueba de independencia estadística aplicaremos las pruebas de las Corridas.

Generando los 50 números U_i Pseudoaleatorios con el método secuencial mixto

a <- 10400 
c <- 2567  
m <- 30439403
X_n <- 44 # semilla
random.number<-numeric(50) # vector numérico de longitud 50
 for (i in 1:50)
   {X_n<-(a*X_n+c)%%m
   random.number[i]<-X_n/m # números en el intervalo [0,1]
   }
 random.number
##  [1] 0.01511748 0.22185376 0.27918570 0.53135267 0.06783277 0.46088460
##  [7] 0.19989840 0.94345914 0.97514836 0.54305743 0.79736866 0.63415472
## [13] 0.20914280 0.08521330 0.21841128 0.47740601 0.02261122 0.15675938
## [19] 0.29765620 0.62455502 0.37230960 0.01993965 0.37242997 0.27179074
## [25] 0.62382593 0.78979558 0.87413436 0.99740777 0.04086966 0.04453083
## [31] 0.12075723 0.87528004 0.91254290 0.44621430 0.62883779 0.91313059
## [37] 0.55821328 0.41819979 0.27792004 0.36846639 0.05056180 0.84280207
## [43] 0.14166086 0.27302599 0.47033281 0.46132620 0.79252461 0.25603134
## [49] 0.72597288 0.11801536
# Probando si los U_i provienen de una uniforme [0,1]
test_ks <- ks.test(random.number,"punif",0,1)
test_ks
## 
##  Exact one-sample Kolmogorov-Smirnov test
## 
## data:  random.number
## D = 0.14259, p-value = 0.2376
## alternative hypothesis: two-sided
# Decision
 test_ks$p.value # P válido
## [1] 0.2375759
ifelse(test_ks$p.value < 0.05, " Los u_i no siguen una distribución uniforme","Los u_i siguen la distribución uniforme [0,1]") # 
## [1] "Los u_i siguen la distribución uniforme [0,1]"

De acuerdo a está prueba, se comprobó que los datos siguen una distribución uniforme.

2. Prueba de Run Test

Es una prueba no paramétrica que evalúa la secuencia de observaciones para determinar si el orden es aleatorio.
Detecta patrones de rachas de valores mayores o menores a la media, lo cual permite comprobar la independencia de los números generados.
Uso en R:
library(randtests) x <- runif(100) runs.test(x)

library(tseries)
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
diff(random.number) # halla la diferencia entre un valor y el otro en un vector
##  [1]  0.206736282  0.057331939  0.252166969 -0.463519899  0.393051828
##  [6] -0.260986196  0.743560739  0.031689222 -0.432090932  0.254311229
## [11] -0.163213943 -0.425011916 -0.123929500  0.133197980  0.258994731
## [16] -0.454794793  0.134148163  0.140896817  0.326898823 -0.252245420
## [21] -0.352369953  0.352490323 -0.100639227  0.352035189  0.165969648
## [26]  0.084338776  0.123273410 -0.956538110  0.003661176  0.076226396
## [31]  0.754522814  0.037262853 -0.466328594  0.182623490  0.284292796
## [36] -0.354917309 -0.140013488 -0.140279755  0.090546355 -0.317904592
## [41]  0.792240275 -0.701141215  0.131365126  0.197306826 -0.009006616
## [46]  0.331198414 -0.536493275  0.469941543 -0.607957521
S<-ifelse(diff(random.number) > 0, 1,0) # secuencia de ceros y unos
S
##  [1] 1 1 1 0 1 0 1 1 0 1 0 0 0 1 1 0 1 1 1 0 0 1 0 1 1 1 1 0 1 1 1 1 0 1 1 0 0 0
## [39] 1 0 1 0 1 1 0 1 0 1 0
runs.test(as.factor(S))
## 
##  Runs Test
## 
## data:  as.factor(S)
## Standard Normal = 1.5929, p-value = 0.1112
## alternative hypothesis: two.sided
# devuelve 1 si el número es mayor que el anterior y 0 en caso contrario.

# Detectar cambios
cambios <- abs(diff(S))

# Contar las corridas
corridas <- sum(cambios)+1
corridas
## [1] 30

Como resultado obtuvimos un total de 30 corridas

3. Prueba Poker

Los números pseudoaleatorios ui se agrupan en combinaciones de varios dígitos decimales (típicamente grupos de 5 decimales). Los grupos de dígitos se clasifican de manera similar a las manos en el juego de póker:

  1. Todo diferente (TD): Ningún decimal se repite en el grupo (Ej: 0.12345). la probabilidad de este evento es: P(TD)=0.3024

  2. Un par (1p): Un decimal aparece dos veces y los demás son diferentes (Ej: 0.14345). P(1p)=0.5040

  3. Dos pares (2p): Dos decimales aparecen dos veces cada uno (Ej: 0.14224). P(2p)=0.1080

  4. Tercia (T): Un decimal aparece tres veces, y los otros dos son diferentes (Ej:0.41443). P(T)=0.0720

  5. Full House (FH): Un dígito aparece tres veces y otro dígito dos veces (Ej: 0.32223). P(FH)=0.0090

  6. Poker (p): Un dígito aparece cuatro veces (Ej: 0.55515). P(p)=0.0045

  7. Quintilla: Todos los dígitos son iguales (Ej: 0.11111). P(Q)=0.0001

library(randtoolbox)
## Cargando paquete requerido: rngWELL
## This is randtoolbox. For an overview, type 'help("randtoolbox")'.
poker.test(random.number,nbcard=5)
## 
##           Poker test
## 
## chisq stat = 2.7, df = 4, p-value = 0.61
## 
##       (sample size : 50)
## 
##  observed number  0 0 4 6 0 
##  expected number  0.016 0.96 4.8 3.8 0.38