Для тренування моделі будемо використовувати безкоштовний набір даних з UCI. Тут зібрано дані показів сенсорів смартфона від 30 волонтерів у віці 10-48 років, які носили на зап'ясті Samsung Galaxy S II і вказували при цьому тип рухової активності. Типи активності такі: стоїть, сидить, лежить, гуляє, піднімається по сходах, спускається по сходах. Дані сенсорів були попередньо оброблені для відфільтрування шуму. Завантажити набір даних та прочитати детальніший опис можна тут.
Отже, почнемо:
Так як, дане завдання пропонувалось у курсі "Data Analysis", завантажити набір даних можна і таким чином:
# вказуємо url
url = "https://spark-public.s3.amazonaws.com/dataanalysis/samsungData.rda"
# завантажуємо дані в робочу директорію
dataset <- download.file(url, method = "curl", "samsungdata.rda")
# завантажуємо дані в R
samsungData <- data.frame(samsungData)
# конвертуємо у дата фрейм
load("samsungdata.rda")
Два останні стовпці subject - номер волонтера та activity - вид активності. Решта стовпців мають малоінформативні назви типу "fBodyBodyGyroJerkMag.kurtosis..", перейменуємо їх нескладною функцією:numbered.var <- function(x) {paste("feature", x, sep="")};
cnames.orig <- colnames(samsungData);
cnames.new <- c(numbered.var(seq(1:561)), c("subject","activity"));
colnames(samsungData) <- cnames.new
Виберемо набір даних для тренування (trainSD) та тестування (testSD) моделі:
# trainSD містить спостережння від волонтерів 1, 3, 5, 6
trainSD <- samsungData[samsungData$subject == 1 | samsungData$subject == 3 | samsungData$subject == 5 | samsungData$subject == 6, ]
trainsubj <- trainSD$subject
trainactivity <- trainSD$activity
trainSD <- trainSD[, -c(562, 563)]
# testSD містить спостережння від волонтерів 27, 28, 29, 30
testSD <- samsungData[samsungData$subject >= 27 & samsungData$subject <= 30, ]
testsubj <- testSD$subject
testactivity <- testSD$activity
testSD <- testSD[, -c(562, 563)]
Для побудови моделі використаємо алгоритм "випадкового лісу". Цей алгоритм дозволить вибрати лише ті фактори (покази сенсорів), які впливають на визначення активності.
library(randomForest)
rfmod <- randomForest(as.factor(activity) ~., data = trainSD,
importance=TRUE, proximity=TRUE,
ntree = 500, mtry = 40)
Подивимось на точність моделі:
> print(rfmod)
Call:
randomForest(formula = as.factor(trainactivity) ~ ., data = trainSD, importance = TRUE, proximity = TRUE, ntree = 500, mtry = 40)
Type of random forest: classification
Number of trees: 500
No. of variables tried at each split: 40
OOB estimate of error rate: 0.76%
Confusion matrix:
laying sitting standing walk walkdown walkup class.error
laying 221 0 0 0 0 0 0.000000000
sitting 0 195 3 0 0 0 0.015151515
standing 0 2 225 0 0 0 0.008810573
walk 0 0 0 263 3 0 0.011278195
walkdown 0 0 0 0 192 1 0.005181347
walkup 0 0 0 1 0 209 0.004761905
Як бачимо, дана модель пояснює більше 99 % тренувального набору даних.
Погратися з параметрами і обрати найкращу модель випадкового лісу можна використовуючи функцію tuneRF:
tuneRF(trainSD, as.factor(trainactivity), ntreeTry = 500, stepFactor = 2)
tuneRF(trainSD, as.factor(trainactivity), ntreeTry = 500, stepFactor = 1.5)
tuneRF(trainSD, as.factor(trainactivity), ntreeTry = 1000, mtryStart = 18, stepFactor = 4, improve = 0.01)
tuneRF(trainSD, as.factor(trainactivity), ntreeTry = 2500, mtryStart = 30, stepFactor = 4, improve = 0.01)
Функція varImpPlot покаже найважливіші предіктори.
Перевіримо точність моделі на тестовому наборі:
>
# будуємо прогноз:
predictactivity <- predict(rfmod, testSD)
# матриця відповідності реальне/прогнозоване значення
> table(predictactivity , t(testactivity))
prrf laying sitting standing walk walkdown walkup
laying 293 0 0 0 0 0
sitting 0 224 30 0 0 0
standing 0 40 253 0 0 7
walk 0 0 0 222 2 0
walkdown 0 0 0 7 193 16
walkup 0 0 0 0 5 193
Обчислимо точність прогнозу у відсотках:
> trueRate <- function(x, y){
+ sumi = 0
+ for (i in 1: length(y) ) {
+ if (x[i] == y[i]) sumi = sumi +1
+ }
+ return(sumi / length(y))
+ }
>
> trueRate(predictactivity, testactivity)
[1] 0.9279461
Отже, наша модель дозволяє визначити рухову активність з точністю 92,79%. Непогано.Можна починати писати софт ).
Звичайно, смартфон з собою носити тяжко, але от ідея застосування алгоритмів machine learning для біореєстратора Basis - дуже класна ідея.
Немає коментарів:
Дописати коментар