├── Clase-1 ├── .DS_Store ├── Clase_1.jl └── Iris.csv ├── Clase-3 └── Clase-3.jl ├── Clase-4 ├── Clase_4.jl └── matches_England.json ├── Clase_2.jl ├── README.md └── data.csv /Clase-1/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HermanObst/data_science_course/b5d2c2e90eebc07b4ad72627c8f9a870567e9339/Clase-1/.DS_Store -------------------------------------------------------------------------------- /Clase-1/Clase_1.jl: -------------------------------------------------------------------------------- 1 | ### A Pluto.jl notebook ### 2 | # v0.14.2 3 | 4 | using Markdown 5 | using InteractiveUtils 6 | 7 | # ╔═╡ 192df0ba-94f7-11eb-2b4d-1739ff47c98c 8 | using Plots 9 | 10 | # ╔═╡ 5cb8035c-94f5-11eb-3c6e-35978f6a9c7f 11 | begin 12 | using DataFrames, Random 13 | 14 | Random.seed!(123) 15 | 16 | data = rand(5, 5) 17 | 18 | df = DataFrame(data) 19 | end 20 | 21 | # ╔═╡ e9b8cff2-94fa-11eb-3dbc-5d213b9ffcc8 22 | using CSV, Statistics 23 | 24 | # ╔═╡ 2193673c-94e1-11eb-175e-4df58b84eb75 25 | md""" 26 | 27 | # Bienvenidxs al curso de ciencia de datos del MLI 28 | 29 | ## Plan de Trabajo 30 | 31 | ### Primera clase 32 | 33 | - ¿Por qué Julia? 34 | - Primeros pasos 35 | - Herramientas básicas para ciencia de datos 36 | 37 | ### Segunda clase 38 | 39 | - Introducción a la estadística bayesiana 40 | - Introducción a la programación probabilistica 41 | - Algunas nociones de distribuciones de probabilidad 42 | - **Aplicación**: detección y ubicación temporal para el cambio en la tasa de arrivo de clientes a un local 43 | 44 | ### Tercera clase 45 | 46 | - Profundización conceptual de la estadística bayesiana 47 | - Cuantificación de la incertidumbre del modelo 48 | - **Aplicación**: Modelo para elección del precio óptimo de un producto contando con una prueba piloto. Análisis ingreso/varianza. 49 | 50 | ### Cuarta clase 51 | 52 | - Modelos bayesianos jerárquicos 53 | - **Aplicación**: Modelado en deportes. Modelo analítico para la premier league. Simulación de partidos y predicción. 54 | 55 | 56 | # Clase 1: Julia y primeras nociones programación científica 57 | 58 | ## ¿Por qué Julia? 59 | 60 | - Lenguaje Multipropósito 61 | - Diseñado para [análisis numérico](https://en.wikipedia.org/wiki/Numerical_analysis) y [computación científica](https://en.wikipedia.org/wiki/Computational_science) 62 | - Lenguaje de alto nivel (capacidad de abstracción y sintaxis simple) 63 | - Performante 64 | 65 | ## Instalación 66 | 67 | - [https://julialang.org/downloads/platform/](https://julialang.org/downloads/platform/) 68 | 69 | ## Primeros Pasos 70 | 71 | 72 | 73 | """ 74 | 75 | # ╔═╡ 7ef1f5ee-94ec-11eb-0437-3352923aeeba 76 | println("Hola Mundo") 77 | 78 | # ╔═╡ 9c2f695c-94ec-11eb-065d-593cc71022c2 79 | md"### Operadores Lógicos" 80 | 81 | # ╔═╡ e6df3128-6204-437e-ae1f-78dd15bb9029 82 | md"##### Escalares" 83 | 84 | # ╔═╡ cf73b8cc-94ec-11eb-1319-f187362bb4b2 85 | 2 + 2 86 | 87 | # ╔═╡ 219089a0-94ed-11eb-1e0b-f96c01210802 88 | π * 2 89 | 90 | # ╔═╡ c8177a72-94ed-11eb-328b-0dde7bbbc82a 91 | π/sqrt(2) 92 | 93 | # ╔═╡ 5d58b629-a3ad-474c-9d5c-14f99986eda4 94 | md"##### Vectores" 95 | 96 | # ╔═╡ 2c482dce-94ed-11eb-30eb-d525ba4aea64 97 | vector = [1,2,3,4,5] #Vector columna 98 | 99 | # ╔═╡ b02663bc-d722-488b-a384-939f9f80cc73 100 | size(vector) 101 | 102 | # ╔═╡ 48fce862-94ed-11eb-029b-b3349bae42ee 103 | vector*2 104 | 105 | # ╔═╡ 536e8f58-94ed-11eb-1607-cbf0af0e6084 106 | vector + 2 107 | 108 | # ╔═╡ 574c51e6-94ed-11eb-2fa6-335ec7d6ba5c 109 | vector .+ 2 110 | 111 | # ╔═╡ 9d198bda-94ed-11eb-2f26-a1363789c034 112 | vector_ = [9,8,7,6,5] 113 | 114 | # ╔═╡ ad442e20-94ed-11eb-13c4-079668f92aa4 115 | vector + vector_ 116 | 117 | # ╔═╡ 9537e766-94f9-11eb-03f8-d77a09477d33 118 | vector_cuadrado = [] 119 | 120 | # ╔═╡ 7c0046bf-e814-415f-984a-2aca174b4f67 121 | vector 122 | 123 | # ╔═╡ 5a4588b6-94f9-11eb-2e47-fb9ce77c45c8 124 | for numero in vector 125 | push!(vector_cuadrado, numero^2) 126 | end 127 | 128 | # ╔═╡ 7cc25720-94f9-11eb-12ef-1be2a137ccf3 129 | vector_cuadrado 130 | 131 | # ╔═╡ eb025511-99da-4626-8b50-8428d9857524 132 | vector_fila = [1 2 3 4] 133 | 134 | # ╔═╡ fc7e02c7-8d51-4f9c-8e1d-1d5f844db2e0 135 | size(vector_fila) 136 | 137 | # ╔═╡ 042b7ae5-ae7b-43e8-af5f-b4c53d0c32e9 138 | function suma_uno(numero) 139 | return numero + 1 140 | end 141 | 142 | # ╔═╡ fa97797b-c721-4bfa-a755-62be2566db1f 143 | vector 144 | 145 | # ╔═╡ 38956f41-4c35-4c4a-8ac2-504e1566f26d 146 | suma_uno(vector) 147 | 148 | # ╔═╡ d1280844-457e-4979-85a5-dc1b6bb5f7a8 149 | suma_uno.(vector) 150 | 151 | # ╔═╡ b0c8b7fc-8bcd-45ce-80f9-9c1e25eab5d1 152 | md"##### Matrices" 153 | 154 | # ╔═╡ 2252dcfc-065c-4c1c-b16c-b17593f9a723 155 | a = [1 2; 3 4] 156 | 157 | # ╔═╡ a937ddd1-61b3-4f99-8f9e-eb5070b60bce 158 | size(a) 159 | 160 | # ╔═╡ 4aea46dc-e035-4a2a-ab93-094a1095e33d 161 | a * 2 162 | 163 | # ╔═╡ d279e94e-6387-45e7-86dd-8ab2e05078ee 164 | a - 2 165 | 166 | # ╔═╡ 90c395a2-f7b4-40e9-a117-c0acf04c9aa1 167 | a .- 2 168 | 169 | # ╔═╡ f9903c09-da66-413b-a536-d61de8071bbc 170 | a - [2 2;2 2] 171 | 172 | # ╔═╡ b00e6b7b-0f60-423e-a62f-79bd01667b89 173 | b = [1 0; 0 1] 174 | 175 | # ╔═╡ eaa4d223-9b77-4128-aac5-e191f68e4a69 176 | a * b 177 | 178 | # ╔═╡ 75330790-1705-4994-a7ec-5a354387932b 179 | a * [1 1;1 1] 180 | 181 | # ╔═╡ 6e0bb9ce-cc30-488d-a368-33399474588b 182 | [1 1; 1 1] * a 183 | 184 | # ╔═╡ 3fad3067-c887-4b62-ae3a-7ddd56f8e0ba 185 | a 186 | 187 | # ╔═╡ dced837a-9519-478f-a092-394668d6cb52 188 | md"**Transposición**" 189 | 190 | # ╔═╡ f97e0145-8b03-41af-afbb-a286b25c2814 191 | a_T = a' 192 | 193 | # ╔═╡ 2aa48230-46c8-4081-891b-3b00321992d1 194 | c = [2 2;2 4] 195 | 196 | # ╔═╡ f60bc545-3889-4828-8e91-d33bca5e71f0 197 | md"**Inversión**" 198 | 199 | # ╔═╡ 1e9a691a-d72d-43d6-9d80-2bff817bd5f0 200 | c_inv = inv(c) 201 | 202 | # ╔═╡ 6e7dfe5e-da04-44fb-9ac2-6e8ae49225fe 203 | c * c_inv 204 | 205 | # ╔═╡ 72a25914-94ee-11eb-2df9-bdc220c1b0c5 206 | md"## Graficación" 207 | 208 | # ╔═╡ 68d02096-03aa-4870-bf14-a28f244ce5de 209 | md"[Documentación Plots.jl](http://docs.juliaplots.org/latest/)" 210 | 211 | # ╔═╡ 84f3e0ea-94ee-11eb-0f96-a9e094716389 212 | begin 213 | secuencia = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] 214 | 215 | p1 = scatter(secuencia, xlabel="n", ylabel="Fibonacci(n)", color="purple", label=false) 216 | 217 | end 218 | 219 | # ╔═╡ d270ba98-94f3-11eb-18a3-f567cfe13b99 220 | begin 221 | x = 0:10 222 | y = x.^2 223 | end 224 | 225 | # ╔═╡ 291f0f68-94f3-11eb-1ff5-1b9e20e4632e 226 | begin 227 | plot(y, label=false, xlabel="x", ylabel="x^2") 228 | p2 = scatter!(y, label=false) 229 | end 230 | 231 | # ╔═╡ 389eee64-94f4-11eb-3135-11cc76e45a7f 232 | plot(p1, p2) 233 | 234 | # ╔═╡ 732bce26-94f4-11eb-359e-0d521ed62399 235 | md"## DataFrames" 236 | 237 | # ╔═╡ b5bfdf36-0e84-4f45-a10c-27878d66b465 238 | md"[Documentación DataFrames](https://dataframes.juliadata.org/stable/)" 239 | 240 | # ╔═╡ ea62a4f0-94f5-11eb-3b92-678fb6c684d7 241 | rename!(df, ["uno", "dos", "tres", "cuatro", "cinco"]) 242 | 243 | # ╔═╡ 816ec820-94f8-11eb-1223-f54d2eb81c33 244 | df.uno 245 | 246 | # ╔═╡ 903b8e58-94f8-11eb-128e-b95a26c712ea 247 | df[1,:] 248 | 249 | # ╔═╡ bbb96fec-94f9-11eb-094f-6547d1582fbb 250 | df[3:5, ["dos", "cuatro", "cinco"]] 251 | 252 | # ╔═╡ 9e9999ea-94f8-11eb-2e53-3911d1a018e9 253 | for fila in eachrow(df) 254 | println(fila.uno) 255 | end 256 | 257 | # ╔═╡ 55f0ba08-94fa-11eb-13ea-914410b7c02a 258 | md"#### Manipulación de DataFrames" 259 | 260 | # ╔═╡ e33fd8ec-94f9-11eb-0f67-b10c30f82beb 261 | describe(df) 262 | 263 | # ╔═╡ a3d4f27c-9617-11eb-36df-7b334c63b9a9 264 | filter(row -> row[1] < 0.5, df) 265 | 266 | # ╔═╡ 633024a8-94fa-11eb-1ce5-6b6f90335ea1 267 | filter(:uno => uno -> uno < 0.5, df) 268 | 269 | # ╔═╡ 8598931e-956c-11eb-134c-33af4c68dbc1 270 | iris_df = CSV.File("Iris.csv") |> DataFrame 271 | 272 | # ╔═╡ 389a6094-956d-11eb-0b5b-1fb2b9d4c91e 273 | md"Agrupamos el data frame por especies" 274 | 275 | # ╔═╡ 4929d4ca-956d-11eb-0131-a1283e495db3 276 | gdf = groupby(iris_df, :Species) 277 | 278 | # ╔═╡ c4544b1a-956d-11eb-260c-d54a008b6c2b 279 | combine(gdf, :PetalLengthCm => mean) 280 | 281 | # ╔═╡ 8badd92e-956e-11eb-2a5d-938b8332aece 282 | filter!(row -> row.Species != "Iris-setosa", iris_df) 283 | 284 | # ╔═╡ aa77dac9-f597-46ab-847b-21564fc769a5 285 | begin 286 | gr() 287 | plot() 288 | for i in 2:5 289 | plot!(iris_df[:,i], legend=false) 290 | end 291 | xlabel!("Flower") 292 | ylabel!("Centimeters (cm)") 293 | title!("Flower features") 294 | current() 295 | end 296 | 297 | # ╔═╡ 0c08d1b7-c48b-4096-815f-107ce1b6e5b0 298 | md"### Referencias" 299 | 300 | # ╔═╡ 4b46904f-2ff4-4f92-a069-18463e83373d 301 | md" 302 | - [Data Science in Julia for Hackers](https://datasciencejuliahackers.com/) 303 | - [Capítulo introducción a Julia](https://datasciencejuliahackers.com/02_julia_intro.jl.html) 304 | - [Curso DataFrames JuliaAcademy](https://juliaacademy.com/p/introduction-to-dataframes-jl) 305 | " 306 | 307 | # ╔═╡ Cell order: 308 | # ╟─2193673c-94e1-11eb-175e-4df58b84eb75 309 | # ╠═7ef1f5ee-94ec-11eb-0437-3352923aeeba 310 | # ╟─9c2f695c-94ec-11eb-065d-593cc71022c2 311 | # ╟─e6df3128-6204-437e-ae1f-78dd15bb9029 312 | # ╠═cf73b8cc-94ec-11eb-1319-f187362bb4b2 313 | # ╠═219089a0-94ed-11eb-1e0b-f96c01210802 314 | # ╠═c8177a72-94ed-11eb-328b-0dde7bbbc82a 315 | # ╟─5d58b629-a3ad-474c-9d5c-14f99986eda4 316 | # ╠═2c482dce-94ed-11eb-30eb-d525ba4aea64 317 | # ╠═b02663bc-d722-488b-a384-939f9f80cc73 318 | # ╠═48fce862-94ed-11eb-029b-b3349bae42ee 319 | # ╠═536e8f58-94ed-11eb-1607-cbf0af0e6084 320 | # ╠═574c51e6-94ed-11eb-2fa6-335ec7d6ba5c 321 | # ╠═9d198bda-94ed-11eb-2f26-a1363789c034 322 | # ╠═ad442e20-94ed-11eb-13c4-079668f92aa4 323 | # ╠═9537e766-94f9-11eb-03f8-d77a09477d33 324 | # ╠═7c0046bf-e814-415f-984a-2aca174b4f67 325 | # ╠═5a4588b6-94f9-11eb-2e47-fb9ce77c45c8 326 | # ╠═7cc25720-94f9-11eb-12ef-1be2a137ccf3 327 | # ╠═eb025511-99da-4626-8b50-8428d9857524 328 | # ╠═fc7e02c7-8d51-4f9c-8e1d-1d5f844db2e0 329 | # ╠═042b7ae5-ae7b-43e8-af5f-b4c53d0c32e9 330 | # ╠═fa97797b-c721-4bfa-a755-62be2566db1f 331 | # ╠═38956f41-4c35-4c4a-8ac2-504e1566f26d 332 | # ╠═d1280844-457e-4979-85a5-dc1b6bb5f7a8 333 | # ╟─b0c8b7fc-8bcd-45ce-80f9-9c1e25eab5d1 334 | # ╠═2252dcfc-065c-4c1c-b16c-b17593f9a723 335 | # ╠═a937ddd1-61b3-4f99-8f9e-eb5070b60bce 336 | # ╠═4aea46dc-e035-4a2a-ab93-094a1095e33d 337 | # ╠═d279e94e-6387-45e7-86dd-8ab2e05078ee 338 | # ╠═90c395a2-f7b4-40e9-a117-c0acf04c9aa1 339 | # ╠═f9903c09-da66-413b-a536-d61de8071bbc 340 | # ╠═b00e6b7b-0f60-423e-a62f-79bd01667b89 341 | # ╠═eaa4d223-9b77-4128-aac5-e191f68e4a69 342 | # ╠═75330790-1705-4994-a7ec-5a354387932b 343 | # ╠═6e0bb9ce-cc30-488d-a368-33399474588b 344 | # ╠═3fad3067-c887-4b62-ae3a-7ddd56f8e0ba 345 | # ╟─dced837a-9519-478f-a092-394668d6cb52 346 | # ╠═f97e0145-8b03-41af-afbb-a286b25c2814 347 | # ╠═2aa48230-46c8-4081-891b-3b00321992d1 348 | # ╟─f60bc545-3889-4828-8e91-d33bca5e71f0 349 | # ╠═1e9a691a-d72d-43d6-9d80-2bff817bd5f0 350 | # ╠═6e7dfe5e-da04-44fb-9ac2-6e8ae49225fe 351 | # ╟─72a25914-94ee-11eb-2df9-bdc220c1b0c5 352 | # ╟─68d02096-03aa-4870-bf14-a28f244ce5de 353 | # ╠═192df0ba-94f7-11eb-2b4d-1739ff47c98c 354 | # ╠═84f3e0ea-94ee-11eb-0f96-a9e094716389 355 | # ╠═d270ba98-94f3-11eb-18a3-f567cfe13b99 356 | # ╠═291f0f68-94f3-11eb-1ff5-1b9e20e4632e 357 | # ╠═389eee64-94f4-11eb-3135-11cc76e45a7f 358 | # ╟─732bce26-94f4-11eb-359e-0d521ed62399 359 | # ╟─b5bfdf36-0e84-4f45-a10c-27878d66b465 360 | # ╠═5cb8035c-94f5-11eb-3c6e-35978f6a9c7f 361 | # ╠═ea62a4f0-94f5-11eb-3b92-678fb6c684d7 362 | # ╠═816ec820-94f8-11eb-1223-f54d2eb81c33 363 | # ╠═903b8e58-94f8-11eb-128e-b95a26c712ea 364 | # ╠═bbb96fec-94f9-11eb-094f-6547d1582fbb 365 | # ╠═9e9999ea-94f8-11eb-2e53-3911d1a018e9 366 | # ╟─55f0ba08-94fa-11eb-13ea-914410b7c02a 367 | # ╠═e33fd8ec-94f9-11eb-0f67-b10c30f82beb 368 | # ╠═a3d4f27c-9617-11eb-36df-7b334c63b9a9 369 | # ╠═633024a8-94fa-11eb-1ce5-6b6f90335ea1 370 | # ╠═e9b8cff2-94fa-11eb-3dbc-5d213b9ffcc8 371 | # ╠═8598931e-956c-11eb-134c-33af4c68dbc1 372 | # ╟─389a6094-956d-11eb-0b5b-1fb2b9d4c91e 373 | # ╠═4929d4ca-956d-11eb-0131-a1283e495db3 374 | # ╠═c4544b1a-956d-11eb-260c-d54a008b6c2b 375 | # ╠═8badd92e-956e-11eb-2a5d-938b8332aece 376 | # ╠═aa77dac9-f597-46ab-847b-21564fc769a5 377 | # ╟─0c08d1b7-c48b-4096-815f-107ce1b6e5b0 378 | # ╟─4b46904f-2ff4-4f92-a069-18463e83373d 379 | -------------------------------------------------------------------------------- /Clase-1/Iris.csv: -------------------------------------------------------------------------------- 1 | Id,SepalLengthCm,SepalWidthCm,PetalLengthCm,PetalWidthCm,Species 2 | 1,5.1,3.5,1.4,0.2,Iris-setosa 3 | 2,4.9,3.0,1.4,0.2,Iris-setosa 4 | 3,4.7,3.2,1.3,0.2,Iris-setosa 5 | 4,4.6,3.1,1.5,0.2,Iris-setosa 6 | 5,5.0,3.6,1.4,0.2,Iris-setosa 7 | 6,5.4,3.9,1.7,0.4,Iris-setosa 8 | 7,4.6,3.4,1.4,0.3,Iris-setosa 9 | 8,5.0,3.4,1.5,0.2,Iris-setosa 10 | 9,4.4,2.9,1.4,0.2,Iris-setosa 11 | 10,4.9,3.1,1.5,0.1,Iris-setosa 12 | 11,5.4,3.7,1.5,0.2,Iris-setosa 13 | 12,4.8,3.4,1.6,0.2,Iris-setosa 14 | 13,4.8,3.0,1.4,0.1,Iris-setosa 15 | 14,4.3,3.0,1.1,0.1,Iris-setosa 16 | 15,5.8,4.0,1.2,0.2,Iris-setosa 17 | 16,5.7,4.4,1.5,0.4,Iris-setosa 18 | 17,5.4,3.9,1.3,0.4,Iris-setosa 19 | 18,5.1,3.5,1.4,0.3,Iris-setosa 20 | 19,5.7,3.8,1.7,0.3,Iris-setosa 21 | 20,5.1,3.8,1.5,0.3,Iris-setosa 22 | 21,5.4,3.4,1.7,0.2,Iris-setosa 23 | 22,5.1,3.7,1.5,0.4,Iris-setosa 24 | 23,4.6,3.6,1.0,0.2,Iris-setosa 25 | 24,5.1,3.3,1.7,0.5,Iris-setosa 26 | 25,4.8,3.4,1.9,0.2,Iris-setosa 27 | 26,5.0,3.0,1.6,0.2,Iris-setosa 28 | 27,5.0,3.4,1.6,0.4,Iris-setosa 29 | 28,5.2,3.5,1.5,0.2,Iris-setosa 30 | 29,5.2,3.4,1.4,0.2,Iris-setosa 31 | 30,4.7,3.2,1.6,0.2,Iris-setosa 32 | 31,4.8,3.1,1.6,0.2,Iris-setosa 33 | 32,5.4,3.4,1.5,0.4,Iris-setosa 34 | 33,5.2,4.1,1.5,0.1,Iris-setosa 35 | 34,5.5,4.2,1.4,0.2,Iris-setosa 36 | 35,4.9,3.1,1.5,0.1,Iris-setosa 37 | 36,5.0,3.2,1.2,0.2,Iris-setosa 38 | 37,5.5,3.5,1.3,0.2,Iris-setosa 39 | 38,4.9,3.1,1.5,0.1,Iris-setosa 40 | 39,4.4,3.0,1.3,0.2,Iris-setosa 41 | 40,5.1,3.4,1.5,0.2,Iris-setosa 42 | 41,5.0,3.5,1.3,0.3,Iris-setosa 43 | 42,4.5,2.3,1.3,0.3,Iris-setosa 44 | 43,4.4,3.2,1.3,0.2,Iris-setosa 45 | 44,5.0,3.5,1.6,0.6,Iris-setosa 46 | 45,5.1,3.8,1.9,0.4,Iris-setosa 47 | 46,4.8,3.0,1.4,0.3,Iris-setosa 48 | 47,5.1,3.8,1.6,0.2,Iris-setosa 49 | 48,4.6,3.2,1.4,0.2,Iris-setosa 50 | 49,5.3,3.7,1.5,0.2,Iris-setosa 51 | 50,5.0,3.3,1.4,0.2,Iris-setosa 52 | 51,7.0,3.2,4.7,1.4,Iris-versicolor 53 | 52,6.4,3.2,4.5,1.5,Iris-versicolor 54 | 53,6.9,3.1,4.9,1.5,Iris-versicolor 55 | 54,5.5,2.3,4.0,1.3,Iris-versicolor 56 | 55,6.5,2.8,4.6,1.5,Iris-versicolor 57 | 56,5.7,2.8,4.5,1.3,Iris-versicolor 58 | 57,6.3,3.3,4.7,1.6,Iris-versicolor 59 | 58,4.9,2.4,3.3,1.0,Iris-versicolor 60 | 59,6.6,2.9,4.6,1.3,Iris-versicolor 61 | 60,5.2,2.7,3.9,1.4,Iris-versicolor 62 | 61,5.0,2.0,3.5,1.0,Iris-versicolor 63 | 62,5.9,3.0,4.2,1.5,Iris-versicolor 64 | 63,6.0,2.2,4.0,1.0,Iris-versicolor 65 | 64,6.1,2.9,4.7,1.4,Iris-versicolor 66 | 65,5.6,2.9,3.6,1.3,Iris-versicolor 67 | 66,6.7,3.1,4.4,1.4,Iris-versicolor 68 | 67,5.6,3.0,4.5,1.5,Iris-versicolor 69 | 68,5.8,2.7,4.1,1.0,Iris-versicolor 70 | 69,6.2,2.2,4.5,1.5,Iris-versicolor 71 | 70,5.6,2.5,3.9,1.1,Iris-versicolor 72 | 71,5.9,3.2,4.8,1.8,Iris-versicolor 73 | 72,6.1,2.8,4.0,1.3,Iris-versicolor 74 | 73,6.3,2.5,4.9,1.5,Iris-versicolor 75 | 74,6.1,2.8,4.7,1.2,Iris-versicolor 76 | 75,6.4,2.9,4.3,1.3,Iris-versicolor 77 | 76,6.6,3.0,4.4,1.4,Iris-versicolor 78 | 77,6.8,2.8,4.8,1.4,Iris-versicolor 79 | 78,6.7,3.0,5.0,1.7,Iris-versicolor 80 | 79,6.0,2.9,4.5,1.5,Iris-versicolor 81 | 80,5.7,2.6,3.5,1.0,Iris-versicolor 82 | 81,5.5,2.4,3.8,1.1,Iris-versicolor 83 | 82,5.5,2.4,3.7,1.0,Iris-versicolor 84 | 83,5.8,2.7,3.9,1.2,Iris-versicolor 85 | 84,6.0,2.7,5.1,1.6,Iris-versicolor 86 | 85,5.4,3.0,4.5,1.5,Iris-versicolor 87 | 86,6.0,3.4,4.5,1.6,Iris-versicolor 88 | 87,6.7,3.1,4.7,1.5,Iris-versicolor 89 | 88,6.3,2.3,4.4,1.3,Iris-versicolor 90 | 89,5.6,3.0,4.1,1.3,Iris-versicolor 91 | 90,5.5,2.5,4.0,1.3,Iris-versicolor 92 | 91,5.5,2.6,4.4,1.2,Iris-versicolor 93 | 92,6.1,3.0,4.6,1.4,Iris-versicolor 94 | 93,5.8,2.6,4.0,1.2,Iris-versicolor 95 | 94,5.0,2.3,3.3,1.0,Iris-versicolor 96 | 95,5.6,2.7,4.2,1.3,Iris-versicolor 97 | 96,5.7,3.0,4.2,1.2,Iris-versicolor 98 | 97,5.7,2.9,4.2,1.3,Iris-versicolor 99 | 98,6.2,2.9,4.3,1.3,Iris-versicolor 100 | 99,5.1,2.5,3.0,1.1,Iris-versicolor 101 | 100,5.7,2.8,4.1,1.3,Iris-versicolor 102 | 101,6.3,3.3,6.0,2.5,Iris-virginica 103 | 102,5.8,2.7,5.1,1.9,Iris-virginica 104 | 103,7.1,3.0,5.9,2.1,Iris-virginica 105 | 104,6.3,2.9,5.6,1.8,Iris-virginica 106 | 105,6.5,3.0,5.8,2.2,Iris-virginica 107 | 106,7.6,3.0,6.6,2.1,Iris-virginica 108 | 107,4.9,2.5,4.5,1.7,Iris-virginica 109 | 108,7.3,2.9,6.3,1.8,Iris-virginica 110 | 109,6.7,2.5,5.8,1.8,Iris-virginica 111 | 110,7.2,3.6,6.1,2.5,Iris-virginica 112 | 111,6.5,3.2,5.1,2.0,Iris-virginica 113 | 112,6.4,2.7,5.3,1.9,Iris-virginica 114 | 113,6.8,3.0,5.5,2.1,Iris-virginica 115 | 114,5.7,2.5,5.0,2.0,Iris-virginica 116 | 115,5.8,2.8,5.1,2.4,Iris-virginica 117 | 116,6.4,3.2,5.3,2.3,Iris-virginica 118 | 117,6.5,3.0,5.5,1.8,Iris-virginica 119 | 118,7.7,3.8,6.7,2.2,Iris-virginica 120 | 119,7.7,2.6,6.9,2.3,Iris-virginica 121 | 120,6.0,2.2,5.0,1.5,Iris-virginica 122 | 121,6.9,3.2,5.7,2.3,Iris-virginica 123 | 122,5.6,2.8,4.9,2.0,Iris-virginica 124 | 123,7.7,2.8,6.7,2.0,Iris-virginica 125 | 124,6.3,2.7,4.9,1.8,Iris-virginica 126 | 125,6.7,3.3,5.7,2.1,Iris-virginica 127 | 126,7.2,3.2,6.0,1.8,Iris-virginica 128 | 127,6.2,2.8,4.8,1.8,Iris-virginica 129 | 128,6.1,3.0,4.9,1.8,Iris-virginica 130 | 129,6.4,2.8,5.6,2.1,Iris-virginica 131 | 130,7.2,3.0,5.8,1.6,Iris-virginica 132 | 131,7.4,2.8,6.1,1.9,Iris-virginica 133 | 132,7.9,3.8,6.4,2.0,Iris-virginica 134 | 133,6.4,2.8,5.6,2.2,Iris-virginica 135 | 134,6.3,2.8,5.1,1.5,Iris-virginica 136 | 135,6.1,2.6,5.6,1.4,Iris-virginica 137 | 136,7.7,3.0,6.1,2.3,Iris-virginica 138 | 137,6.3,3.4,5.6,2.4,Iris-virginica 139 | 138,6.4,3.1,5.5,1.8,Iris-virginica 140 | 139,6.0,3.0,4.8,1.8,Iris-virginica 141 | 140,6.9,3.1,5.4,2.1,Iris-virginica 142 | 141,6.7,3.1,5.6,2.4,Iris-virginica 143 | 142,6.9,3.1,5.1,2.3,Iris-virginica 144 | 143,5.8,2.7,5.1,1.9,Iris-virginica 145 | 144,6.8,3.2,5.9,2.3,Iris-virginica 146 | 145,6.7,3.3,5.7,2.5,Iris-virginica 147 | 146,6.7,3.0,5.2,2.3,Iris-virginica 148 | 147,6.3,2.5,5.0,1.9,Iris-virginica 149 | 148,6.5,3.0,5.2,2.0,Iris-virginica 150 | 149,6.2,3.4,5.4,2.3,Iris-virginica 151 | 150,5.9,3.0,5.1,1.8,Iris-virginica 152 | -------------------------------------------------------------------------------- /Clase-3/Clase-3.jl: -------------------------------------------------------------------------------- 1 | ### A Pluto.jl notebook ### 2 | # v0.14.2 3 | 4 | using Markdown 5 | using InteractiveUtils 6 | 7 | # ╔═╡ d6a37b99-ab94-4d41-9147-ef7c0b695704 8 | using Plots 9 | 10 | # ╔═╡ acc3e9f5-5ddd-4fab-8536-471aee398eb2 11 | using Turing 12 | 13 | # ╔═╡ e38aca18-0098-4cb5-9229-1f639c8243ca 14 | using StatsPlots 15 | 16 | # ╔═╡ 6364fa28-0737-43f2-b5d4-5f743ce64ea1 17 | begin 18 | using LaTeXStrings 19 | s = latexstring("\\mu_{Profit}") 20 | s2 = latexstring("\\mu_{Profit} \\pm \\sigma_{Profit}") 21 | s3 = latexstring("ArgMax(\\mu_{Profit})") 22 | end; 23 | 24 | # ╔═╡ c42c63d2-a615-11eb-094c-07ffc56e14b0 25 | md""" 26 | 27 | # Tercera clase del curso de ciencia de datos del MLI 28 | 29 | ## Plan de Trabajo 30 | 31 | ### Primera clase (ok) 32 | 33 | - ¿Por qué Julia? 34 | - Primeros pasos 35 | - Herramientas básicas para ciencia de datos 36 | 37 | ### Segunda clase (ok) 38 | 39 | - Introducción a la estadística bayesiana 40 | - Introducción a la programación probabilistica 41 | - Algunas nociones de distribuciones de probabilidad 42 | - **Aplicación**: detección y ubicación temporal para el cambio en la tasa de arrivo de clientes a un local 43 | 44 | ### Tercera clase 45 | 46 | - Profundización conceptual de la estadística bayesiana 47 | - Cuantificación de la incertidumbre del modelo 48 | - **Aplicación**: Modelo para elección del precio óptimo de un producto contando con una prueba piloto. Análisis ingreso/varianza. 49 | 50 | ### Cuarta clase 51 | 52 | - Modelos bayesianos jerárquicos 53 | - **Aplicación**: Modelado en deportes. Modelo analítico para la premier league. Simulación de partidos y predicción. 54 | 55 | ### Incretidumbre del modelo 56 | 57 | Al ser los parámetros de nuestros modelos **distribuciones** de probabilidad, el modelado bayesiano nos permite incluir la incertidumbre de manera integral. 58 | 59 | ### Aplicación: Modelo para elección del precio óptimo de un producto contando con una prueba piloto. 60 | """ 61 | 62 | # ╔═╡ 93ea39ee-6aa6-41f2-8ece-7b3715a9a060 63 | md"La idea de este problema es que tenemos un nuevo producto que lanzar. Sabemos nuestros costos de producción, pero no sabemos el precio óptimo para maximizar nuestras ganancias. 64 | 65 | Como sabemos que: 66 | 67 | $Ventas = Cantidad * Precio$ 68 | 69 | y que al subir el precio, las cantidades que nos compran van a tender a disminuir, nos gustaría saber el precio óptimo para maximizar las ventas. 70 | 71 | Para esto, vamos a querer construir la curva de demanda de nuestro producto utilizando una prueba piloto. En esta caso usaremos el modelo clásico P vs Q: 72 | 73 | $Q = aP^{c}$ 74 | 75 | Pero decir esto, sería olvidarnos de la naturaleza aleatoria de la variable Q. Osea, al definir un precio no podemos obtener la cantidad **exacta** de Q, pero si un valor esperado. 76 | 77 | Más correcto sería decir: 78 | 79 | $E[Q|P] = aP^{c}$ 80 | 81 | Así no nos olvidamos que Q es una *variable aleatoria*. En paricular, vamos a proponer que Q viene de una Poisson con parámetro (media) $Q_{medio} = E[Q|P] = aP^{c}$ 82 | 83 | $Q \sim Poisson(Q_{med})$" 84 | 85 | # ╔═╡ ae70c258-249f-4a1e-9bcc-f778dad4146e 86 | begin 87 | 88 | a = 500 89 | c_ = -0.9 90 | P = 1:100 91 | Q_ = a.*(P.^c_) 92 | 93 | plot(P, Q_, legend=false, title="Modelo de Cantidad vs Precio") 94 | 95 | xlabel!("Precio") 96 | ylabel!("Cantidad") 97 | end 98 | 99 | # ╔═╡ e8856141-2d30-41c6-80af-e05f434f69fd 100 | md"Para facilitar el trabajo, vamos a linealizar la relación propuesta: 101 | 102 | $log(Q)=log(a) + c*log(P)$ 103 | 104 | Se puede pensar como una recta: 105 | 106 | $Y = b + m*X$" 107 | 108 | # ╔═╡ 55100ed9-c4dc-4b3f-9832-e412b6299149 109 | md"Definamos nuestro modelo:" 110 | 111 | # ╔═╡ 4605184e-a890-44ce-b51f-751f10cdc1e7 112 | begin 113 | @model function demanda(qval,p0) 114 | loga ~ Cauchy() 115 | c ~ Cauchy() 116 | logQ0 = loga .+ c*(log.(p0) .- mean(log.(p0))) 117 | 118 | Q0 = exp.(logQ0) 119 | for i in eachindex(Q0) 120 | qval[i] ~ Poisson(Q0[i]) 121 | end 122 | end 123 | end 124 | 125 | # ╔═╡ 6d14330d-134b-44e7-b929-d3328d32889d 126 | begin 127 | plot(-10:0.01:10,Cauchy(), xlim=(-10,10),label="Cauchy(0,1)") 128 | plot!(Normal(), xlim=(-10,10), label="Normal(0,1)") 129 | end 130 | 131 | # ╔═╡ 6b5f7859-8f6d-48f2-b027-0df88f504ea0 132 | md"#### Una vez definido el modelo ¡tomemos datos!" 133 | 134 | # ╔═╡ f6546947-a5f0-43b1-bc18-bd7bad36b82a 135 | begin 136 | #Nuestros puntos obtenidos de la prueba piloto 137 | precio = [1500, 2500, 4000, 5000] 138 | cantidad = [590, 259, 231, 117] 139 | 140 | scatter(precio, cantidad, markersize=6, color="orange", legend=false, xlim=(1000,6000), ylim=(0,1100)) 141 | xlabel!("Precio") 142 | ylabel!("Cantidad") 143 | end 144 | 145 | # ╔═╡ f45fbaf8-02d0-4cd4-971f-a1b058d011cd 146 | begin 147 | modelo = demanda(cantidad, precio) 148 | posterior = sample(modelo, NUTS(),1000) 149 | end; 150 | 151 | # ╔═╡ c6e56884-4853-4c90-8e72-0caae4ad0844 152 | md"$log(Q)=log(a) + c*log(P)$" 153 | 154 | # ╔═╡ 3fb416de-79eb-4950-a0b2-040c04619228 155 | begin 156 | post_loga = collect(get(posterior, :loga)) 157 | post_c = collect(get(posterior, :c)) 158 | 159 | hist_loga = histogram(post_loga, normed=true, bins=20, label=false, xlabel="log a") 160 | hist_c = histogram(post_c, normed=true, legend=false, bins=20, xlabel="c") 161 | plot(hist_loga, hist_c, layout=(1,2)) 162 | end 163 | 164 | # ╔═╡ 8a08fe88-184f-4d64-9fc5-abe87a9c8422 165 | mean(post_loga[1]) 166 | 167 | # ╔═╡ 8fe80c8a-023e-486d-bcbd-bb2244a26356 168 | mean(post_c[1]) 169 | 170 | # ╔═╡ 27fd6af3-0864-4276-a7c6-a4ee2896dcbe 171 | md"Okey!! 172 | 173 | Podríamos entonces suponer que nuestro modelo tiene esta función: 174 | 175 | $Log(Q)=5.55 - 1.18Log(P)$ 176 | 177 | ¿Tendría esto sentido? 178 | 179 | Ni de cerca! Haciendo esto, estamos perdiendo toda la preciosa información de la incertidumbre de nuestro modelo!" 180 | 181 | # ╔═╡ 8f3f610c-cc20-4f74-ba90-8af10cbf74bc 182 | md"#### Incorporando a la incertibumbre para la toma de decisiones" 183 | 184 | # ╔═╡ a41ed419-0fd0-4d0f-8ea9-5f9347fca281 185 | begin 186 | p = range(1000,9000,step = 10); 187 | q = zeros(length(p),length(post_c[1])) 188 | 189 | for i in collect(1:length(post_c[1])) 190 | q[:,i] = exp.(post_loga[1][i] .+ post_c[1][i] .* (log.(p) .- mean(log.(precio)))) 191 | end 192 | end 193 | 194 | # ╔═╡ 9044ccbe-f2a6-4fcd-8894-8fe943f78b55 195 | q 196 | 197 | # ╔═╡ 9e2d40f3-d971-4b21-8f75-e22fe8e1bc43 198 | begin 199 | plot(p,q[:,1], xlim=(1000,6000)) 200 | for i in collect(1:length(post_c[1])) 201 | plot!(p,q[:,i], color="blue", legend=false, alpha = 0.1) 202 | end 203 | 204 | plot!(p, mean(q, dims=2), color="red", lw=2) 205 | scatter!(precio, cantidad, color="orange", markersize=5) 206 | ylabel!("Cantidad") 207 | xlabel!("Precio") 208 | end 209 | 210 | # ╔═╡ 3675d864-5169-46fb-b4fd-4191a84e33a3 211 | md"""#### Maximización de la ganancia 212 | 213 | Teniendo en cuenta que: 214 | 215 | $Ganancia = Precio * Cantidad - Costos$ 216 | 217 | $Ganancia=Precio * Cantidad - (CostosVariable * Cantidad + CostosFijos)$ 218 | 219 | Podemos contruir nuestra curva de ganancias 220 | """ 221 | 222 | # ╔═╡ c6e0c9ef-86c8-4d8e-9d08-82beb3d03668 223 | begin 224 | costo_fijo = 10000 225 | costo_var_unit = 700 226 | costo_variable = costo_var_unit .* q 227 | costo_total = costo_variable .+ costo_fijo 228 | ganancia = p .* q .- costo_total 229 | end; 230 | 231 | # ╔═╡ 4f551424-e5aa-49c6-b27b-06c6058c9ac9 232 | ganancia 233 | 234 | # ╔═╡ 6105a2c4-9e3f-4e4f-a028-3bac8a758bf3 235 | mxval, mxindx = findmax(mean(ganancia, dims=2); dims=1); 236 | 237 | # ╔═╡ 402d63a8-cf38-4a1e-8e24-0c8e72d1f8f2 238 | mxval[1] #Ganancia media 239 | 240 | # ╔═╡ 2848ff96-39ce-4b98-a58c-0021971743a9 241 | desfavorable = mxval[1] - std(ganancia[mxindx[1][1], : ]) #Ganancia caso desfavorable 242 | 243 | # ╔═╡ 280f65a6-9ef6-4b34-9b9c-d22d7d141183 244 | favorable = mxval[1] + std(ganancia[mxindx[1][1], : ]) #Ganancia caso favorable 245 | 246 | # ╔═╡ 3f7e3b90-f964-4819-966f-c3190b1f428f 247 | begin 248 | plot() 249 | for i in collect(1:length(post_c[1])) 250 | plot!(p,ganancia[:,i], color="blue", label=false, alpha = 0.1) 251 | end 252 | 253 | plot!(p,mean(ganancia, dims=2) + std(ganancia, dims=2), color = "orange", lw=2, label =s2) 254 | 255 | plot!(p,mean(ganancia, dims=2), color = "red", lw=4, label=s) 256 | 257 | plot!(p,mean(ganancia, dims=2) - std(ganancia, dims=2), color = "orange", lw=2, label="") 258 | 259 | vline!(p[mxindx], p[mxindx], line = (:black, 3), label=s3) 260 | 261 | xlabel!("Precio") 262 | ylabel!("Ganancia") 263 | end 264 | 265 | # ╔═╡ d9ab2acf-7fc7-4b57-b596-629e8f4e50ea 266 | md"##### Cuantificación del riesgo" 267 | 268 | # ╔═╡ 839f838d-b2fe-48bb-a47d-79c7f71ff7a3 269 | std_p = [std(ganancia[i, : ]) for i in collect(1:length(p))] 270 | 271 | # ╔═╡ 43f52222-be42-4042-b9da-a95bd61a86e8 272 | plot(p,std_p, legend=false, xlabel = "Price", ylabel= "Desviación standard de la ganancia", lw=2) 273 | 274 | # ╔═╡ 7517412b-0196-4727-a787-01efd524fd3e 275 | md"Vemos que la incertidumbre sube mucho a medida que el precio baja! Veamos que pasa con otro valor de P, por ejemplo 4000" 276 | 277 | # ╔═╡ 7fe7bda0-46ca-4574-a6ca-21304fd54cda 278 | cantidades_p_4000 = q[findfirst(isequal(4000), p), : ] 279 | 280 | # ╔═╡ 8dd3331a-8e32-4ee7-89c3-6032034ac2d9 281 | ganancias_p_4000 = ganancia[findfirst(isequal(4000), p), :] 282 | 283 | # ╔═╡ 740f553d-3c0e-4a72-ba06-ae25a47babd4 284 | mean(ganancias_p_4000) #ganancia media con precio = $4000 285 | 286 | # ╔═╡ 7f7f59f0-cd07-4538-badf-a7dfaec29409 287 | desfavorable_4000 = mean(ganancias_p_4000) - std(ganancias_p_4000) 288 | 289 | # ╔═╡ edf807ac-d41e-4068-be49-2cee7a52f042 290 | favorable_4000 = mean(ganancias_p_4000) + std(ganancias_p_4000) 291 | 292 | # ╔═╡ 422a9120-40ee-46b0-a701-f3dfa8355ee4 293 | begin 294 | plot() 295 | 296 | for i in collect(1:length(post_c[1])) 297 | plot!(p,ganancia[:,i], color="blue", label=false, alpha = 0.1) 298 | end 299 | 300 | plot!(p,mean(ganancia, dims=2) + std(ganancia, dims=2), color = "orange", lw=2, label =s2) 301 | 302 | plot!(p,mean(ganancia, dims=2), color = "red", lw=4, label=s) 303 | 304 | plot!(p,mean(ganancia, dims=2) - std(ganancia, dims=2), color = "orange", lw=2, label="") 305 | 306 | vline!([4000], [4000], line = (:purple, 3), label=false) 307 | vline!(p[mxindx], p[mxindx], line = (:black, 3), label=s3) 308 | xlabel!("Precio") 309 | ylabel!("Ganancia") 310 | plot!(legend=true) 311 | end 312 | 313 | # ╔═╡ 5e3a7c87-36c3-421d-bd2b-f9853ed169f3 314 | md"Entonces, en el caso de elegir el precio de $4000 obtenemos una disminución porcentual de la ganancia media del:" 315 | 316 | # ╔═╡ bad71016-9962-43ae-90ac-a127cb235105 317 | dif_porcen_genancia_media = ((mean(ganancias_p_4000) - mxval[1]) / mxval[1]) * 100 318 | 319 | # ╔═╡ ad7d8705-7dc2-42e9-a776-adad044ab384 320 | dif_porcentual_desfavorable = (desfavorable_4000 - desfavorable)/desfavorable * 100 321 | 322 | # ╔═╡ 42ca7571-6d17-4554-ab96-858d630518a7 323 | dif_porcentual_desfavorable / dif_porcen_genancia_media 324 | 325 | # ╔═╡ 4ebe5f54-1630-4e85-9f61-bd3cf8e71637 326 | md"Lo que nos indica que por cada peso que perdemos en ganancia media, ganamos más del doble en reducción de la variabilidad!" 327 | 328 | # ╔═╡ 9946d1ef-358c-4a57-a536-b4d5c26999bd 329 | md"### Referencias 330 | 331 | - [Chad Scherrer Bayesian Optimal Pricing Post](https://cscherrer.github.io/post/max-profit/) 332 | - [Capítulo 9, Data science in Julia for Hackers](https://datasciencejuliahackers.com/09_optimal_pricing.jl.html) 333 | 334 | " 335 | 336 | # ╔═╡ Cell order: 337 | # ╟─c42c63d2-a615-11eb-094c-07ffc56e14b0 338 | # ╟─93ea39ee-6aa6-41f2-8ece-7b3715a9a060 339 | # ╠═d6a37b99-ab94-4d41-9147-ef7c0b695704 340 | # ╠═ae70c258-249f-4a1e-9bcc-f778dad4146e 341 | # ╟─e8856141-2d30-41c6-80af-e05f434f69fd 342 | # ╠═acc3e9f5-5ddd-4fab-8536-471aee398eb2 343 | # ╟─55100ed9-c4dc-4b3f-9832-e412b6299149 344 | # ╠═4605184e-a890-44ce-b51f-751f10cdc1e7 345 | # ╠═e38aca18-0098-4cb5-9229-1f639c8243ca 346 | # ╠═6d14330d-134b-44e7-b929-d3328d32889d 347 | # ╟─6b5f7859-8f6d-48f2-b027-0df88f504ea0 348 | # ╠═f6546947-a5f0-43b1-bc18-bd7bad36b82a 349 | # ╠═f45fbaf8-02d0-4cd4-971f-a1b058d011cd 350 | # ╟─c6e56884-4853-4c90-8e72-0caae4ad0844 351 | # ╠═3fb416de-79eb-4950-a0b2-040c04619228 352 | # ╠═8a08fe88-184f-4d64-9fc5-abe87a9c8422 353 | # ╠═8fe80c8a-023e-486d-bcbd-bb2244a26356 354 | # ╟─27fd6af3-0864-4276-a7c6-a4ee2896dcbe 355 | # ╟─8f3f610c-cc20-4f74-ba90-8af10cbf74bc 356 | # ╠═a41ed419-0fd0-4d0f-8ea9-5f9347fca281 357 | # ╠═9044ccbe-f2a6-4fcd-8894-8fe943f78b55 358 | # ╠═9e2d40f3-d971-4b21-8f75-e22fe8e1bc43 359 | # ╟─3675d864-5169-46fb-b4fd-4191a84e33a3 360 | # ╠═c6e0c9ef-86c8-4d8e-9d08-82beb3d03668 361 | # ╠═4f551424-e5aa-49c6-b27b-06c6058c9ac9 362 | # ╠═6105a2c4-9e3f-4e4f-a028-3bac8a758bf3 363 | # ╠═402d63a8-cf38-4a1e-8e24-0c8e72d1f8f2 364 | # ╠═2848ff96-39ce-4b98-a58c-0021971743a9 365 | # ╠═280f65a6-9ef6-4b34-9b9c-d22d7d141183 366 | # ╠═6364fa28-0737-43f2-b5d4-5f743ce64ea1 367 | # ╠═3f7e3b90-f964-4819-966f-c3190b1f428f 368 | # ╟─d9ab2acf-7fc7-4b57-b596-629e8f4e50ea 369 | # ╠═839f838d-b2fe-48bb-a47d-79c7f71ff7a3 370 | # ╠═43f52222-be42-4042-b9da-a95bd61a86e8 371 | # ╟─7517412b-0196-4727-a787-01efd524fd3e 372 | # ╠═7fe7bda0-46ca-4574-a6ca-21304fd54cda 373 | # ╠═8dd3331a-8e32-4ee7-89c3-6032034ac2d9 374 | # ╠═740f553d-3c0e-4a72-ba06-ae25a47babd4 375 | # ╠═7f7f59f0-cd07-4538-badf-a7dfaec29409 376 | # ╠═edf807ac-d41e-4068-be49-2cee7a52f042 377 | # ╠═422a9120-40ee-46b0-a701-f3dfa8355ee4 378 | # ╟─5e3a7c87-36c3-421d-bd2b-f9853ed169f3 379 | # ╠═bad71016-9962-43ae-90ac-a127cb235105 380 | # ╠═ad7d8705-7dc2-42e9-a776-adad044ab384 381 | # ╠═42ca7571-6d17-4554-ab96-858d630518a7 382 | # ╟─4ebe5f54-1630-4e85-9f61-bd3cf8e71637 383 | # ╟─9946d1ef-358c-4a57-a536-b4d5c26999bd 384 | -------------------------------------------------------------------------------- /Clase-4/Clase_4.jl: -------------------------------------------------------------------------------- 1 | ### A Pluto.jl notebook ### 2 | # v0.14.2 3 | 4 | using Markdown 5 | using InteractiveUtils 6 | 7 | # ╔═╡ add40067-e4fd-463a-af40-ebb8452b9aca 8 | begin 9 | using JSON 10 | using DataFrames 11 | end 12 | 13 | # ╔═╡ d0f2202e-ea5a-4bc9-b7b1-d52ed628f48a 14 | using Turing 15 | 16 | # ╔═╡ 2b99e438-8848-449b-af30-3c5f68c32606 17 | using LinearAlgebra 18 | 19 | # ╔═╡ 814ee63a-ad3d-11eb-2e73-f5f95c27e1fc 20 | md""" 21 | 22 | # Cuarta clase del curso de ciencia de datos del MLI 23 | 24 | ## Plan de Trabajo 25 | 26 | ### Primera clase (ok) 27 | 28 | - ¿Por qué Julia? 29 | - Primeros pasos 30 | - Herramientas básicas para ciencia de datos 31 | 32 | ### Segunda clase (ok) 33 | 34 | - Introducción a la estadística bayesiana 35 | - Introducción a la programación probabilistica 36 | - Algunas nociones de distribuciones de probabilidad 37 | - **Aplicación**: detección y ubicación temporal para el cambio en la tasa de arrivo de clientes a un local 38 | 39 | ### Tercera clase (ok) 40 | 41 | - Profundización conceptual de la estadística bayesiana 42 | - Cuantificación de la incertidumbre del modelo 43 | - **Aplicación**: Modelo para elección del precio óptimo de un producto contando con una prueba piloto. Análisis ingreso/varianza. 44 | 45 | ### Cuarta clase 46 | 47 | - Modelos bayesianos jerárquicos 48 | - **Aplicación**: Modelado en deportes. Modelo analítico para la premier league. Simulación de partidos y predicción.""" 49 | 50 | # ╔═╡ c12d3d77-25d5-4561-9172-0e9db8ad119b 51 | md"""#### Modelos Jerárquicos 52 | 53 | - Nos permiten modelar relaciones más abstractas 54 | - Hasta ahora, siempre hubo una distribución que "generaba" los datos". Esa distribución tenía parámetros a los que le asignábamos distribuciones prior. 55 | - Ahora, a los parámetros de nuestra distribución prior para los parámetros de la distribución que genera los datos de la "realidad", se le asigna otra distribución prior. 56 | - Nos permite inferir variables **letentes**: Por ejemplo, en economía, "calidad de vida" """ 57 | 58 | # ╔═╡ 62b21692-c9b7-4cd7-bc9a-fafab68b1d05 59 | begin 60 | england_league = JSON.parsefile("matches_England.json") 61 | matches_df = DataFrame(home = [], away = [], score_home = [], score_away = []) 62 | end; 63 | 64 | # ╔═╡ 00bd28b6-737a-4291-854f-d6b7bc3c6b2a 65 | begin 66 | matches = [] 67 | for match in england_league 68 | push!(matches, split(match["label"], ",")) 69 | end 70 | end 71 | 72 | # ╔═╡ 8bc3335e-27f3-4dc8-b010-b54b4192c835 73 | begin 74 | for match in matches 75 | home, away = split(match[1], " - ") 76 | score_home, score_away = split(match[2], " - ") 77 | 78 | push!(matches_df,[home, away, parse(Int,score_home), parse(Int,score_away)]) 79 | end 80 | end 81 | 82 | # ╔═╡ eaaa7424-facd-4020-af15-b105e59741b1 83 | matches_df 84 | 85 | # ╔═╡ ab3d8089-e549-4a8e-b4e9-302b6cdec268 86 | teams = unique(collect(matches_df[:,1])) 87 | 88 | # ╔═╡ d514149e-de9b-4b58-8655-58790a97100c 89 | md"- Para nuestro modelo, vamos a modelar a los goles realizados por un equipo mediante una distribución de $Poisson$" 90 | 91 | # ╔═╡ 82b4487f-ebf6-4fc3-9ebb-bc7552643f12 92 | begin 93 | @model function football_matches(home_teams, away_teams, score_home, score_away, teams) 94 | #hyper priors 95 | σatt ~ Exponential(1) 96 | σdeff ~ Exponential(1) 97 | μatt ~ Normal(0,0.1) 98 | μdef ~ Normal(0,0.1) 99 | 100 | home ~ Normal(0,1) 101 | 102 | #Team-specific effects 103 | att ~ filldist(Normal(μatt, σatt), length(teams)) 104 | def ~ filldist(Normal(μatt, σdeff), length(teams)) 105 | 106 | dict = Dict{String, Int64}() 107 | for (i, team) in enumerate(teams) 108 | dict[team] = i 109 | end 110 | 111 | #Zero-sum constrains 112 | offset = mean(att) + mean(def) 113 | 114 | log_θ_home = Vector{Real}(undef, length(home_teams)) 115 | log_θ_away = Vector{Real}(undef, length(home_teams)) 116 | 117 | #Modeling score-rate and scores (as many as there were games in the league) 118 | for i in 1:length(home_teams) 119 | #score-rate 120 | log_θ_home[i] = home + att[dict[home_teams[i]]] + def[dict[away_teams[i]]] - offset 121 | log_θ_away[i] = att[dict[away_teams[i]]] + def[dict[home_teams[i]]] - offset 122 | #scores 123 | score_home[i] ~ LogPoisson(log_θ_home[i]) 124 | score_away[i] ~ LogPoisson(log_θ_away[i]) 125 | end 126 | 127 | end 128 | end 129 | 130 | # ╔═╡ 4abd669a-cf74-48ce-9362-b7e6ae2e04d7 131 | model = football_matches(matches_df[:,1], matches_df[:,2], matches_df[:,3], matches_df[:,4], teams) 132 | 133 | # ╔═╡ f20cb54d-da70-401c-9d05-4a4badf8d80d 134 | posterior = sample(model, NUTS(),3000); 135 | 136 | # ╔═╡ 26dbb558-6a0d-4d46-b103-38624b02ff54 137 | begin 138 | table_positions = 139 | [11, 5, 9, 4, 13, 14, 1, 15, 12, 6, 2, 16, 10, 17, 20, 3, 7, 8, 19, 18] 140 | 141 | games_won = 142 | [32, 25, 23, 21, 21, 19, 14, 13, 12, 12, 11, 11, 10, 11, 9, 9, 7, 8, 7, 6] 143 | 144 | teams_ = [] 145 | for i in table_positions 146 | push!(teams_, teams[i]) 147 | end 148 | 149 | table_position_df = DataFrame(Table_of_positions = teams_, Wins = games_won) 150 | 151 | end 152 | 153 | # ╔═╡ 94fd4533-5cd3-4533-a951-c3fc6c1748cd 154 | begin 155 | post_att = collect(get(posterior, :att)[1]) 156 | post_def = collect(get(posterior, :def)[1]) 157 | post_home = collect(get(posterior, :home)[1]) 158 | end; 159 | 160 | # ╔═╡ 1250bf45-a687-485d-b2fb-fa2e0cc59da5 161 | begin 162 | using Plots 163 | gr() 164 | histogram(post_home, legend=false, title="Posterior distribution of home parameter") 165 | end 166 | 167 | # ╔═╡ c17f7e9b-ade1-4056-9505-c662ea30e62a 168 | mean(post_home) 169 | 170 | # ╔═╡ 394cb607-db4c-4276-b234-fca65dc2a53a 171 | begin 172 | teams_att = [] 173 | teams_def = [] 174 | for i in 1:length(post_att) 175 | push!(teams_att, post_att[i]) 176 | push!(teams_def, post_def[i]) 177 | end 178 | end 179 | 180 | # ╔═╡ 54163b71-ad66-404b-ad3a-d6e1719df7ec 181 | teams_att 182 | 183 | # ╔═╡ e057c589-45c0-4224-840a-835941fe8c1a 184 | teams[1] 185 | 186 | # ╔═╡ cfe96e6e-fa9b-421a-aba0-ba2f58366528 187 | histogram(teams_att[1], legend=false, title="Posterior distribution of Burnley´s attack power") 188 | 189 | # ╔═╡ 44a15b43-d2b9-49c6-9baf-586509889e7b 190 | teams[11] 191 | 192 | # ╔═╡ f591a93e-499a-40d7-ade9-12ff139718b9 193 | begin 194 | histogram(teams_att[11], legend=false, title="Posterior distribution of Manchester City´s attack power") 195 | end 196 | 197 | # ╔═╡ a020deb0-40e6-4a9b-abf1-7722712235d7 198 | mean(teams_att[11]) 199 | 200 | # ╔═╡ 8be72413-3450-45f5-b493-c1970e67895d 201 | begin 202 | teams_att_μ = mean.(teams_att) 203 | teams_def_μ = mean.(teams_def) 204 | teams_att_σ = std.(teams_att) 205 | teams_def_σ = std.(teams_def) 206 | end; 207 | 208 | # ╔═╡ da8731ef-f963-429d-b184-642827239f04 209 | begin #ocultar 210 | teams_att_μ 211 | sorted_att = sortperm(teams_att_μ) 212 | abbr_names = [t[1:3] for t in teams] 213 | end; 214 | 215 | # ╔═╡ e0475968-868b-4af6-b09b-c4e7e32a46a8 216 | sorted_names = abbr_names[sorted_att] 217 | 218 | # ╔═╡ 6be2a414-78cd-4fac-b438-17141d4acf4c 219 | begin 220 | scatter(1:20, teams_att_μ[sorted_att], grid=false, legend=false, yerror=teams_att_σ[sorted_att], color=:blue, title="Premier league 17/18 teams attack power") 221 | annotate!([(x, y + 0.238, text(team, 8, :center, :black)) for (x, y, team) in zip(1:20, teams_att_μ[sorted_att], sorted_names)]) 222 | 223 | ylabel!("Mean team attack") 224 | end 225 | 226 | # ╔═╡ fb67b249-a276-485a-967f-e347adda3118 227 | begin #ocultar 228 | sorted_def = sortperm(teams_def_μ) 229 | sorted_names_def = abbr_names[sorted_def] 230 | end 231 | 232 | # ╔═╡ afb45641-c8cb-4ed7-a8ba-a6c1b2c8b427 233 | begin 234 | scatter(1:20, teams_def_μ[sorted_def], grid=false, legend=false, yerror=teams_def_σ[sorted_def], color=:blue, title="Premier league 17/18 teams defence power") 235 | annotate!([(x, y + 0.2, text(team, 8, :center, :black)) for (x, y, team) in zip(1:20, teams_def_μ[sorted_def], sorted_names_def)]) 236 | ylabel!("Mean team defence") 237 | end 238 | 239 | # ╔═╡ e6c1b2a7-dbf4-42b0-af03-03688d773e34 240 | begin #ocultar 241 | table_position = 242 | [11, 5, 9, 4, 13, 14, 1, 15, 12, 6, 2, 16, 10, 17, 20, 3, 7, 8, 19, 18] 243 | position = sortperm(table_position) 244 | end 245 | 246 | # ╔═╡ 35620e16-5737-4786-9fb2-2b40153844b4 247 | begin 248 | scatter(teams_att_μ, teams_def_μ, legend=false) 249 | annotate!([(x, y + 0.016, text(team, 6, :center, :black)) for (x, y, team) in zip(teams_att_μ, teams_def_μ, abbr_names)]) 250 | 251 | annotate!([(x, y - 0.016, text(team, 5, :center, :black)) for (x, y, team) in zip(teams_att_μ, teams_def_μ, position)]) 252 | 253 | xlabel!("Mean team attack") 254 | ylabel!("Mean team defence") 255 | end 256 | 257 | # ╔═╡ cb9bf807-72e5-48ad-8169-4d1e26ce834e 258 | md"### Simulando posibles realidades" 259 | 260 | # ╔═╡ 8b2c385a-ff24-45bd-b591-822232645f9f 261 | begin 262 | mci_att_post = collect(get(posterior, :att)[:att])[11][:,1]; 263 | mci_def_post = collect(get(posterior, :def)[:def])[11][:,1]; 264 | liv_att_post = collect(get(posterior, :att)[:att])[4][:,1]; 265 | liv_def_post = collect(get(posterior, :def)[:def])[4][:,1]; 266 | end 267 | 268 | # ╔═╡ c32c8de1-59ec-42c1-a328-b51b06948dc6 269 | begin 270 | ha1 = histogram(mci_att_post, title="Manchester City attack", legend=false) 271 | ha2 = histogram(liv_att_post, title="Liverpool attack", legend=false) 272 | plot(ha1, ha2, layout=(1,2)) 273 | end 274 | 275 | # ╔═╡ 94f3714e-5589-4722-9a77-72b51d38e6b2 276 | begin 277 | hd1 = histogram(mci_def_post, title="Manchester City defense", legend=false) 278 | hd2 = histogram(liv_def_post, title="Liverpool defense", legend=false) 279 | plot(hd1, hd2, layout=(1,2)) 280 | end 281 | 282 | # ╔═╡ 6e9b0748-9266-46b1-bb17-2b2a4804c3f5 283 | # This function simulates matches given the attack, defense and home parameters. 284 | # The first pair of parameters alwas correspond to the home team. 285 | 286 | function simulate_matches_(att₁, def₁, att₂, def₂, home, n_matches, home_team = 1) 287 | if home_team == 1 288 | logθ₁ = home + att₁ + def₂ 289 | logθ₂ = att₂ + def₁ 290 | 291 | elseif home_team == 2 292 | logθ₁ = att₁ + def₂ 293 | logθ₂ = home + att₂ + def₁ 294 | else 295 | return DomainError(home_team, "Invalid home_team value") 296 | end 297 | 298 | scores₁ = rand(LogPoisson(logθ₁), n_matches) 299 | scores₂ = rand(LogPoisson(logθ₂), n_matches) 300 | 301 | results = [(s₁, s₂) for (s₁, s₂) in zip(scores₁, scores₂)] 302 | 303 | return results 304 | end 305 | 306 | # ╔═╡ 3209f5b4-f46b-46c8-8a0c-a02e535b9448 307 | simulate_matches_(0.75, -0.53, 0.1, 0.1, 0.3, 10) 308 | 309 | # ╔═╡ fa821028-0f1f-48ad-b829-12e15a9c1c05 310 | function simulate_matches(team1_att_post, team1_def_post, team2_att_post, team2_def_post, home_post, n_matches) 311 | 312 | team1_as_home_results = Tuple{Int64,Int64}[] 313 | team2_as_home_results = Tuple{Int64,Int64}[] 314 | 315 | for (t1_att, t1_def, t2_att, t2_def, home) in zip(team1_att_post, team1_def_post, 316 | team2_att_post, team2_def_post, 317 | home_post) 318 | 319 | team1_as_home_results = vcat(team1_as_home_results, 320 | simulate_matches_(t1_att, t1_def, t2_att, 321 | t2_def, home, n_matches, 1)) 322 | 323 | team2_as_home_results = vcat(team2_as_home_results, 324 | simulate_matches_(t1_att, t1_def, t2_att, t2_def, home, n_matches, 2)) 325 | end 326 | 327 | max_t1_as_home = maximum(map(x -> x[1], team1_as_home_results)) 328 | max_t2_as_away = maximum(map(x -> x[2], team1_as_home_results)) 329 | 330 | max_t1_as_away = maximum(map(x -> x[1], team2_as_home_results)) 331 | max_t2_as_home = maximum(map(x -> x[2], team2_as_home_results)) 332 | 333 | matrix_t1_as_home = zeros(Float64, (max_t1_as_home + 1, max_t2_as_away + 1)) 334 | matrix_t2_as_home = zeros(Float64, (max_t1_as_away + 1, max_t2_as_home + 1)) 335 | 336 | for match in team1_as_home_results 337 | matrix_t1_as_home[match[1] + 1, match[2] + 1] += 1 338 | end 339 | 340 | normalize!(matrix_t1_as_home, 1) 341 | 342 | for match in team2_as_home_results 343 | matrix_t2_as_home[match[1] + 1, match[2] + 1] += 1 344 | end 345 | 346 | normalize!(matrix_t2_as_home, 1) 347 | 348 | return matrix_t1_as_home, matrix_t2_as_home 349 | end 350 | 351 | # ╔═╡ dd94c11d-963a-4b68-b226-d64b90833b5b 352 | simulate_matches_(0.75, -0.35, 0.55, -0.2, 0.33, 1000, 2) 353 | 354 | # ╔═╡ fab1a81b-0e47-4d4c-847e-3a5c743f2639 355 | mci_as_home_simulations, 356 | liv_as_home_simulations = simulate_matches(mci_att_post, mci_def_post, 357 | liv_att_post, liv_def_post, post_home, 1000) 358 | 359 | # ╔═╡ 1c4a8804-b681-44ed-ab26-0ef7460604fa 360 | function match_heatmaps(matrix_t1_as_home, matrix_t2_as_home, 361 | team1_name="Team 1", team2_name="Team 2") 362 | gr() 363 | 364 | x_t1_home = string.(0:10) 365 | y_t1_home = string.(0:10) 366 | heat_t1_home = heatmap(x_t1_home, 367 | y_t1_home, 368 | matrix_t1_as_home[1:11, 1:11], 369 | xlabel="$team2_name score", ylabel="$team1_name score", 370 | title="$team1_name as home") 371 | 372 | x_t2_home = string.(0:10) 373 | y_t2_home = string.(0:10) 374 | heat_t2_home = heatmap(x_t2_home, 375 | y_t2_home, 376 | matrix_t2_as_home[1:11, 1:11], 377 | xlabel="$team2_name score", ylabel="$team1_name score", 378 | title="$team2_name as home") 379 | 380 | plot(heat_t1_home, heat_t2_home, layout=(1,2), size=(900, 300)) 381 | current() 382 | end 383 | 384 | # ╔═╡ 396ec5a4-d02a-4b9f-8771-497b95c90e5e 385 | match_heatmaps(mci_as_home_simulations, liv_as_home_simulations, "Manchester City", "Liverpool") 386 | 387 | # ╔═╡ 015b70a7-efe4-4009-8cbd-bf8e98e28033 388 | function win_and_lose_probability(simulation) 389 | 390 | team1_winning_prob = 0 391 | team2_winning_prob = 0 392 | draw_prob = 0 393 | 394 | for i in 1:size(simulation, 1) 395 | for j in 1:size(simulation, 2) 396 | if i > j 397 | team1_winning_prob += simulation[i,j] 398 | elseif i < j 399 | team2_winning_prob += simulation[i,j] 400 | else 401 | draw_prob += simulation[i,j] 402 | end 403 | end 404 | end 405 | 406 | return team1_winning_prob, team2_winning_prob, draw_prob 407 | end 408 | 409 | # ╔═╡ 44938842-0d30-45de-969b-50e8148b9778 410 | win_and_lose_probability(liv_as_home_simulations) 411 | 412 | # ╔═╡ 8d2b3fa7-d5fa-4070-87f6-732430788364 413 | win_and_lose_probability(mci_as_home_simulations) 414 | 415 | # ╔═╡ Cell order: 416 | # ╟─814ee63a-ad3d-11eb-2e73-f5f95c27e1fc 417 | # ╟─c12d3d77-25d5-4561-9172-0e9db8ad119b 418 | # ╠═add40067-e4fd-463a-af40-ebb8452b9aca 419 | # ╠═62b21692-c9b7-4cd7-bc9a-fafab68b1d05 420 | # ╠═00bd28b6-737a-4291-854f-d6b7bc3c6b2a 421 | # ╠═8bc3335e-27f3-4dc8-b010-b54b4192c835 422 | # ╠═eaaa7424-facd-4020-af15-b105e59741b1 423 | # ╠═ab3d8089-e549-4a8e-b4e9-302b6cdec268 424 | # ╟─d514149e-de9b-4b58-8655-58790a97100c 425 | # ╠═d0f2202e-ea5a-4bc9-b7b1-d52ed628f48a 426 | # ╠═82b4487f-ebf6-4fc3-9ebb-bc7552643f12 427 | # ╠═4abd669a-cf74-48ce-9362-b7e6ae2e04d7 428 | # ╠═f20cb54d-da70-401c-9d05-4a4badf8d80d 429 | # ╠═26dbb558-6a0d-4d46-b103-38624b02ff54 430 | # ╠═94fd4533-5cd3-4533-a951-c3fc6c1748cd 431 | # ╠═1250bf45-a687-485d-b2fb-fa2e0cc59da5 432 | # ╠═c17f7e9b-ade1-4056-9505-c662ea30e62a 433 | # ╠═394cb607-db4c-4276-b234-fca65dc2a53a 434 | # ╠═54163b71-ad66-404b-ad3a-d6e1719df7ec 435 | # ╠═e057c589-45c0-4224-840a-835941fe8c1a 436 | # ╠═cfe96e6e-fa9b-421a-aba0-ba2f58366528 437 | # ╠═44a15b43-d2b9-49c6-9baf-586509889e7b 438 | # ╠═f591a93e-499a-40d7-ade9-12ff139718b9 439 | # ╠═a020deb0-40e6-4a9b-abf1-7722712235d7 440 | # ╠═8be72413-3450-45f5-b493-c1970e67895d 441 | # ╠═da8731ef-f963-429d-b184-642827239f04 442 | # ╠═e0475968-868b-4af6-b09b-c4e7e32a46a8 443 | # ╠═6be2a414-78cd-4fac-b438-17141d4acf4c 444 | # ╠═fb67b249-a276-485a-967f-e347adda3118 445 | # ╠═afb45641-c8cb-4ed7-a8ba-a6c1b2c8b427 446 | # ╠═e6c1b2a7-dbf4-42b0-af03-03688d773e34 447 | # ╠═35620e16-5737-4786-9fb2-2b40153844b4 448 | # ╟─cb9bf807-72e5-48ad-8169-4d1e26ce834e 449 | # ╠═8b2c385a-ff24-45bd-b591-822232645f9f 450 | # ╠═c32c8de1-59ec-42c1-a328-b51b06948dc6 451 | # ╠═94f3714e-5589-4722-9a77-72b51d38e6b2 452 | # ╠═2b99e438-8848-449b-af30-3c5f68c32606 453 | # ╠═6e9b0748-9266-46b1-bb17-2b2a4804c3f5 454 | # ╠═3209f5b4-f46b-46c8-8a0c-a02e535b9448 455 | # ╠═fa821028-0f1f-48ad-b829-12e15a9c1c05 456 | # ╠═dd94c11d-963a-4b68-b226-d64b90833b5b 457 | # ╠═fab1a81b-0e47-4d4c-847e-3a5c743f2639 458 | # ╠═1c4a8804-b681-44ed-ab26-0ef7460604fa 459 | # ╠═396ec5a4-d02a-4b9f-8771-497b95c90e5e 460 | # ╠═015b70a7-efe4-4009-8cbd-bf8e98e28033 461 | # ╠═44938842-0d30-45de-969b-50e8148b9778 462 | # ╠═8d2b3fa7-d5fa-4070-87f6-732430788364 463 | -------------------------------------------------------------------------------- /Clase_2.jl: -------------------------------------------------------------------------------- 1 | ### A Pluto.jl notebook ### 2 | # v0.14.2 3 | 4 | using Markdown 5 | using InteractiveUtils 6 | 7 | # This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). 8 | macro bind(def, element) 9 | quote 10 | local el = $(esc(element)) 11 | global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : missing 12 | el 13 | end 14 | end 15 | 16 | # ╔═╡ 265639fb-4d6f-4785-b842-1413a4cee7ee 17 | using Distributions, Plots, StatsPlots 18 | 19 | # ╔═╡ bdfa8154-0a1b-4a80-b147-70f076d7eac2 20 | using Turing 21 | 22 | # ╔═╡ 8fe1e658-f674-4bcd-88b8-b4611b231b5a 23 | using CSV, DataFrames 24 | 25 | # ╔═╡ 04db4d81-90bd-48ee-a0f9-7101cddec9ae 26 | begin 27 | using Random 28 | 29 | Random.seed!(123) 30 | 31 | data = vcat([i <= 36 ? rand(Poisson(10), 1)[1] : rand(Poisson(15), 1)[1] for i in 1:74]) 32 | 33 | data_df = DataFrame(col1 = data) 34 | 35 | #CSV.write("data.csv", data_df, writeheader=false) 36 | end; 37 | 38 | # ╔═╡ 1b6013d8-9fc0-11eb-198a-c709f6caab97 39 | md"# Segunda clase del curso de ciencia de datos del MLI 40 | 41 | ## Plan de Trabajo 42 | 43 | ### Primera clase (ok) 44 | - ¿Por qué Julia? 45 | - Primeros pasos 46 | - Herramientas básicas para ciencia de datos 47 | 48 | ### Segunda clase 49 | - Introducción a la estadística bayesiana 50 | - Introducción a la programación probabilistica 51 | - Algunas nociones de distribuciones de probabilidad 52 | - **Aplicación**: detección y ubicación temporal para el cambio en la tasa de arrivo de clientes a un local 53 | 54 | ### Tercera clase 55 | - Profundización conceptual de la estadística bayesiana 56 | - Cuantificación de la incertidumbre del modelo 57 | - **Aplicación**: Modelo para elección del precio óptimo de un producto contando con una prueba piloto. Análisis ingreso/varianza. 58 | 59 | ### Cuarta clase 60 | - Modelos bayesianos jerárquicos 61 | - **Aplicación**: Modelado en deportes. Modelo analítico para la premier league. Simulación de partidos y predicción. 62 | " 63 | 64 | # ╔═╡ 415aa9c5-0fa4-4af3-910c-3eb2ebc5f13c 65 | md"""### Estadística Bayesiana 66 | 67 | ##### Conceptos generales 68 | 69 | - **Noción de probabilidad**: Grado de certeza (o incerteza) que tenemos ante algún evento. 70 | 71 | - Como en "la vida real", se comienza un grado de certeza (o probabilidad) a *priori* de dicho evento. 72 | 73 | - Se contrasta con los datos y se actualiza nuestra creencia. Se obtiene así la nueva probabilidad (creencia) a *posteriori*. 74 | 75 | ##### Y otros un poco más técnicos 76 | 77 | - El mismo proceso se puede dar con **distribuciones de probabilidad** 78 | 79 | - Se cree que algún proceso de la realidad sigue una determinada distribución, pero no conocemos sus *parámetros*. A estos le asignamos una distribución a priori. 80 | - Se contrasta con los datos y se obtiene una distribución a posteriori 81 | """ 82 | 83 | # ╔═╡ 6641dc40-496b-4e7e-affe-aef0bf082ac0 84 | md" 85 | ¿Qué es una distribución de probabilidad? 86 | 87 | Le asigna un valor de probabilidad a cada valor posible de x. Por ejemplo, si tomamos que $x$ es el valor de la altura de las personas en Argentina, tenemos la siguiente distribución de probabilidad para las alturas: 88 | " 89 | 90 | # ╔═╡ abc220ef-b2ec-4322-9610-ecee32e9f204 91 | md" 92 | * Media: 93 | " 94 | 95 | # ╔═╡ 922fff4e-7ced-48d4-b724-e9729ebbf7b6 96 | @bind μ html"" 97 | 98 | # ╔═╡ 11b299a9-d10e-4660-86d8-902df0faba4f 99 | md" 100 | * Desvio: 101 | " 102 | 103 | # ╔═╡ 1ed7e2c4-7f48-492f-b65e-b26b09d6c5d1 104 | @bind σ html"" 105 | 106 | # ╔═╡ 9902d655-4aa1-4902-9da3-f5e4bbfe864b 107 | begin 108 | plot(Normal(μ, σ), xlim=(1, 2.5), xlabel="Altura", ylabel="Probabilidad", title="Distribución de probabilidad de alturas", legend=false, size=(500, 300)) 109 | end 110 | 111 | # ╔═╡ f9e829ed-ed1b-40ca-9f42-6503c3960163 112 | md"### ¿La moneda está cargada?" 113 | 114 | # ╔═╡ 04883759-9066-4838-87b2-48e57f0b6c03 115 | md"La pregunta que queremos responder: ¿es igualmente probable sacar cara o ceca?" 116 | 117 | # ╔═╡ ca547033-0f21-41fb-b264-66c9a60927c7 118 | md"##### Distribución Binomial 119 | 120 | - Modeliza una seguidilla de experimentos (llamados experimentos de Bernoulli) donde hay dos posibilidades con una probabilidad de ocurrencia $p$ para *éxito* y $1-p$ para *fracaso*, en nuestro caso, cara o ceca. 121 | 122 | - La cuestión aquí es que justamente **no** sabemos la probabilidad $p$ de éxito, que en el caso de que la moneda no estuviera adulterada sería $p = 1 - p = 0.5$." 123 | 124 | # ╔═╡ c8849fd9-650d-40de-bf08-5dc0600ef5a6 125 | md" 126 | Pensemos un experimento donde tiramos una moneda 100 veces y anotamos cuántas veces obtenemos 'cara'. 127 | " 128 | 129 | # ╔═╡ 6bbe995a-04ca-4217-a027-6c31d22951f5 130 | plot(Binomial(100,0.5), legend=false, xlabel="Número de éxitos", ylabel="Probabilidad", size=(500, 300)) 131 | 132 | # ╔═╡ 6832b13d-01dc-4fa4-ba87-18ad985e5e81 133 | md" 134 | Como no confiamos en que la moneda este equilibrada, vamos a suponer una distribución uniforme(0,1) para la probabilidad de éxito. Esto es equivalente a decir que no sabemos nada sobre la moneda" 135 | 136 | # ╔═╡ 5bb9c585-6e88-4375-8209-ea82b1733a68 137 | begin 138 | plot(Uniform(0, 1), ylim=(0, 2), xlabel="Probabilidad de obtener cara (éxito)", ylabel="Probabilidad", title="Distribución Uniforme", label=false, size=(500, 300)) 139 | end 140 | 141 | # ╔═╡ 0e64f052-6aae-4f03-bce0-6c9851bc0c81 142 | md"##### Armemos nuestro modelo" 143 | 144 | # ╔═╡ 37e83672-7d9d-471b-8c40-750e7b0a902b 145 | begin 146 | @model tirada_moneda(y) = begin 147 | # Nuestra creencia a priori sobre la probabilidad que salga cara 148 | p ~ Uniform(0, 1) 149 | 150 | # Número de veces que la vamos a tirar para estimar la probabilidad 151 | N = length(y) 152 | for n in 1:N 153 | # Tiradas de moneda se modeliza con una bernoulli 154 | y[n] ~ Bernoulli(p) 155 | end 156 | end 157 | end 158 | 159 | # ╔═╡ 0e2a3617-e922-41e9-8068-8c0bd94705aa 160 | md" 161 | Asociamos: 162 | * Cara => 1 163 | * Ceca => 0 164 | 165 | Después de hacer 10 tiradas con la moneda y registrar lo obtenido, tenemos: 166 | " 167 | 168 | # ╔═╡ 8de48e1c-3fb8-4a02-a838-50a471847db9 169 | tiradas_moneda = [0, 1, 1, 0, 1, 0, 0, 1, 1, 1] 170 | 171 | # ╔═╡ 90e8516f-acca-454b-b862-46f8e8d3a5ae 172 | md" 173 | En vez de tener que hacer las cuentas analíticamente (hay integrales muy feas involucradas), el desarrollo de la computación moderna nos permite poder resolver el problema de una manera alternativa. 174 | La distribución posterior (o lo que es lo mismo, nuestra creencia actualizada) puede ser obtenida de manera aproximada usando una técnica de *sampling*. Los detalles de esta técnica no importan ahora, lo importante es entender que nos permite obtener, de manera aproximada, la distribución de probabilidad actualizada de nuestro problema. 175 | " 176 | 177 | # ╔═╡ 432ff5ee-82cb-4b77-8245-cabd8fb91510 178 | md" 179 | Veamos cómo queda nuestra creencia actualizada después de ver sólo el primer resultado de la tirada, usando el modelo que acabamos de crear. Nuestra creencia inicial o *prior* se va a ver modificada por los datos le mostremos a nuestro modelo. Veamoslo en el bloque de abajo, 180 | " 181 | 182 | # ╔═╡ 282e63f7-2a8c-44fc-9ad3-703e1c2902cf 183 | begin 184 | # Settings of the Hamiltonian Monte Carlo (HMC) sampler. 185 | iterations = 1000 186 | ϵ = 0.05 187 | τ = 10 188 | 189 | # Start sampling. 190 | chain = sample(tirada_moneda(tiradas_moneda[1]), HMC(ϵ, τ), iterations, progress=false) 191 | end; 192 | 193 | # ╔═╡ d1988a04-12cd-4b87-9b3e-7514f8cf0917 194 | histogram(chain[:p], normed=true, legend=false, size=(500, 300), 195 | title="Distribución a posteriori luego de sacar ceca", 196 | ylabel="Probabilidad", xlabel="p") 197 | 198 | # ╔═╡ bd9e5d11-d765-4c9d-9852-f0d5fb5c9ce4 199 | md" 200 | Esta distribución obtenida mediante sampling la podemos expresar como un histograma. La ventaja de este enfoque es que podemos obtener distribuciones que quizás nisiquiera tengan una fórmula analítica determinada, es decir, que la podamos expresar como una función de $p$. 201 | 202 | Aún sin tener la fórmula matemática exacta de esta distribución, el tenerla expresada como un histograma nos permite calcular probabilidades y en base a ello, tomar desiciones. Por ejemplo, la probabilidad de que la moneda esté cargada para el lado 'cara' puede ser computada sumando las probabilidades que existen de que $p$ esté entre $0.5$ y $1.0$ 203 | " 204 | 205 | # ╔═╡ 90256372-bc1d-4110-8409-94c4482d716f 206 | md" 207 | Veamos ahora cómo se va actualizando lo que sabemos sobre la moneda a medida que incluimos más, en el mdodelo, de los datos que obtuvimos haciendo nuestra tirada de monedas, 208 | " 209 | 210 | # ╔═╡ 1aef4447-e44e-4243-abec-fce1f3d7141b 211 | begin 212 | posterioris = [] 213 | for i in 2:10 214 | global cadena_ 215 | cadena_ = sample(tirada_moneda(tiradas_moneda[1:i]), HMC(ϵ, τ), iterations, progress=false) 216 | 217 | push!(posterioris, cadena_[:p]) 218 | end 219 | end; 220 | 221 | # ╔═╡ d085f9ec-9505-4555-976f-ff1ec3515257 222 | tiradas_moneda 223 | 224 | # ╔═╡ 934fd4a1-878f-4c62-b40a-48d1cefc48b6 225 | begin 226 | plots = histogram.(posterioris, normalized=true, legend=false, bins=10) 227 | 228 | p_ = plot(plots[1], plots[2], plots[3], plots[4], plots[5], plots[6], plots[7],plots[8], plots[9], layout = 9, 229 | title = ["$i tiradas" for j in 1:1, i in 2:10], 230 | titleloc = :right, titlefont = font(8), xlim=(0,1)) 231 | end 232 | 233 | # ╔═╡ 5d0d8c8f-9490-424e-ac3c-6feb7de7090d 234 | md" 235 | Vemos que a medida que incluimos más tiradas, el histograma que representa a nuestra creencia a posteriori se centra cada vez más alrededor del 0.5 236 | " 237 | 238 | # ╔═╡ c78828bf-fee8-4c6b-a4b6-89cf6571a348 239 | mean(posterioris[9]) 240 | 241 | # ╔═╡ 0dd77ba5-55f1-4faf-b03a-cd0933033830 242 | mas_tiradas = rand(Bernoulli(0.5), 100) 243 | 244 | # ╔═╡ f9245f36-25e9-4a0a-af81-7bf1ee92cd97 245 | cadena_2 = sample(tirada_moneda(mas_tiradas), HMC(ϵ, τ), iterations, progress=false); 246 | 247 | # ╔═╡ 31c3dc15-cb49-435b-9ae4-79604874ac24 248 | histogram(cadena_2[:p], normed=true, legend=false, size=(500, 300), 249 | title="Distribución a posteriori luego 100 tiradas", 250 | ylabel="Probabilidad", xlabel="p", xlim=(0,1)) 251 | 252 | # ╔═╡ 4563bd7f-1c69-4d55-a5f3-1d8196809823 253 | muchas_tiradas = rand(Bernoulli(0.5), 1000) 254 | 255 | # ╔═╡ fc4c1af7-8729-46dd-9a49-9a6dced100c3 256 | cadena_3 = sample(tirada_moneda(muchas_tiradas), HMC(ϵ, τ), iterations, progress=false); 257 | 258 | # ╔═╡ 03e2e6e4-c2c3-4c01-9bd9-429bbea239c7 259 | histogram(cadena_3[:p], normed=true, legend=false, size=(500, 300), 260 | title="Distribución a posteriori luego 1000 tiradas", 261 | ylabel="Probabilidad", xlabel="p", xlim=(0.4, 0.6)) 262 | 263 | # ╔═╡ 8ff5d846-26d1-47c1-b600-ec2b720bea3a 264 | mean(cadena_3[:p]) 265 | 266 | # ╔═╡ b9f6ef67-89f4-484a-9b90-fd31d003970d 267 | md"#### **Aplicación**: detección y ubicación temporal del cambio en la tasa de arrivo de clientes a un local" 268 | 269 | # ╔═╡ ed2bb374-862d-4d20-adf8-c302f34b0a17 270 | arrivos_df = DataFrame(CSV.File("data.csv", header=false)) 271 | 272 | # ╔═╡ c6742698-ccb2-4444-8a8a-a6e061da3e97 273 | arrivos = arrivos_df.Column1 274 | 275 | # ╔═╡ a387635e-8a42-4e32-96c0-5dec3d9c2ab6 276 | begin 277 | dias = collect(1:74) 278 | bar(dias, arrivos, legend=false, xlabel="Día", ylabel="Arrivos diarios de clientes", alpha=0.8) 279 | end 280 | 281 | # ╔═╡ 754ab16a-fb82-4a7b-8482-381892adc9e0 282 | @model function deteccion_cambio(x) 283 | N = length(x) 284 | μ1 ~ Exponential() 285 | μ2 ~ Exponential() 286 | τ ~ Uniform(0, N) 287 | for j in eachindex(x) 288 | if τ