getwd() setwd("G:/Il mio Drive/Didattica/Livellamento R/2021-2022") # https://www.kaggle.com/samarthmehta/pokemon-analysis/data help("read.csv2") pkmn <- read.csv2(file = "Pokemon.csv", # Nome del file, con eventuale directory header = T, # Il file ha come prima riga il nome delle variabili? TRUE o FALSE sep="," # Qual è il separatore? ) str(pkmn) # Attenzione alla variabile Legendary: non assume valori booleani! Ma due etichette "False" e "True" ################################ ######## Data Cleaning: ######## ################################ # 1 - Generation e' una variabile qualitativa, ma e' stata codificata come 'int' anziche' come factor: pkmn$Generation <- as.factor(pkmn$Generation) pkmn$Legendary <- as.factor(pkmn$Legendary) pkmn$Type1 <- as.factor(pkmn$Type1) pkmn$Type2 <- as.factor(pkmn$Type2) # 2 - Alcuni Pokemon sembrano ripetuti (forme Mega): identifichiamoli ed eliminiamoli dal dataset mega.row <- grep("Mega", pkmn$Name) mega.row pkmn$Name[mega.row] pkmn[mega.row,2] # Ma il pokemon Meganium ha "Mega" nel nome senza essere una forma Mega: mega.row[16] # Due modi per risolvere: # -- 1) mega.row2 <- grep("Mega ", pkmn$Name) # C'è uno spazio dopo il Mega # -- 2) mega.row <- mega.row[-16] all(mega.row2==mega.row) # Creo la variabile Mega e la unisco al data frame: pkmn$Mega <- rep(0, nrow(pkmn)) # altrimenti: numeric(nrow(pkmn)) pkmn$Mega[mega.row] <- 1 # Guardiamo la riga specifica di Meganium: pkmn$Name=="Meganium" pkmn[pkmn$Name=="Meganium",] # Creiamo un sottoinsieme dei dati con la funzione subset e chiedo di togliere la variabile Mega pkmn <- subset(x=pkmn, subset=(Mega==0), select=-Mega) # Oppure: # pkmn <- pkmn[which(pkmn$Mega == 0),-14] # ATTENZIONE: abbiamo sovrascritto il data frame!!! Se si volessero mantenere tutte # le versioni dei dati, assegnare nomi diversi agli oggetti che li contengono. # pkmn2 <- subset(x=pkmn, subset=(Mega==0), select=-Mega) ###################################################################### ###################################################################### ###################################################################### ###################################################################### # Quanti pokemon ci sono in ogni generazione? plot(pkmn$Generation) table(pkmn$Generation) # Il fido amico Google ci suggerisce che dovremmo avere # (151,100,135,107,156,72) # Abbiamo ottenuto le frequenze che ci aspettavamo? freq.osservate <- as.numeric(table(pkmn$Generation)) freq.attese <- c(151,100,135,107,156,72) all(freq.osservate == freq.attese) # Ci sono dei pokemon che sono stati registrati piu' volte per motivi di gioco. # Notiamo che gli ID di alcuni Pokemon sono ripetuti. Lavoriamo su questo aspetto: eliminare <- numeric(nrow(pkmn)) for(i in 2:nrow(pkmn)) { eliminare[i] <- ifelse(pkmn$ID[i]==pkmn$ID[i-1], 1, 0) } # In questo modo abbiamo deciso di conservare la prima unita' statistica tra quelle ripetute. pkmn$Name[eliminare==1] pkmn_OLD <- pkmn pkmn <- subset(pkmn, eliminare==0) # Ricontrolliamo: freq.osservate <- as.numeric(table(pkmn$Generation)) freq.attese <- c(151,100,135,107,156,72) all(freq.osservate == freq.attese) attach(pkmn) ###################################################################### ###################################################################### ###################################################################### ###################################################################### # Cosi' tante variabili... cosi' poco tempo... summary(pkmn) # Ma non ci sono indici di variabilità: apply( cbind(Total, HP, Attack, Defense, SpAtk, SpDef, Speed), # creo una matrice con le sole variabili NUMERICHE 2, # lavoro con le colonne function(x){ c(summary(x), Sd=sd(x), Var=var(x)) }) # Oppure, equivalentemente: apply( cbind(Total, HP, Attack, Defense, SpAtk, SpDef, Speed), 2, function(x){ t <- c(summary(x), sd=sd(x), Var=var(x)) return(t) }) # Quanti leggendari ci sono in ogni generazione? table(Generation, Legendary) table(subset(pkmn, Legendary=="True", select=Generation)) plot(table(subset(pkmn, Legendary=="True", select=Generation)), ylab="Conteggio Leggendari", xlab="Generation", main="Numero di Leggendari per Generazione") # La distribuzione del numero di leggendari cambia tra le varie generazioni? # Questo grafico e' molto fuorviante: non tiene conto del numero di pokemon # presenti in ogni generazione. Parlare in termini "assoluti" anziché # in termini "relativi" (percentuali), può fornire un'interpretazione # diversa ad un grafico # Con questo grafico noi diremmo che c'è differenze tra il numero di # leggendari a seconda della generazione plot(table(subset(pkmn, Legendary=="True", select=Generation)), ylab="Conteggio Leggendari", xlab="Generation", main="Numero di Leggendari per Generazione") # Un grafico migliore potrebbe essere questo: freq.relative <- table(subset(pkmn, Legendary=="True", select=Generation))/freq.osservate class(freq.relative) plot(freq.relative, ylab="Conteggio Leggendari", xlab="Generation", main="Numero di Leggendari per Generazione") # Notiamo ancora delle differenze, ma adesso ogni barra puo' "arrivare" # al massimo a 1 # Le differenze sembrano trascurabili se si cambiasse il range dell'asse y: plot(freq.relative, ylim=c(0,1), ylab="Conteggio Leggendari", xlab="Generation", main="Numero di Leggendari per Generazione") # Una diversa scelta di elementi grafici puo' veicolare informazioni # molto differenti. Attenzione! # Oppure questo: plot(Legendary ~ Generation) ###### Dedichiamoci al tipo principale del pokemon (Type1) x11() # apre una finestra grafica di windows plot(Type1) table(Type1) table(Type1,Generation) plot(Type1, Generation) # Notiamo che la seconda colonna è formata soltanto da 5 rettangoli: # il primo ha lo stesso colore del secondo rettangolo della prima colonna. # Risulta molto difficile da leggere! # Oppure, plottando un oggetto di classe table: plot(table(Type1,Generation), main="Type1 e Generation") # Le aree delle barre sono proporzionali alla frequenza di cella corrispondente. plot(pkmn, pch=20) # Notiamo che le variabili factor sono state rappresentate tramite la codifica # che R riserva alle loro modalita'/livelli. # Non sono informativi e la loro presenza "causa" il restringimento degli altri scatterplot: plot(subset(pkmn, select=-c(ID, Name, Type1, Type2, Generation)), pch=20) cor(subset(pkmn, select=-c(ID, Name, Type1, Type2, Generation, Legendary))) round(cor(subset(pkmn, select=-c(ID, Name, Type1, Type2, Generation, Legendary))),3) # Total e' la somma delle altre statistiche del Pokemon? somma <- HP+Attack+Defense+SpAtk+SpDef+Speed cor(Total,somma) # C'e' una perfetta relazione lineare tra Total e una variabile # definita come la somma di tutte le altre caratteristiche del pokemon plot(somma, Total, pch=20); abline(a=0, b=1, col=2) # Oppure: (Total-(HP+Attack+Defense+SpAtk+SpDef+Speed)) # Check: all((Total-(HP+Attack+Defense+SpAtk+SpDef+Speed))==0) # Supponiamo ora di essere interessati ai punti vita dei pokemon (variabile HP) # Il tipo del Pokemon influenza i suoi punti vita? # (=> Ci sono dei Tipi che hanno dei punti vita maggiori/minori?) boxplot(HP~Type1) boxplot(HP~Type1, pch=20) abline(h=mean(HP), col="blue", lwd=2) # Con la funzione aggregate possiamo calcolare alcune statistiche descrittive stratificando per le # modalita' di altre variabili: aggregate(HP, by=list(Type1=Type1), FUN = mean) aggregate(HP, by=list(Type1=Type1), function(x) cbind(mean(x), median(x))) aggregate(HP, by=list(Gen=Generation, Type1=Type1), mean) ########################################### ######### Analisi di Regressione: ######### ########################################### plot(HP ~ Attack, col=Legendary, pch=19) abline(h=180, col=2, lty=2) # Chi sono i pokemon con molti punti vita? pkmn[which(HP >=180),] identify(HP ~ Attack) pkmn[c(113,202,242),] # L'attacco ha una relazione lineare con il numero di punti vita? modello.retta <- lm(HP ~ Attack, data=pkmn) (summ <- summary(modello.retta)) names(summ) summ$r.squared plot(HP ~ Attack, col=Legendary, pch=19) # Possiamo disegnare la retta di regressione abline(modello.retta, col=3, lwd=4) class(modello.retta) modello.piano <- lm(HP ~ Attack + Legendary) (summ.piano <- summary(modello.piano)) summ.piano$r.squared - summ$r.squared # Possiamo prevedere i punti vita di nuovi Pokemon: nuovi.dati <- data.frame(Attack=c(20,20,70,55), Legendary=as.factor(c("True", "False", "False", "False"))) predict(modello.piano, newdata = nuovi.dati) ############################################################ ########## MONTY HALL PROBLEM # https://it.wikipedia.org/wiki/Problema_di_Monty_Hall # In un gioco a premi ci sono tre porte. Dietro ad una di esse # si nasconde un premio, mentre dietro # ciascuna delle restanti due, una capra. # Vi viene chiesto di scegliere una porta. Successivamente, il conduttore # Monty Hall, che conosce la distribuzione dei premi dietro # alle porte, apre una delle restanti due porte, mostrandovi una capra. # A quel punto egli vi propone di cambiare la porta da voi scelta con quella rimanente. # Scegliereste di cambiare porta? Oppure una porta vale l'altra? # La domanda può essere letta come: qual e' la probabilità di vincere # il premio se si cambiasse porta? # Simuliamo quindi un grande numero di partite, utilizzando le informazioni # a nostra disposizione. Ad ogni partita sceglieremo sempre di cambiare porta, # per valutare se si rivelerà la strategia vincente oppure non produrra' variazioni. nsim <- 100000 # Simuliamo questo numero di partite esito_cambio <- numeric(nsim) # Vettore in cui salveremo l'esito (Vincita o Perdita) di ogni partita porte <- c(1,2,3) for(i in 1:nsim){ # Dietro a quale porta si nasconde il premio? premio <- sample(1:3, size=1) # Quale porta sceglie il giocatore? mia.scelta <- sample(1:3, size=1) if(mia.scelta==premio){ # Se ho scelto la porta vincente... monty <- sample(porte[-mia.scelta], 1) #... lui puo' aprire una qualunque delle porte con le capre esito_cambio[i] <- "YOU LOSE" #... e se cambiassi porta, perderei... } else { #... altrimenti, se ho scelto una porta associata ad una capra monty <- porte[-c(mia.scelta, premio)] #... Monty è obbligato ad aprirmi l'unica altra porta contenente una capra esito_cambio[i] <- "YOU WIN" #... e se cambiassi porta, vincerei!!!! } } table(esito)/nsim*100