Practical Machine Learning Project

Classification of Motion Data by Activity

Background

Using devices such as Jawbone Up, Nike FuelBand, and Fitbit it is now possible to collect a large amount of data about personal activity relatively inexpensively. These type of devices are part of the quantified self movement - a group of enthusiasts who take measurements about themselves regularly to improve their health, to find patterns in their behavior, or because they are tech geeks. One thing that people regularly do is quantify how much of a particular activity they do, but they rarely quantify how well they do it. In this project, your goal will be to use data from accelerometers on the belt, forearm, arm, and dumbell of 6 participants. They were asked to perform barbell lifts correctly and incorrectly in 5 different ways. More information is available from the website here: http://groupware.les.inf.puc-rio.br/har (see the section on the Weight Lifting Exercise Dataset).

Data

The training data for this project are available here:

https://d396qusza40orc.cloudfront.net/predmachlearn/pml-training.csv

The test data are available here:

https://d396qusza40orc.cloudfront.net/predmachlearn/pml-testing.csv

The data for this project come from this source: http://groupware.les.inf.puc-rio.br/har. If you use the document you create for this class for any purpose please cite them as they have been very generous in allowing their data to be used for this kind of assignment.

Load packages

library(caret)
## Loading required package: lattice
## Loading required package: ggplot2

Load data sets

train.data <- read.csv("pml-training.csv")
test.data <- read.csv("pml-testing.csv")

Partition and clean data for analysis

Partition data into sample and validation sets

set.seed(92109)
train.partion <- createDataPartition(y=train.data$classe, 
                                     p=0.7, 
                                     list=FALSE)
train.sample <- train.data[train.partion, ]
train.validation <- train.data[-train.partion, ]

Remove variables with near zero variance using Caret’s nearZeroVar function

data.nearZero <- nearZeroVar(train.sample)
train.sample <- train.sample[, -data.nearZero]
train.validation <- train.validation[, -data.nearZero]

Remove variables that are NA greater than 95% of instances

data.na <- sapply(train.sample, function(x) mean(is.na(x))) > 0.95
train.sample <- train.sample[, data.na==FALSE]
train.validation <- train.validation[, data.na==FALSE]

Reviewing the data types, it is clear that the first 5 columns have no effect on the model

Remove the first 5 columns from the training and test sets

train.sample <- train.sample[, -(1:5)]
train.validation <- train.validation[, -(1:5)]

Analyze sample against validation set and prepare model to use 3-fold Cross Validation

train.Control <- trainControl(method="cv", number=3, verboseIter=FALSE)

Train random forest model on train.sample

train.fit <- train(classe ~ ., data=train.sample, method="rf", trControl=train.Control)
## Loading required package: randomForest
## randomForest 4.6-12
## Type rfNews() to see new features/changes/bug fixes.
train.fit$finalModel
## 
## Call:
##  randomForest(x = x, y = y, mtry = param$mtry) 
##                Type of random forest: classification
##                      Number of trees: 500
## No. of variables tried at each split: 27
## 
##         OOB estimate of  error rate: 0.17%
## Confusion matrix:
##      A    B    C    D    E  class.error
## A 3905    1    0    0    0 0.0002560164
## B    2 2654    2    0    0 0.0015048909
## C    0    5 2389    2    0 0.0029215359
## D    0    0    9 2243    0 0.0039964476
## E    0    0    0    2 2523 0.0007920792

Use model to predict classe in validation set

prediction.data <- predict(train.fit, newdata=train.validation)

Show confusion matrix to get estimate of out-of-sample error

confusionMatrix(train.validation$classe, prediction.data)
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction    A    B    C    D    E
##          A 1673    0    0    0    1
##          B    3 1135    1    0    0
##          C    0    2 1024    0    0
##          D    0    0    5  959    0
##          E    0    0    0    6 1076
## 
## Overall Statistics
##                                           
##                Accuracy : 0.9969          
##                  95% CI : (0.9952, 0.9982)
##     No Information Rate : 0.2848          
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.9961          
##  Mcnemar's Test P-Value : NA              
## 
## Statistics by Class:
## 
##                      Class: A Class: B Class: C Class: D Class: E
## Sensitivity            0.9982   0.9982   0.9942   0.9938   0.9991
## Specificity            0.9998   0.9992   0.9996   0.9990   0.9988
## Pos Pred Value         0.9994   0.9965   0.9981   0.9948   0.9945
## Neg Pred Value         0.9993   0.9996   0.9988   0.9988   0.9998
## Prevalence             0.2848   0.1932   0.1750   0.1640   0.1830
## Detection Rate         0.2843   0.1929   0.1740   0.1630   0.1828
## Detection Prevalence   0.2845   0.1935   0.1743   0.1638   0.1839
## Balanced Accuracy      0.9990   0.9987   0.9969   0.9964   0.9989

This seems to be a very accurate model with over 99% accuracy

Repeat previous analysis on training and test sets

Remove variables with nearly zero variance using nearZeroVar function from Caret package

data.nearZero <- nearZeroVar(train.data)
train.data <- train.data[, -data.nearZero]
test.data <- test.data[, -data.nearZero]

Remove variables that have an NA value greater than 95% of the time

data.na <- sapply(train.data, function(x) mean(is.na(x))) > 0.95
train.data <- train.data[, data.na==FALSE]
test.data <- test.data[, data.na==FALSE]

Reviewing the data types, it is clear that the first 5 columns have no effect on the model

Remove the first 5 columns from the training and test sets

train.data <- train.data[, -(1:5)]
test.data <- test.data[, -(1:5)]

Re-train model using full training set

train.Control <- trainControl(method="cv", number=3, verboseIter=FALSE)
train.fit <- train(classe ~ ., 
                   data=train.data, 
                   method="rf", 
                   trControl=train.Control)

Predict training set on test set

prediction.data <- predict(train.fit, 
                           newdata=test.data)
prediction.data <- as.character(prediction.data)

Function to write predictions to individual files provided by course

pml_write_files <- function(x) {
  n <- length(x)
  for(i in 1:n) {
    filename <- paste0("problem_id_", i, ".txt")
    write.table(x[i], file=filename, quote=F, row.names=FALSE, col.names=FALSE)
  }
}

Create prediction files to submit using function

pml_write_files(prediction.data)