-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprosa.Rmd
471 lines (338 loc) · 14.3 KB
/
prosa.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
---
title: "Analisi sul Dataset dei Pokemon"
author: "Massimiliano Baldo"
date: "25/8/2020"
output:
html_document:
df_print: paged
editor_options:
chunk_output_type: inline
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
# Introduzione
I Pokemon sono delle creature immaginarie che vivono a stretto contatto con gli umani.
Alcune volte sono impiegati nei lavori pubblici, altri nei concorsi e infine, l'ambito che interessa a noi, quello delle lotte.
Le informazioni importanti da sapere sui pokemon sono le seguenti:
- Ogni pokemon ha delle stastiche base (chiamate "stats") e includono:
+ HP = Punti Salute
+ ATK = Punti Attacco Fisico
+ DEF = Punti Difesa Fisica
+ SP_ATK = Punti Attacco Speciale
+ SP_DEF = Punti Difesa Speciale
+ SPD = Punti Velocità
- Ogni pokemon ha almeno un tipo (ovvero un elemento naturale), altri ne hanno 2.
- Ogni pokemon ha un livello che varia da 1 a 100 (estremi inclusi). Più un pokemon sale di livello, più le sue statistiche base aumentano.
- Alcuni pokemon posso evolversi: tale processo consiste nel cambio di aspetto, di dimensione, di tipo appartenente e di stats.
Prima di iniziare a parlare dell'analisi, è necessario fare alcune premesse per poter comprendere il codice scritto:
- Nel set denominato "aux_set" sono presenti i moltiplicatori di danni in base alla mossa subita e al tipo del pokemon difensore, questi dati eran necessari per la maggior parte delle domande di queste analisi.
- Nel set denominato "set" sono presenti pokemon alcuni pokemon che nel primo set non ci sono, pertanto per coerenza di dati, il set è filtrato fino alle generazioni presenti anche nell'aux_set.
- Nel dataset "set" non ci sono dati mancanti come nel primo, questo perchè le forme speciali di alcuni pokemon vengono gestite in maniera molto più ottimale (per questo motivo ci sono più pokemon rispetto al primo set).
## Obiettivo
L'obiettivo di questa analisi è rispondere a delle domande che sono state mosse dalla mia curiosità sin da giovane.
Tali domande sono le seguenti:
- Qual è il tipo più forte nel complesso? Qual è il più debole?
- Qual è il doppio tipo esistente nel complesso il più forte? Qual è il più debole?
- Qual è il tipo più probabile che sia un Pokemon leggendario?
- Come si correla l'altezza e il peso di un Pokemon con le sue varie statistiche di base?
- Si può costruire un dream team Pokemon?<br>Una squadra di 6 Pokemon che rimane relativamente impenetrabile a qualsiasi altra squadra di 6 Pokemon.
## Nota personale
Sin da quando ero ragazzino i pokemon sono sempre stati una ammirazione per me, ho capito solo qualche anno fa qual fosse il vero potenziale di un pokemon e le possibili opportunità che il gioco stesso ti proponeva.
Spero che questa analisi possa far anche voi scoprire qualcosa in più di questo mondo immenso.
```{r include=FALSE}
library(readr)
library(dplyr)
library(tidyr)
library(ggplot2)
library(modelr)
library(corrplot)
## Set completo dei dati sui Pokemon
set <- read.csv("./sets/Pokedex_Ver3.csv")
## Set con le debolezze dei pokemon
aux_set <- read.csv("./sets/dataset_pokemon.csv")
set <- set %>%
filter(GENERATION <= 7)
```
---
## Prima Domanda:<br>Qual è il tipo più forte nel complesso? Qual è il più debole?
### Creazione della Weak Table
Abbiamo a disposizione i moltiplicatori di danni degli attachi sui pokemon, possiamo determinare quanto danno potrebbe ricevere un determinato tipo di pokemon se ricevesse un attacco di ogni tipo.
Possiamo far ciò filtrando tutti i pokemon che hanno un solo tipo, eliminare tutti i doppioni così da avere una tabella che mostra le varie debolezze dei singoli tipi pokemon
```{r}
weak_table <- aux_set %>%
select(type1, type2, contains("against")) %>%
filter(type2 == "") %>%
distinct() %>% ## make only one type for row because are identicaly
select(-type2) %>%
rename(type = type1)
```
```{r echo=FALSE}
weak_table
```
### Somma dei Punti
Ora sommiamo i diversi danni possibili che può ricevere un tipo e riordiniamoli
```{r include=FALSE}
sum <- weak_table %>%
select(-type) %>%
rowSums()
weak_table <- weak_table %>%
select(-contains("against")) %>%
mutate(sum = sum) %>%
arrange(sum) %>%
rename(
Type = type,
"Weak Point" = sum
)
```
```{r echo=FALSE}
weak_table
```
Prendiamo il considerazione il primo della tabella (quello con meno punti) e l'ultimo (quello con più punti).
```{r echo=FALSE}
head(weak_table, 1)
tail(weak_table, 1)
```
Otteniamo che il tipo con un numero di danni è il ferro, mentre il pokemon con maggiori punti di danni che può subire è quello di tipo ghiaccio.
---
## Seconda Domanda:<br>Qual è il doppio tipo esistente nel complesso il più forte?<br>Qual è il più debole?
Visto che i pokemon di rado hanno solo una tipologia di tipo, è interessante capire quale accoppiata di tipi sia quella che può ricevere meno danno e quella più vulnerabile
### Creazione della Double Weak Table
Come prima, creiamo una seconda la tabelle delle debolezze considerando ora anche il secondo tipo dei pokemon
```{r}
double_weak_table <- aux_set %>%
select(type1, type2, contains("against")) %>%
filter(type2 != "") %>%
distinct()
```
```{r echo=FALSE}
double_weak_table
```
### Somma dei Punti
Rieseguiamo le stesse operazioni di prima per conteggiare i danni e riordinarli
```{r}
sum <- double_weak_table %>%
select(-contains("type")) %>%
rowSums()
double_weak_table <- double_weak_table %>%
select(-contains("against")) %>%
mutate(sum = sum) %>%
arrange(sum) %>%
rename(
"Type 1" = type1,
"Type 2" = type2,
"Weak Point" = sum
)
```
Osserviamo la prima parte della tabella
```{r echo=FALSE}
double_weak_table %>%
head()
```
E adesso l'ultima
```{r echo=FALSE}
double_weak_table %>%
arrange(-`Weak Point`) %>%
head()
```
L'accoppiata con meno danni che può subire è Ferro-Fata (sarà importante da ricordare) mentre quella più debole è Roccia-Ghiaccio.
Ahimè, avere un pokemon come Auorus in squadra è molto svantaggioso.
---
## Terza Domanda:<br>Qual è il tipo più probabile che sia un Pokemon leggendario?
Da parte della community c'è sempre stata una enorme ammirazione per i pokemon leggendari a tal punto che molti giocatori sceglievano una versione del gioco piuttosto che un'altra solo per avere quel pokemon leggendario.
Cerchiamo allora di capire quale siano i più frequenti tipi di pokemon leggendari e di ipotizzare se in una prossima uscita di un gioco pokemon ci sarà un pokemon con i tipi individuati.
### Ricerca dei pokemon leggendari
```{r}
legendary <- set %>%
select(NAME, TYPE1, TYPE2, LEGENDARY) %>%
filter(LEGENDARY == TRUE) %>%
distinct() ## necessario poichè alucni pokemon come Deoxsy cambiano forma ma non tipo
```
```{r echo=FALSE}
legendary
```
### Trovare il Tipo che risulta più frequente
```{r}
t1 <- as.data.frame(table(legendary$TYPE1))
t2 <- as.data.frame(table(legendary$TYPE2, exclude = ""))
# Il full join serve perchè si ha due tabelle distinte e vogliamo vedere i valori accoppiati,
# così da poterli sommare
legendary_type_sum <- full_join(t1, t2, by = "Var1") %>%
select(-Var1) %>%
rowSums()
t1 %>%
rename(Type = Var1) %>%
select(-Freq) %>%
mutate(Freq = legendary_type_sum) %>%
arrange(-Freq)
```
Abbiamo trovato che i tipi più frequenti tra i pokemon leggendari sono il tipo Psico e quello Drago.
---
## Quarta Domanda:<br>Come si correla l'altezza e il peso di un Pokemon con le sue varie statistiche di base?
Un' aspetto importante dei pokemon è l'evoluzione, non solo cambia l'aspetto fisico ma ne aumenta anche le statistiche di lotta.
Effettivamente, esiste una sorta di correlazione tra l'aumento di peso e di altezza con gli stats?
```{r fig.height = 5, fig.width = 10, fig.align = "center"}
par(mfrow=c(2,1))
# Correlazione tra altezza e gli stati
corrplot(cor(set$HEIGHT, set[, c(16:21)]),
method = "number",
type = "upper", # show only upper side
)
# Correlazione tra peso e gli stati
corrplot(cor(set$WEIGHT, set[, c(16:21)]),
method = "number",
type = "upper",
)
```
Nel grafico superirore viene rappresentata la correlazione lineare tra il peso e gli stats, mentre in quello inferiore tra l'altezza e gli stats.
Si evince che non esiste una correlazione lineare tra l'altezza e il peso verso le statistiche base del pokeomn.
Difatti si hanno tutti i valori intorno allo zero, ovvero assenza di correlazione.
Proviamo a verificare se magari esiste una correlazione di tipo quadratica.
```{r fig.height = 5, fig.width = 10, fig.align = "center"}
# Creiamo i quadrati delle altezze e dei pesi e valutiamo se esiste una correlazione lineare tra gli stats
quad_height <- set[, c(14)] ^ 2
quad_weight <- set[, c(15)] ^ 2
par(mfrow=c(2,1))
corrplot(cor(quad_height, set[, c(16:21)]),
method = "number",
type = "upper"
)
corrplot(cor(quad_weight, set[, c(16:21)]),
method = "number",
type = "upper"
)
```
Anche con una correlazione quadratica abbiamo dei valori molto più piccoli (vicini al 0.2), pertanto non esiste effettivamente una correlazione quadratica.
Utlima osservazione, proviamo con una funzione logaritmica
```{r fig.height = 5, fig.width = 10, fig.align = "center"}
log_height <- set[, c(14)] %>% log()
log_weight <- set[, c(15)] %>% log()
par(mfrow=c(2,1))
corrplot(cor(log_height, set[, c(16:21)]),
method = "number",
type = "upper"
)
corrplot(cor(log_weight, set[, c(16:21)]),
method = "number",
type = "upper"
)
```
In questo caso otteniamo che sia per il peso che per l'altezza c'è una correlazione: infatti si nots che i primi 3 stats, ovvero hp atk e def, hanno una correlazione sopra il 0.5.
```{r fig.height = 5, fig.width = 15, fig.align = "center"}
library(ggpubr)
height_plot <- ggplot(data = set, mapping = aes(log_height, ATK)) +
geom_point() +
geom_smooth(method = "loess", formula = "y ~ x")
weight_plot <- ggplot(data = set, mapping = aes(log_weight, ATK)) +
geom_point() +
geom_smooth(method = "loess", formula = "y ~ x")
ggarrange(height_plot, weight_plot, ncol = 2, nrow = 1, align = "h")
```
Questi grafici dimostrano che esiste una correlazione diretta tra le altezze e i pesi sottoposti in forma logaritmica, e in questo caso l'attacco del pokemon.
Possiamo dedurre alla fine, che esiste una correlazione logaritmica tra peso e altezza con l'attacco, la difesa ed infine, i punti salute.
---
## Ultima Domanda:<br>Si può costruire un dream team Pokemon?<br>Una squadra di 6 Pokemon che rimane relativamente impenetrabile a qualsiasi altra squadra di 6 Pokemon.
Ogni qual volta si inizia un gioco pokemon, ci si chiede quale possa essere la migliore squadra.
Cerchiamo di usare la scienza dei dati per poter dare una risposta effettiva a questa domanda.
Secondo i forum per le lotte pokemon in competitiva, per creare una squadra bisogna partire da un pokemon e analizzare le sue debolezze.
Cercare un'altro pokemon, il quale sia immune oppure sia poco vulnerabile alle debolezze del primo, e ripetere questo fino ad avere la squadra di 6 pokemon.
```{r}
# Cerchiamo una combinazione di pokemon la quale abbia una ampia "copertura" dai vari attacchi
# Dobbiamo considerare le debolezze e moltiplicarle tra loro
best_candidates <- aux_set %>%
select(name, contains("against"))
## Selezionare quelli che hanno presente almeno un zero nelle colonne delle debolezze
best_candidates <- best_candidates %>%
filter(rowSums(best_candidates == 0) > 0)
```
```{r}
## Scegliere quello che ha la somma più bassa
best_candidates <- best_candidates %>%
rowwise() %>%
mutate(Sum = sum(c_across("against_bug":"against_water"))) %>%
arrange(Sum)
# Mawile
dream_team <- head(best_candidates, 1)
```
```{r echo=FALSE}
dream_team
```
```{r}
## Da lui, cercare un altro pokemon che compensi le debolezze del primo
any(best_candidates$against_ground %in% 0)
new_member <- best_candidates %>%
filter(against_ground == 0) %>%
arrange(Sum) %>%
head(1)
# Skarmory
dream_team <- rbind(dream_team, new_member)
```
```{r echo=FALSE}
dream_team
```
```{r}
any(best_candidates$against_fire %in% 0)
any(best_candidates$against_fire %in% 0.5)
new_member <- best_candidates %>%
filter(against_fire == 0.5) %>%
arrange(Sum) %>%
head(1)
# Marill -> Azumarill
dream_team <- rbind(dream_team, new_member)
```
```{r echo=FALSE}
dream_team
```
```{r}
any(best_candidates$against_electric %in% 0)
new_member <- best_candidates %>%
filter(against_electric == 0) %>%
arrange(Sum) %>%
head(1)
# Steelix
dream_team <- rbind(dream_team, new_member)
```
```{r echo=FALSE}
dream_team
```
```{r}
any(best_candidates$against_fight %in% 0)
new_member <- best_candidates %>%
filter(against_fight == 0) %>%
arrange(Sum) %>%
head(1)
# Honedge --> Aegislash
dream_team <- rbind(dream_team, new_member)
```
```{r echo=FALSE}
dream_team
```
```{r}
any(best_candidates$against_dark %in% 0.5)
# ritorna Mawile, che abbiamo già in squadra
new_member <- best_candidates %>%
filter(against_water == 0.5) %>%
arrange(Sum) %>%
head(2) ## Sarebbe Dialga, però considerare pokemon leggendari nella ricerca non è funzionale al fine di tale, pertanto usaimo il secondo che è anche uno starter
# Empoleon
dream_team <- rbind(dream_team, new_member[2, ])
final_team <- aux_set %>%
filter(name %in% dream_team$name) %>%
select(name, type1, type2, hp, attack, defense, speed, sp_attack, sp_defense)
head(final_team)
```
Abbiam raggiunto un team ideale, ma per correttezza è giusto mettere le evoluzione finali dei pokemon
```{r}
# Usiam le evoluzioni finali
final_team[1,] <-aux_set %>%
select(name, type1, type2, hp, attack, defense, speed, sp_attack, sp_defense) %>%
filter(name == "Azumarill")
final_team[6,] <-aux_set %>%
select(name, type1, type2, hp, attack, defense, speed, sp_attack, sp_defense) %>%
filter(name == "Aegislash")
final_team
```
Il team finale è un buon team attaccante ed un ottimo team difensivo, ma non è il migliore.
Effettivamente non esiste una squadra ottimale, esistono squadre competitive usate nei tornei ma anche quelle sono le più disparate
Pertanto, la risposta alla domanda finale è che non si può creare un dream team oggettivo, dipende molto anche da quale pokemon si inizia a reclutare e soprattutto quali altri pokemon aggiungere alla squadra per compensare le vulnerabilità del primo.
Alla fine, forse è propio per questo che un qualsiasi team può essere considerato "il migliore".