Applicazioni pratiche di machine learning/Riconoscimento della scrittura a mano
Caricamento librerie
modifica library(caret)
Parte 1 : Dati
modificaI seguenti files di dati train.csv e test.csv contengono immagini in scala di grigio di numeri disegnati a mano, da zero a nove.
Ogni immagine ha 28 pixel di altezza e 28 pixel di larghezza, per un totale di 784 pixel . Ogni pixel ha un singolo numero associato ad esso, che indica la luminosità o l'oscurità di quel pixel, dove i numeri più alti indicano colori più scuri. Questo numero intero è compreso tra 0 e 255 incluso.
Il training set di dati (train.csv) ha 785 colonne. La prima colonna, chiamata "label", è il numero disegnato dall'utente. Il resto delle colonne contiene i numeri di pixel dell'immagine associata.
Ogni colonna di pixel nel training set ha come nome “pixelx”, dove x è un numero intero compreso tra 0 e 783, incluso. Ad esempio, pixel31 indica il pixel che si trova nella quarta colonna da sinistra e la seconda riga dall'alto.
Il testing set , (test.csv), è uguale al training set , tranne per il fatto che non contiene la colonna "label", che dovrà essere prevista costruendo un modello di classificazione tramite un algoritmo di machine learning.
Caricamento dei dati:
training <- read.csv("train.csv")
testing <- read.csv("test.csv")
Parte 2: Domanda di ricerca
modificaSi vuole predire quale numero da 0 a 9 corrisponde a ciascuna delle 28.000 righe del testing set, ognuna delle quali contiene 784 pixels rappresentati da 784 numeri compresi tra 0 e 255 incluso, relativi al numero scritto a mano dall'utente.
Parte 3: Modellizzazione
modificaInvece di riconoscere il numero tramite 784 pixels, si calcolano i "principal components" riducendo il numero di predictors da 784 a 20 . Con 20 principal components la varianza ottenuta è pari a circa il 60% come si vede dal seguente grafico :
#Calcolo principal components
pca <- prcomp(training[,-1])
# Calcolo varianza dei singoli principal components
v <- pca$sdev^2
#Varianza dei singoli principal componenents diviso la varianza totale
p <- v/sum(v)
#Varianza dei primi 20 principal components
plot(cumsum(p[1:20]) )
Divido il training set in un 70% su cui costruisco il modello previsionale utilizzando l'algoritmo di machine learning Random Forest e in un rimanente 30% che chiamo validation set su cui testo il modello. Calcolo poi la confusion matrix sia sul training set. che sul validation set che mi danno rispettivamente un' Accuracy quasi del 100% sul training set, e un'Accuracy del 91% sul validation set . Tutto ciò soltanto con 20 principal components invece di 784 predictors.
inTrain <- createDataPartition(y=training$label,p=0.7,list = FALSE)
train_p <- training[inTrain,]
test_p <- training[-inTrain,]
pca <- prcomp(train_p[,-1], rank. = 20)
Z <- as.data.frame(pca$x)
train_data <- cbind(Z,label=as.factor(train_p$label))
model <- train(label ~ ., data=train_data, method="rf", ntree=10)
pred <- predict(model, newdata=train_data)
print("Confusion Matrix on training data with Accuracy about 100%")
confusionMatrix(pred,train_data$label)
test.data <- predict(pca, newdata=test_p)
test.data <- as.data.frame(test.data)
rf.pred <- predict(model,test.data)
print("Confusion Matrix on testing data with Accuracy about 91%")
confusionMatrix(rf.pred,as.factor(test_p$label))
Confusion Matrix and Statistics
Reference Prediction 0 1 2 3 4 5 6 7 8 9 0 2871 0 1 1 0 2 2 0 1 2 1 0 3286 1 0 0 1 0 0 1 0 2 0 0 2931 2 0 1 0 2 1 0 3 0 0 0 3019 0 4 0 0 4 3 4 0 0 1 0 2863 1 0 2 2 5 5 0 0 0 1 0 2690 0 0 4 0 6 0 0 2 1 1 0 2864 0 0 0 7 0 0 0 0 1 0 0 3063 0 1 8 0 0 2 0 1 0 0 0 2834 1 9 0 1 0 0 7 0 0 2 0 2917
Overall Statistics Accuracy : 0.9978 95% CI : (0.9972, 0.9983) No Information Rate : 0.1118 P-Value [Acc > NIR] : < 2.2e-16 Kappa : 0.9975 Mcnemar's Test P-Value : NA
Statistics by Class:
Class: 0 Class: 1 Class: 2 Class: 3 Class: 4 Class: 5 Sensitivity 1.00000 0.9997 0.99762 0.9983 0.99652 0.99667 Specificity 0.99966 0.9999 0.99977 0.9996 0.99959 0.99981 Pos Pred Value 0.99687 0.9991 0.99796 0.9964 0.99617 0.99814 Neg Pred Value 1.00000 1.0000 0.99974 0.9998 0.99962 0.99966 Prevalence 0.09764 0.1118 0.09992 0.1028 0.09771 0.09179 Detection Rate 0.09764 0.1118 0.09968 0.1027 0.09737 0.09149 Detection Prevalence 0.09795 0.1119 0.09989 0.1031 0.09775 0.09166 Balanced Accuracy 0.99983 0.9998 0.99870 0.9990 0.99805 0.99824 Class: 6 Class: 7 Class: 8 Class: 9 Sensitivity 0.99930 0.9980 0.99543 0.99590 Specificity 0.99985 0.9999 0.99985 0.99962 Pos Pred Value 0.99861 0.9993 0.99859 0.99658 Neg Pred Value 0.99992 0.9998 0.99951 0.99955 Prevalence 0.09747 0.1044 0.09683 0.09962 Detection Rate 0.09741 0.1042 0.09638 0.09921 Detection Prevalence 0.09754 0.1042 0.09652 0.09955 Balanced Accuracy 0.99958 0.9990 0.99764 0.99776
Confusion Matrix and Statistics
Reference Prediction 0 1 2 3 4 5 6 7 8 9 0 1212 0 8 5 1 18 12 2 4 4 1 0 1366 3 2 6 4 1 9 8 2 2 7 3 1145 26 10 4 12 24 17 4 3 2 7 11 1179 2 36 4 6 44 28 4 2 3 11 3 1071 9 5 14 9 85 5 9 3 7 44 5 971 12 15 48 12 6 16 1 9 4 16 10 1220 0 9 3 7 4 3 22 15 10 5 0 1234 10 52 8 6 5 20 36 10 24 5 6 1047 15 9 3 6 3 13 68 15 0 22 20 1054
Overall Statistics Accuracy : 0.9128 95% CI : (0.9078, 0.9177) No Information Rate : 0.1109 P-Value [Acc > NIR] : < 2.2e-16 Kappa : 0.9031 Mcnemar's Test P-Value : NA
Statistics by Class:
Class: 0 Class: 1 Class: 2 Class: 3 Class: 4 Class: 5 Sensitivity 0.96114 0.9778 0.92413 0.88847 0.89324 0.88595 Specificity 0.99524 0.9969 0.99058 0.98758 0.98763 0.98652 Pos Pred Value 0.95735 0.9750 0.91454 0.89386 0.88366 0.86234 Neg Pred Value 0.99568 0.9972 0.99171 0.98688 0.98876 0.98910 Prevalence 0.10010 0.1109 0.09836 0.10534 0.09518 0.08700 Detection Rate 0.09621 0.1084 0.09089 0.09359 0.08502 0.07708 Detection Prevalence 0.10050 0.1112 0.09939 0.10471 0.09621 0.08939 Balanced Accuracy 0.97819 0.9873 0.95736 0.93802 0.94044 0.93624 Class: 6 Class: 7 Class: 8 Class: 9 Sensitivity 0.95987 0.92643 0.86102 0.83717 Specificity 0.99400 0.98926 0.98884 0.98677 Pos Pred Value 0.94720 0.91070 0.89182 0.87542 Neg Pred Value 0.99549 0.99128 0.98521 0.98201 Prevalence 0.10090 0.10574 0.09653 0.09994 Detection Rate 0.09685 0.09796 0.08312 0.08367 Detection Prevalence 0.10225 0.10757 0.09320 0.09558 Balanced Accuracy 0.97694 0.95784 0.92493 0.91197
Parte 4: Previsione
modificaUtilizzo infine il modello precedentemente creato per riconoscere i numeri scritti a mano sul testing set:
test.data <- predict(pca, newdata = testing)
test.data <- as.data.frame(test.data)
rf.pred <- predict(model,test.data)
df <- data.frame(ImageId=1:nrow(testing),Label=rf.pred)
df
write.csv(df, file="digit_recognizer.csv", row.names = FALSE)
ImageId Label 1 1 2 2 2 0 3 3 9 4 4 9 5 5 3 6 6 7 7 7 0 8 8 3 9 9 0 10 10 3 11 11 5 12 12 7 13 13 4 14 14 0 15 15 4 16 16 3 17 17 3 18 18 1 19 19 9 20 20 0 21 21 9 22 22 1 23 23 1 24 24 5 25 25 7 26 26 4 27 27 2 28 28 7 29 29 9 30 30 7 31 31 7 32 32 5 33 33 4 34 34 2 35 35 6 36 36 2 37 37 5 38 38 5 39 39 1 40 40 6 ...