Classificazione k-nn con R Strumenti quantitativi per la gestione Emanuele Taufer file:///g:/il%20mio%20drive/2%20corsi/3%20sqg/labs/l1-knn.html#(1) 1/16
Altezza e peso degli adulti Le statistiche sull altezza e sul peso di maschi e femmine adulti ci dicono che la distribuzione di queste due caratteristiche nelle popolazioni è ben approssimata da variabili normali. Più in dettaglio abbiamo la distribuzione delle altezze per i maschi adulti è normale con media 177 cm e ds 16 cm. Indichiamolo con Altezza M N(177, 16) Analogamente, Altezza F N(165, 9) P eso M N(65, 4.5) P eso F N(55, 3.6) La correlazione tra Altezza e Peso (per entrambi i gruppi) è 0,5 file:///g:/il%20mio%20drive/2%20corsi/3%20sqg/labs/l1-knn.html#(1) 2/16
Dati HW Il set di dati HW.csv contiene 200 osservazioni su altezza e peso di adulti, suddivisi in M e F (nel data set i dati sono espressi in pollici e libbre): Y : M of F (qualitativa) X 1 X 2 : Altezza dell unità in pollici (quantitativa) : Peso dell unità in libbre (quantitativa) file:///g:/il%20mio%20drive/2%20corsi/3%20sqg/labs/l1-knn.html#(1) 3/16
Obbiettivo Creare un modello per classificare un unità come M o F in base all altezza e al peso Questo esempio giocattolo ci permetterà di visualizzare i risultati graficamente Un set di dati test, di convalida è disponibile nel file `HWTest.csv file:///g:/il%20mio%20drive/2%20corsi/3%20sqg/labs/l1-knn.html#(1) 4/16
Carica i dati Scarichiamo direttamente il file dall indirizzo web e vediamone le caratteristiche library(ggplot2) HW<-read.csv("http://www.cs.unitn.it/~taufer/Data/HW.csv") head(hw) ## X Gender Height Weight ## 1 1 F 67.55243 121.6895 ## 2 2 F 63.25061 124.9538 ## 3 3 F 63.04638 117.9914 ## 4 4 F 68.19534 133.6552 ## 5 5 F 69.50217 121.8862 ## 6 6 F 69.67889 121.1802 str(hw) ## 'data.frame': 200 obs. of 4 variables: ## $ X : int 1 2 3 4 5 6 7 8 9 10... ## $ Gender: Factor w/ 2 levels "F","M": 1 1 1 1 1 1 1 1 1 1... ## $ Height: num 67.6 63.3 63 68.2 69.5... ## $ Weight: num 122 125 118 134 122... file:///g:/il%20mio%20drive/2%20corsi/3%20sqg/labs/l1-knn.html#(1) 5/16
Scatter plot gg1<-ggplot(hw,aes(x=height,y=weight, color=gender,shape=gender))+geom_point(size=3) gg1 file:///g:/il%20mio%20drive/2%20corsi/3%20sqg/labs/l1-knn.html#(1) 6/16
Classificazione k-nn. Per la classificazione k-nn in R si usa la funzione knn(), che fa parte della libreria class. knn() fornisce direttamente la classe prevista per l unità utilizzando un singolo comando. La funzione richiede 4 argomenti (input): Una matrice contenente i predittori associati ai dati training, contrassegnati da XTrain sotto. Una matrice contenente i predittori associati ai dati per i quali desideriamo fare previsioni, con l etichetta XTest sotto (possiamo fare le previsioni anche per i dati training, utilizzeremo in questo caso ancora XTrain). Un vettore contenente le etichette di classe per le osservazioni training, contrassegnato con YTrain sotto. Un valore per k, il numero di vicini più vicini da utilizzare dal classificatore. Nota L output della funzione sono i valori previsti file:///g:/il%20mio%20drive/2%20corsi/3%20sqg/labs/l1-knn.html#(1) 7/16
Come usare la funzione knn() library(class) knn(xtrain,xtest,ytrain,k) Importante! La sintassi sopra produce le previsioni per un XTest dato il modello k-nn costruito utilizzando i dati XTrain eytrain Queste previsioni possono essere utilizzate per stimare il tasso di errore test La sintassi sotto produrrà le previsioni per XTrain dato che il modellok-nn viene generato utilizzando i dati XTrain eytrain Queste previsioni possono essere utilizzate per stimare il tasso di errore training library(class) knn(xtrain,xtrain,ytrain,k) file:///g:/il%20mio%20drive/2%20corsi/3%20sqg/labs/l1-knn.html#(1) 8/16
k-nn con i dati HW Nei dati HW, separare le variabili Y e X per applicare la funzione knn() Nel codice sotto la classificazione k-nn viene eseguita con k = 5 (arbitrariamente scelto). Le classi previste (p.ytrain) per i dati training vengono memorizzate nel set di dati HW. library(class) ## carica la libreria MASS XTrain=HW[,c(3,4)] ## seleziona solo altezza e peso YTrain=HW[,2] ## seleziona la variabile qualitativa ## crea l'oggetto p.ytrain che contiene le previsioni per i dati training p.ytrain=knn(xtrain,xtrain,ytrain,k=5) ## inserisci le previsioni come nuova variabile nel dataset HW HW$Predict=p.YTrain Il tasso di errore training è mean(ytrain!= p.ytrain) ## [1] 0.085 file:///g:/il%20mio%20drive/2%20corsi/3%20sqg/labs/l1-knn.html#(1) 9/16
Rappresentare i risultati Nota. Il colore è il genere previsto. La forma è il genere osservato. Ad esempio, un cerchio blu è un F erroneamente classificato come M gg2<-ggplot(hw,aes(x=height,y=weight, color=predict,shape=gender))+geom_point(size=3) gg2 file:///g:/il%20mio%20drive/2%20corsi/3%20sqg/labs/l1-knn.html#(1) 10/16
Usando k=50 invece di k=5 XTrain=HW[,c(3,4)] YTrain=HW[,2] p.ytrain=knn(xtrain,xtrain,ytrain,k=55) HW$Predict=p.YTrain Il tasso di errore training è mean(ytrain!= p.ytrain) ## [1] 0.105 file:///g:/il%20mio%20drive/2%20corsi/3%20sqg/labs/l1-knn.html#(1) 11/16
gg2<-ggplot(hw,aes(x=height,y=weight, color=predict,shape=gender))+geom_point(size=3) gg2 file:///g:/il%20mio%20drive/2%20corsi/3%20sqg/labs/l1-knn.html#(1) 12/16
Scegliere il modello (ossia scegliere k) Utilizziamo i dati HWtest per ottenere una stima del Tasso di errore test per diversi valori di k. Scegli il modello (cioè seleziona k) che ha il tasso di errore test più basso Preparare i dati HWTest<-read.csv("http://www.cs.unitn.it/~taufer/Data/HWTest.csv") XTest=HWTest[,c(3,4)] YTest=HWTest[,2] file:///g:/il%20mio%20drive/2%20corsi/3%20sqg/labs/l1-knn.html#(1) 13/16
Un loop per rendere tutto automatico Il codice riportato di seguito, per i valori di k nell intervallo 1 50, produce una stima del tasso di errore test basato sui dati HWTest p.ytest = NULL test.error.rate = NULL for(i in 1:50){ set.seed(1) p.ytest = knn(xtrain,xtest,ytrain,k=i) test.error.rate[i] = mean(ytest!= p.ytest) } Il valore di è k che minimizza il tasso di errore test stimato which.min(test.error.rate) ## [1] 9 min(test.error.rate) ## [1] 0.05 file:///g:/il%20mio%20drive/2%20corsi/3%20sqg/labs/l1-knn.html#(1) 14/16
Possiamo fare lo stesso per calcolare il tasso di errore training p.ytrain = NULL train.error.rate = NULL for(i in 1:50){ set.seed(1) p.ytrain = knn(xtrain,xtrain,ytrain,k=i) train.error.rate[i] = mean(ytrain!= p.ytrain) } Il valore di k che minimizza il tasso di errore training è which.min(train.error.rate) ## [1] 1 min(train.error.rate) ## [1] 0 file:///g:/il%20mio%20drive/2%20corsi/3%20sqg/labs/l1-knn.html#(1) 15/16
Plot degli error rate Error.rates<-data.frame("k"=1:50, "Test.error.rate"=test.error.rate,"Train.error.rate"=trai gg4<-ggplot(error.rates)+geom_line(aes(x=1/k,y=test.error.rate), color="blue")+geom_line(ae gg4 file:///g:/il%20mio%20drive/2%20corsi/3%20sqg/labs/l1-knn.html#(1) 16/16