I1M2015: Estadística descriptiva en Haskell
En la segunda parte de la clase de hoy de Informática de 1º del Grado en Matemáticas hemos comentado las soluciones a los ejercicios de la relación 7 sobre estadística descriptiva.
Los ejercicios y su solución se muestran a continuación
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
-- --------------------------------------------------------------------- -- Introducción -- -- --------------------------------------------------------------------- -- El objetivo de esta relación es definir las principales medidas -- estadísticas de centralización (medias, mediana y modas) y de -- dispersión (rango, desviación media, varianza y desviación típica) -- que se estudian en 3º de ESO (como en http://bit.ly/1yXc7mv ). -- -- En las soluciones de los ejercicios se pueden usar las siguientes -- funciones de la librería Data.List fromIntegral, genericLength, sort, -- y group (cuya descripción se puede consultar en el "Manual de -- funciones básicas de Haskell" http://bit.ly/1PqHagT ). -- --------------------------------------------------------------------- -- Librerías auxiliares -- -- --------------------------------------------------------------------- import Data.List import Test.QuickCheck -- --------------------------------------------------------------------- -- Medidas de centralización -- -- --------------------------------------------------------------------- -- --------------------------------------------------------------------- -- Ejercicio 1. Definir la función -- media :: Floating a => [a] -> a -- tal que (media xs) es la media aritmética de los números de la lista -- xs. Por ejemplo, -- media [4,8,4,5,9] == 6.0 -- --------------------------------------------------------------------- media :: Floating a => [a] -> a media xs = sum xs / genericLength xs -- --------------------------------------------------------------------- -- Ejercicio 2. La mediana de una lista de valores es el valor de -- la lista que ocupa el lugar central de los valores ordenados de menor -- a mayor. Si el número de datos es impar se toma como valor de la -- mediana el valor central. Si el número de datos es par se toma como -- valor de la mediana la media aritmética de los dos valores -- centrales. -- -- Definir la función -- mediana :: (Floating a, Ord a) => [a] -> a -- tal que (mediana xs) es la mediana de la lista xs. Por ejemplo, -- mediana [2,3,6,8,9] == 6.0 -- mediana [2,3,4,6,8,9] == 5.0 -- mediana [9,6,8,4,3,2] == 5.0 -- --------------------------------------------------------------------- mediana :: (Floating a, Ord a) => [a] -> a mediana xs | odd n = ys !! i | even n = media [ys !! (i-1), ys !! i] where ys = sort xs n = length xs i = n `div` 2 -- --------------------------------------------------------------------- -- Ejercicio 3. Comprobar con QuickCheck que para cualquier lista no -- vacía xs el número de elementos de xs menores que su median es menor -- o igual que la mitad de los elementos de xs y lo mismo pasa con los -- mayores o iguales que la mediana. -- --------------------------------------------------------------------- -- La propiedad es prop_mediana :: (Floating a, Ord a) => [a] -> Property prop_mediana xs = not (null xs) ==> genericLength [x | x <- xs, x < m] <= n/2 && genericLength [x | x <- xs, x > m] <= n/2 where m = mediana xs n = genericLength xs -- La comprobación es -- ghci> quickCheck prop_mediana -- +++ OK, passed 100 tests. -- --------------------------------------------------------------------- -- Ejercicio 4. Definir la función -- frecuencias :: Ord a => [a] -> [(a,Int)] -- tal que (frecuencias xs) es la lista formada por los elementos de xs -- junto con el número de veces que aparecen en xs. Por ejemplo, -- frecuencias "sosos" == [('o',2),('s',3)] -- -- Nota: El orden de los pares no importa -- --------------------------------------------------------------------- -- 1ª solución frecuencias :: Ord a => [a] -> [(a,Int)] frecuencias xs = [(y,ocurrencias y xs) | y <- sort (nub xs)] where ocurrencias y xs = length [1 | x <- xs, x == y] -- 2ª solución frecuencias2 :: Ord a => [a] -> [(a,Int)] frecuencias2 xs = [(x,1 + length xs) | (x:xs) <- group (sort xs)] -- --------------------------------------------------------------------- -- Ejercicio 5. Las modas de una lista son los elementos de la lista -- que más se repiten. -- -- Definir la función -- modas :: Ord a => [a] -> [a] -- tal que (modas xs) es la lista ordenada de las modas de xs. Por -- ejemplo -- modas [7,3,7,5,3,1,6,9,6] == [3,6,7] -- --------------------------------------------------------------------- modas :: Ord a => [a] -> [a] modas xs = [y | (y,n) <- ys, n == m] where ys = frecuencias xs m = maximum (map snd ys) -- --------------------------------------------------------------------- -- Ejercicio 6. La media geométrica de una lista de n números es la -- raíz n-ésima del producto de todos los números. -- -- Definir la función -- mediaGeometrica :: Floating a => [a] -> a -- tal que (mediaGeometrica xs) es la media geométrica de xs. Por -- ejemplo, -- mediaGeometrica [2,18] == 6.0 -- mediaGeometrica [3,1,9] == 3.0 -- --------------------------------------------------------------------- mediaGeometrica :: Floating a => [a] -> a mediaGeometrica xs = (product xs)**(1 / genericLength xs) -- --------------------------------------------------------------------- -- Ejercicio 7. Comprobar con QuickCheck que la media geométrica de -- cualquier lista no vacía de números no negativos es siempre menor o -- igual que la media aritmética. -- --------------------------------------------------------------------- -- La propiedad es prop_mediaGeometrica :: (Floating a, Ord a) => [a] -> Property prop_mediaGeometrica xs = not (null xs) ==> mediaGeometrica ys <= media ys where ys = map abs xs -- La comprobación es -- ghci> quickCheck prop_mediaGeometrica -- +++ OK, passed 100 tests. -- --------------------------------------------------------------------- -- Medidas de dispersión -- -- --------------------------------------------------------------------- -- --------------------------------------------------------------------- -- Ejercicio 8. El recorrido (o rango) de una lista de valores es la -- diferencia entre el mayor y el menor. -- -- Definir la función -- rango :: (Num a, Ord a) => [a] -> a -- tal que (rango xs) es el rango de xs. Por ejemplo, -- rango [4,2,4,7,3] == 5 -- --------------------------------------------------------------------- rango :: (Num a, Ord a) => [a] -> a rango xs = maximum xs - minimum xs -- --------------------------------------------------------------------- -- Ejercicio 9. La desviación media de una lista de datos xs es la -- media de las distancias de los datos a la media xs, donde la -- distancia entre dos elementos es el valor absoluto de su -- diferencia. Por ejemplo, la desviación media de [4,8,4,5,9] es 2 ya -- que la media de [4,8,4,5,9] es 6 y -- (|4-6| + |8-6| + |4-6| + |5-6| + |9-6|) / 5 -- = (2 + 2 + 2 + 1 + 3) / 5 -- = 2 -- -- Definir la función -- desviacionMedia :: Floating a => [a] -> a -- tal que (desviacionMedia xs) es la desviación media de xs. Por -- ejemplo, -- desviacionMedia [4,8,4,5,9] == 2.0 -- desviacionMedia (replicate 10 3) == 0.0 -- --------------------------------------------------------------------- desviacionMedia :: Floating a => [a] -> a desviacionMedia xs = media [abs(x - m) | x <- xs] where m = media xs -- --------------------------------------------------------------------- -- Ejercicio 10. La varianza de una lista datos es la media de los -- cuadrados de las distancias de los datos a la media. Por ejemplo, la -- varianza de [4,8,4,5,9] es 4.4 ya que la media de [4,8,4,5,9] es 6 y -- ((4-6)^2 + (8-6)^2 + (4-6)^2 + (5-6)^2 + (9-6)^2) / 5 -- = (4 + 4 + 4 + 1 + 9) / 5 -- = 4.4 -- -- Definir la función -- varianza :: Floating a => [a] -> a -- tal que (desviacionMedia xs) es la varianza de xs. Por ejemplo, -- varianza [4,8,4,5,9] == 4.4 -- varianza (replicate 10 3) == 0.0 -- --------------------------------------------------------------------- varianza :: Floating a => [a] -> a varianza xs = media [(x-m)^2 | x <- xs] where m = media xs -- --------------------------------------------------------------------- -- Ejercicio 11. La desviación típica de una lista de datos es la raíz -- cuadrada de su varianza. -- -- Definir la función -- desviacionTipica :: Floating a => [a] -> a -- tal que (desviacionTipica xs) es la desviación típica de xs. Por -- ejemplo, -- desviacionTipica [4,8,4,5,9] == 2.0976176963403033 -- desviacionTipica (replicate 10 3) == 0.0 -- --------------------------------------------------------------------- desviacionTipica :: Floating a => [a] -> a desviacionTipica xs = sqrt (varianza xs) |
El codigo correspondiente se encuentra en GitHub.