├── 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 τ