Vamos a crear un algoritmo para predecir con la mayor precisión, la manera (How well) de realizar ejercicio. Para ello vamos a usar un dataset publico (Weight Lifting Exercises Dataset) y técnicas de Machine Learning, principalmente Random Forest, Generalized Boosted, Linear Discriminant Analysis, Recursive Partitioning And Regression Trees and, of course, Cross Validation.
URL.train <- "https://d396qusza40orc.cloudfront.net/predmachlearn/pml-training.csv"
URL.test <- "https://d396qusza40orc.cloudfront.net/predmachlearn/pml-testing.csv"
Fil.train <- "pml-training.csv"
Fil.test <- "pml-testing.csv"
if(!file.exists(Fil.train))
download.file(URL.train, destfile = Fil.train)
if(!file.exists(Fil.test))
download.file(URL.test, destfile = Fil.test)
Dat.train <- read.csv(Fil.train, na.strings=c("NA","#DIV/0!",""))
Dat.test <- read.csv(Fil.test, na.strings=c("NA","#DIV/0!",""))
Bajamos los 2 dataset (training y testing) y los cargamos en memoria. Hemos identificado previamente varios valores residuales y nulos, procedemos a convertirlos en NA.
set.seed(13)
Spl <- createDataPartition(Dat.train$classe, p = 0.7, list = FALSE)
Dat.train.train <- Dat.train[Spl, ]
Dat.train.valid <- Dat.train[-Spl, ]
Dat.train.train <- Dat.train.train[, -c(1:7)]
Dat.train.valid <- Dat.train.valid[, -c(1:7)]
nz <- nearZeroVar(Dat.train.train)
Dat.train.train <- Dat.train.train[, -nz]
Dat.train.valid <- Dat.train.valid[, -nz]
vna <- sapply(Dat.train.train, function(x) mean(is.na(x))) > 0.97
Dat.train.train <- Dat.train.train[, vna==FALSE]
Dat.train.valid <- Dat.train.valid[, vna==FALSE]
dim(Dat.train.train)
## [1] 13737 53
dim(Dat.train.valid)
## [1] 5885 53
descrCor <- cor(Dat.train.train[, -length(Dat.train.train)])
highlyCorDescr <- findCorrelation(descrCor, cutoff = .8)
Dat.train.train <- Dat.train.train[,-highlyCorDescr]
Dat.train.valid <- Dat.train.valid[,-highlyCorDescr]
dim(Dat.train.train)
## [1] 13737 40
dim(Dat.train.valid)
## [1] 5885 40
En un principio los 2 dataset tienen 160 covariables, los datos de training los partimos en 2 trozos, uno con el 70% para construir los modelos, y el otro con el 30% para validarlos y poder elegir el que tiene mas accuracy. A continuación tenemos que eliminar las covariables descriptivas del propio proceso de medicion o las que contengan id’s inútiles para nuestra predicción (las 7 primeras) en segundo lugar las covariables que tengan una variance cercana a cero y en tercer lugar eliminamos las covariables que en su mayoria tienen valor NA (por encima del 97% de los datos). Por último evaluamos la correlación entre las 53 covariables y fijando un umbral del 80% de correlación absoluta, nos quedamos con 40 covariables que consideramos apropiadas para contruir los modelos de predicción.
Dat.test <- Dat.test[, -c(1:7)]
Dat.test <- Dat.test[, -nz]
Dat.test <- Dat.test[, vna==FALSE]
Dat.test <- Dat.test[,-highlyCorDescr]
dim(Dat.test)
## [1] 20 40
Debemos hacer las mismas transformaciones con los datos de testing proporcionados, con los cuales efectuaremos al final del report la predicción de las 20 muestras (individuos).
vControl <- trainControl(method="cv", number=4, verboseIter = FALSE)
vMetric <- "Accuracy"
Establecemos los parametros generales que usaremos al construir todos los modelos. Vamos a usar Cross Validatión en todos los casos.
Modfit.lda <- train(classe ~ ., method = "lda", data = Dat.train.train, verbose = FALSE, trControl = vControl, metric = vMetric)
Pre.lda <- predict(Modfit.lda, Dat.train.valid)
confusionMatrix(Pre.lda, Dat.train.valid$classe)
## Confusion Matrix and Statistics
##
## Reference
## Prediction A B C D E
## A 1269 190 102 53 49
## B 151 657 90 71 185
## C 147 111 665 114 132
## D 88 87 142 653 131
## E 19 94 27 73 585
##
## Overall Statistics
##
## Accuracy : 0.6506
## 95% CI : (0.6383, 0.6628)
## No Information Rate : 0.2845
## P-Value [Acc > NIR] : < 2.2e-16
##
## Kappa : 0.5586
##
## Mcnemar's Test P-Value : < 2.2e-16
##
## Statistics by Class:
##
## Class: A Class: B Class: C Class: D Class: E
## Sensitivity 0.7581 0.5768 0.6481 0.6774 0.54067
## Specificity 0.9064 0.8953 0.8963 0.9090 0.95565
## Pos Pred Value 0.7631 0.5693 0.5689 0.5931 0.73308
## Neg Pred Value 0.9041 0.8981 0.9235 0.9350 0.90230
## Prevalence 0.2845 0.1935 0.1743 0.1638 0.18386
## Detection Rate 0.2156 0.1116 0.1130 0.1110 0.09941
## Detection Prevalence 0.2826 0.1961 0.1986 0.1871 0.13560
## Balanced Accuracy 0.8323 0.7361 0.7722 0.7932 0.74816
Construimos el modelo con el 70% de los datos de training y lo validamos con el 30% restante. En este caso la Accuracy no llega al 70%, pensamos que esta técnica de Machine Learning no es la apropiada para nuestros datos.
Modfit.rpart <- train(classe ~ ., method = "rpart", data = Dat.train.train, trControl = vControl, metric = vMetric)
Pre.rpart <- predict(Modfit.rpart, Dat.train.valid)
confusionMatrix(Pre.rpart, Dat.train.valid$classe)
## Confusion Matrix and Statistics
##
## Reference
## Prediction A B C D E
## A 1513 478 499 375 241
## B 29 386 24 191 213
## C 106 234 399 80 222
## D 25 39 104 234 31
## E 1 2 0 84 375
##
## Overall Statistics
##
## Accuracy : 0.494
## 95% CI : (0.4811, 0.5068)
## No Information Rate : 0.2845
## P-Value [Acc > NIR] : < 2.2e-16
##
## Kappa : 0.3384
##
## Mcnemar's Test P-Value : < 2.2e-16
##
## Statistics by Class:
##
## Class: A Class: B Class: C Class: D Class: E
## Sensitivity 0.9038 0.33889 0.3889 0.24274 0.34658
## Specificity 0.6217 0.90371 0.8679 0.95956 0.98189
## Pos Pred Value 0.4871 0.45789 0.3833 0.54042 0.81169
## Neg Pred Value 0.9421 0.85065 0.8706 0.86610 0.86963
## Prevalence 0.2845 0.19354 0.1743 0.16381 0.18386
## Detection Rate 0.2571 0.06559 0.0678 0.03976 0.06372
## Detection Prevalence 0.5278 0.14325 0.1769 0.07358 0.07850
## Balanced Accuracy 0.7628 0.62130 0.6284 0.60115 0.66423
De igual manera construimos el modelo con el 70% de los datos de training y lo validamos con el 30% restante. En este caso la Accuracy no llega al 50%, definitivamente esta técnica de Machine Learning no es la apropiada para nuestros datos.
Modfit.gbm <- train(classe ~ ., method = "gbm", data = Dat.train.train, trControl = vControl, metric = vMetric, verbose = FALSE)
Pre.gbm <- predict(Modfit.gbm, Dat.train.valid)
confusionMatrix(Pre.gbm, Dat.train.valid$classe)
## Confusion Matrix and Statistics
##
## Reference
## Prediction A B C D E
## A 1649 32 0 0 2
## B 16 1064 48 6 8
## C 5 39 960 40 13
## D 4 1 15 912 12
## E 0 3 3 6 1047
##
## Overall Statistics
##
## Accuracy : 0.957
## 95% CI : (0.9515, 0.962)
## No Information Rate : 0.2845
## P-Value [Acc > NIR] : < 2.2e-16
##
## Kappa : 0.9456
##
## Mcnemar's Test P-Value : 5.575e-06
##
## Statistics by Class:
##
## Class: A Class: B Class: C Class: D Class: E
## Sensitivity 0.9851 0.9342 0.9357 0.9461 0.9677
## Specificity 0.9919 0.9836 0.9800 0.9935 0.9975
## Pos Pred Value 0.9798 0.9317 0.9082 0.9661 0.9887
## Neg Pred Value 0.9941 0.9842 0.9863 0.9895 0.9927
## Prevalence 0.2845 0.1935 0.1743 0.1638 0.1839
## Detection Rate 0.2802 0.1808 0.1631 0.1550 0.1779
## Detection Prevalence 0.2860 0.1941 0.1796 0.1604 0.1799
## Balanced Accuracy 0.9885 0.9589 0.9579 0.9698 0.9826
Para este modelo hacemos lo mismo, lo construimos con el 70% de los datos de training y lo validamos con el 30% restante. En este caso, la Accuracy es mas que aceptable llegando al 96%, dependiendo del resultado del ultimo modelo este podria ser el elegido.
Modfit.rf <- train(classe ~ ., method = "rf", data = Dat.train.train, trControl = vControl, metric = vMetric)
Pre.rf <- predict(Modfit.rf, Dat.train.valid)
confusionMatrix(Pre.rf, Dat.train.valid$classe)
## Confusion Matrix and Statistics
##
## Reference
## Prediction A B C D E
## A 1674 4 0 1 0
## B 0 1129 11 0 0
## C 0 6 1009 12 1
## D 0 0 6 951 0
## E 0 0 0 0 1081
##
## Overall Statistics
##
## Accuracy : 0.993
## 95% CI : (0.9906, 0.995)
## No Information Rate : 0.2845
## P-Value [Acc > NIR] : < 2.2e-16
##
## Kappa : 0.9912
##
## Mcnemar's Test P-Value : NA
##
## Statistics by Class:
##
## Class: A Class: B Class: C Class: D Class: E
## Sensitivity 1.0000 0.9912 0.9834 0.9865 0.9991
## Specificity 0.9988 0.9977 0.9961 0.9988 1.0000
## Pos Pred Value 0.9970 0.9904 0.9815 0.9937 1.0000
## Neg Pred Value 1.0000 0.9979 0.9965 0.9974 0.9998
## Prevalence 0.2845 0.1935 0.1743 0.1638 0.1839
## Detection Rate 0.2845 0.1918 0.1715 0.1616 0.1837
## Detection Prevalence 0.2853 0.1937 0.1747 0.1626 0.1837
## Balanced Accuracy 0.9994 0.9945 0.9898 0.9926 0.9995
Como podemos observar este es el modelo mas exacto, Random Forest, con una Accuracy que supera el 99%, practicamente inmejorable. Es el que usaremos para hacer nuestra predicción de la covariable ‘classe’ que determinará para cada una de las 20 muestras (individuos), su mamera de hacer ejercicio, siendo el valor A la manera correcta, y siendo B, C, D y E los 4 errores mas usuales a la hora de hacer los ejercicios del experimento.
Accu <- sum(Pre.rf == Dat.train.valid$classe) / length(Pre.rf)
Accu
## [1] 0.9930331
Error <- 1 - Accu
Error
## [1] 0.006966865
pError <- Error * 100
pError
## [1] 0.6966865
Hemos calculado la tasa de error ‘out-of-sample’ para nuestro modelo construido con Random Forest y como podiamos sospechar es muy baja, por debajo del 1% (0.7%). Podemos tener la seguridad de que el modelo ganador. A parte de ser el mejor de los calculados, tambien tiene un nivel de exactitud muy alto.
Pre.rf.testing <- predict(Modfit.rf, Dat.test)
Pre.rf.testing
## [1] B A B A A E D B A A B C B A E E A B B B
## Levels: A B C D E
La predicción de las 20 muestras (individuos) realizada con nuestro modelo ganador son todas correctas. El modelo se ajusta a la realidad de los datos perfectamente. Hemos comprobado que los 20 resultados son correctos introduciendolos en el Atomatized Quiz.