Aqui segue a coleta de dados do data set.
Podemos observar a tabela a seguir:
Na primeira linha: a dimensão do conjunto de dados, quantidades de observações (linhas) e quantidade de colunas, ou variáveis. Na demais linhas : a primeira coluna com os demes de cada viriável, o tipo do caracter da variável, se é numério, númeiro inteiro, string (caracteres) e a demonstração de cada variável dentro do conjunto de dados na terceira coluna.
# Loading Data
bikes <- read.csv('bikes.csv', sep = ',', header = T, stringsAsFactors = FALSE)
str(bikes)
## 'data.frame': 17379 obs. of 17 variables:
## $ instant : int 1 2 3 4 5 6 7 8 9 10 ...
## $ dteday : chr "2011-01-01" "2011-01-01" "2011-01-01" "2011-01-01" ...
## $ season : int 1 1 1 1 1 1 1 1 1 1 ...
## $ yr : int 0 0 0 0 0 0 0 0 0 0 ...
## $ mnth : int 1 1 1 1 1 1 1 1 1 1 ...
## $ hr : int 0 1 2 3 4 5 6 7 8 9 ...
## $ holiday : int 0 0 0 0 0 0 0 0 0 0 ...
## $ weekday : int 6 6 6 6 6 6 6 6 6 6 ...
## $ workingday: int 0 0 0 0 0 0 0 0 0 0 ...
## $ weathersit: int 1 1 1 1 1 2 1 1 1 1 ...
## $ temp : num 0.24 0.22 0.22 0.24 0.24 0.24 0.22 0.2 0.24 0.32 ...
## $ atemp : num 0.288 0.273 0.273 0.288 0.288 ...
## $ hum : num 0.81 0.8 0.8 0.75 0.75 0.75 0.8 0.86 0.75 0.76 ...
## $ windspeed : num 0 0 0 0 0 0.0896 0 0 0 0 ...
## $ casual : int 3 8 5 3 0 0 2 1 1 8 ...
## $ registered: int 13 32 27 10 1 1 0 2 7 6 ...
## $ cnt : int 16 40 32 13 1 1 2 3 8 14 ...
Podemos também observar as cinco primeiras linhas de nosso conjunto de dados, usando a função “head(bikes)” e as cinco últimas linhas do nosso conjunto de dados com a utilização da função “tail(bikes)”.
rbind(head(bikes), tail(bikes))
Segue o quadro abaixo com todas as colunas e a quantidade de valores minssing em nosso conjuntos de dados, ou seja, valores que não estão preeenchido com informações, valores faltantes.
Ao analisar o conjunto de dados, podemos perceber que temos quase 100% das informações preenchida, tendo soment dois campos da coluna “dteday” com falta de informação, denvendo ser aterada futuramente para a criação do modelo.
rbind(head(bikes), tail(bikes))
char.toPOSIXct <- function(inFrame) {
as.POSIXct(strptime(
paste(inFrame$dteday, " ",
as.character(inFrame$hr),
":00:00",
sep = ""),
"%Y-%m-%d %H:%M:%S")) }
bikes$dteday <- char.toPOSIXct(bikes)
sapply(bikes, function(x) sum(is.na(x)))
## instant dteday season yr mnth hr holiday
## 0 2 0 0 0 0 0
## weekday workingday weathersit temp atemp hum windspeed
## 0 0 0 0 0 0 0
## casual registered cnt
## 0 0 0
Como o objetivo do problema de negócio é a análise de demanda por biciletas, será realizar o primeiro filtro em nosso conjunto de dados para observarmos somentos os dias em que existiu a quantidade demandada de bicicleta acima de 100 unidades.
Ao realizar a filto somente acima de 100 unidades diárias, reduzimos o nosso conjunto de dados para 10.342 linhas
require(dplyr)
bikes <- bikes %>% filter(cnt >100)
dim(bikes)
## [1] 10344 17
Em primeiro momento separaremos, em conformidade com o objetivo de negócio, baseando no item “1.2. Informações do conjuntos de dados” e “1.3 Informações sobre os atributos” uma seleção de variáveis considerando as mais relevantes para o modelo.
Na transformação de carga iremos realizar a normalização das variáveis numéricas, transformando toda as coluna em uma mesma escala, para que possamos na hora de criar o modelo preditivo, possamos observar um nível de acúrária melhor.
Iremos também criar novas variáveis, para melhor entendimento do conjuntos de dados, afim de evitar possíveis erros em nosso conjuntos. Criaremos a coluna (“isWorking” - dias úteis, “monthCount” - mês e “dayWeek” - dia de semana).
cols <- c("dteday", "mnth", "hr", "holiday",
"workingday", "weathersit", "temp",
"hum", "windspeed", "cnt")
# Criando um subset dos dados
bikes <- bikes[,cols]
# Transformar o objeto de data
bikes$dteday <- char.toPOSIXct(bikes)
# Esta linha acima gera dois valores NA
# Esta linha abaixo corrige
bikes <- na.omit(bikes)
# Normalizar as variaveis preditoras numericas
cols <- c('temp', 'hum', 'windspeed')
bikes[,cols] <- scale(bikes[,cols])
str(bikes)
## 'data.frame': 10342 obs. of 10 variables:
## $ dteday : POSIXct, format: "2011-01-01 14:00:00" "2011-01-01 15:00:00" ...
## $ mnth : int 1 1 1 1 1 1 1 1 1 1 ...
## $ hr : int 14 15 8 17 18 19 8 17 18 19 ...
## $ holiday : int 0 0 0 0 0 0 0 0 0 0 ...
## $ workingday: int 0 0 1 1 1 1 1 1 1 1 ...
## $ weathersit: int 2 2 1 1 1 1 1 1 1 1 ...
## $ temp : num -0.542 -0.653 -2.317 -1.762 -1.762 ...
## $ hum : num 0.783 1.056 -0.417 -1.509 -1.399 ...
## $ windspeed : num 0.682 0.805 0.682 0.193 -0.787 ...
## $ cnt : int 106 110 154 157 157 110 179 212 182 112 ...
## - attr(*, "na.action")= 'omit' Named int [1:2] 3581 9289
## ..- attr(*, "names")= chr [1:2] "3581" "9289"
rbind(head(bikes), tail(bikes))
# Criar uma nova variável para indicar dia da semana (workday)
bikes$isWorking <- ifelse(bikes$workingday & !bikes$holiday, 1, 0)
# Adicionar uma coluna com a quantidade de meses, o que vai ajudar a criar o modelo
month.count <- function(inFrame){
Dteday <- strftime(inFrame$dteday, format = "%Y-%m-%dT%H:%M:%S")
yearCount <- as.numeric(unlist(lapply(strsplit(
Dteday, "-"),
function(x){x[1]}))) - 2011
inFrame$monthCount <- 12 * yearCount + inFrame$mnth
inFrame
}
bikes <- month.count(bikes)
# Criar um fator ordenado para o dia da semana, comecando por segunda-feira
bikes$dayWeek <- as.factor(weekdays(bikes$dteday))
head(bikes)
Podemos observar que na tabela acima que na coluna “dayWeek” está recebendo os dias da semana: de segunda-feira à domingo.
A tabela abaixo a coluna “dayWeek” agora os dias da semana devem estar como valores numéricos.
bikes$dayWeek <- as.numeric(ordered(bikes$dayWeek,
levels = c("segunda-feira",
"terça-feira",
"quarta-feira",
"quinta-feira",
"sexta-feira",
"sábado",
"domingo")))
head(bikes)
Adiciona uma variável com valores únicos para o horário do dia em dias de semana e dias de fim de semana. Com isso diferenciamos as horas dos dias de semana, das horas em dias de fim de semana
bikes$workTime <- ifelse(bikes$isWorking, bikes$hr, bikes$hr + 24)
# Transforma os valores de hora na madrugada, quando a demanda por bibicletas é praticamente nula
bikes$xformHr <- ifelse(bikes$hr > 4, bikes$hr - 5, bikes$hr + 19)
# Adiciona uma variável com valores únicos para o horário do dia para dias de semana e dias de fim de semana
# Considerando horas da madrugada
bikes$xformWorkHr <- ifelse(bikes$isWorking, bikes$xformHr, bikes$xformHr + 24)
str(bikes)
## 'data.frame': 10342 obs. of 16 variables:
## $ dteday : POSIXct, format: "2011-01-01 14:00:00" "2011-01-01 15:00:00" ...
## $ mnth : int 1 1 1 1 1 1 1 1 1 1 ...
## $ hr : int 14 15 8 17 18 19 8 17 18 19 ...
## $ holiday : int 0 0 0 0 0 0 0 0 0 0 ...
## $ workingday : int 0 0 1 1 1 1 1 1 1 1 ...
## $ weathersit : int 2 2 1 1 1 1 1 1 1 1 ...
## $ temp : num -0.542 -0.653 -2.317 -1.762 -1.762 ...
## $ hum : num 0.783 1.056 -0.417 -1.509 -1.399 ...
## $ windspeed : num 0.682 0.805 0.682 0.193 -0.787 ...
## $ cnt : int 106 110 154 157 157 110 179 212 182 112 ...
## $ isWorking : num 0 0 1 1 1 1 1 1 1 1 ...
## $ monthCount : num 1 1 1 1 1 1 1 1 1 1 ...
## $ dayWeek : num 6 6 1 1 1 1 2 2 2 2 ...
## $ workTime : num 38 39 8 17 18 19 8 17 18 19 ...
## $ xformHr : num 9 10 3 12 13 14 3 12 13 14 ...
## $ xformWorkHr: num 33 34 3 12 13 14 3 12 13 14 ...
## - attr(*, "na.action")= 'omit' Named int [1:2] 3581 9289
## ..- attr(*, "names")= chr [1:2] "3581" "9289"
Existe diversas técnicas para a análise de correlação entre as variáveis de nosso conjunto de dados. Em nosso modelo utilizaremos apenas duas:
Pearson - coeficiente usado para medir o grau de relacionamento entre duas variáveis com relação linear;
Spearman - teste não paramétrico, para medir o grau de relacionamento entre duas variaveis;
cols <- c("mnth", "hr", "holiday", "workingday",
"weathersit", "temp", "hum", "windspeed",
"isWorking", "monthCount", "dayWeek",
"workTime", "xformHr", "cnt")
# Vetor com os métodos de correlação
metodos <- c('pearson','spearman')
# Aplicando os métodos de correlação com a função cor()
cors <- lapply(metodos, function(method)
(cor(bikes[,cols], method = method)))
head(cors)
## [[1]]
## mnth hr holiday workingday weathersit
## mnth 1.000000000 -0.0136042973 0.008793902 -0.0138388321 0.05840581
## hr -0.013604297 1.0000000000 -0.005520887 -0.0006323913 -0.06736674
## holiday 0.008793902 -0.0055208870 1.000000000 -0.2425512192 -0.01835272
## workingday -0.013838832 -0.0006323913 -0.242551219 1.0000000000 0.04953479
## weathersit 0.058405813 -0.0673667444 -0.018352723 0.0495347916 1.00000000
## temp 0.064922430 0.0980559021 0.008323454 -0.0107187615 -0.10799126
## hum 0.169468456 -0.1618604473 -0.009470555 0.0342820187 0.43078518
## windspeed -0.138354012 0.0407698801 0.009087200 -0.0117451965 -0.02761308
## isWorking -0.013838832 -0.0006323913 -0.242551219 1.0000000000 0.04953479
## monthCount 0.402902865 -0.0183907785 0.012936999 -0.0144820763 0.03331750
## dayWeek 0.008096668 0.0057470548 -0.168587689 -0.6999169949 -0.05072788
## workTime 0.006903870 0.4174590932 0.218103726 -0.9089595324 -0.07309621
## xformHr 0.006098419 0.8160565174 0.001099527 -0.1151723378 -0.07917747
## cnt 0.072404459 0.0504996750 -0.010775456 -0.0178389461 -0.11363010
## temp hum windspeed isWorking monthCount
## mnth 0.064922430 0.169468456 -0.1383540123 -0.0138388321 0.402902865
## hr 0.098055902 -0.161860447 0.0407698801 -0.0006323913 -0.018390779
## holiday 0.008323454 -0.009470555 0.0090871999 -0.2425512192 0.012936999
## workingday -0.010718762 0.034282019 -0.0117451965 1.0000000000 -0.014482076
## weathersit -0.107991263 0.430785180 -0.0276130822 0.0495347916 0.033317501
## temp 1.000000000 -0.099110979 -0.0262672773 -0.0107187615 -0.032336350
## hum -0.099110979 1.000000000 -0.2708755225 0.0342820187 0.019952516
## windspeed -0.026267277 -0.270875522 1.0000000000 -0.0117451965 -0.074350779
## isWorking -0.010718762 0.034282019 -0.0117451965 1.0000000000 -0.014482076
## monthCount -0.032336350 0.019952516 -0.0743507788 -0.0144820763 1.000000000
## dayWeek -0.003146259 -0.053534426 0.0054068644 -0.6999169949 0.011405683
## workTime 0.050618075 -0.098629032 0.0276691407 -0.9089595324 0.005492974
## xformHr 0.109501457 -0.111091068 -0.0006654943 -0.1151723378 0.018037934
## cnt 0.271030746 -0.173727633 0.0278603203 -0.0178389461 0.300181501
## dayWeek workTime xformHr cnt
## mnth 0.008096668 0.006903870 0.0060984187 0.07240446
## hr 0.005747055 0.417459093 0.8160565174 0.05049967
## holiday -0.168587689 0.218103726 0.0010995270 -0.01077546
## workingday -0.699916995 -0.908959532 -0.1151723378 -0.01783895
## weathersit -0.050727878 -0.073096210 -0.0791774726 -0.11363010
## temp -0.003146259 0.050618075 0.1095014572 0.27103075
## hum -0.053534426 -0.098629032 -0.1110910680 -0.17372763
## windspeed 0.005406864 0.027669141 -0.0006654943 0.02786032
## isWorking -0.699916995 -0.908959532 -0.1151723378 -0.01783895
## monthCount 0.011405683 0.005492974 0.0180379337 0.30018150
## dayWeek 1.000000000 0.638407560 0.0968783145 0.01648730
## workTime 0.638407560 1.000000000 0.4448578968 0.03726271
## xformHr 0.096878314 0.444857897 1.0000000000 -0.02437982
## cnt 0.016487299 0.037262706 -0.0243798215 1.00000000
##
## [[2]]
## mnth hr holiday workingday weathersit
## mnth 1.000000000 -0.009966956 1.068391e-02 -0.013761000 0.06713597
## hr -0.009966956 1.000000000 -4.810764e-03 -0.024589912 -0.08804987
## holiday 0.010683908 -0.004810764 1.000000e+00 -0.242551219 -0.01758894
## workingday -0.013761000 -0.024589912 -2.425512e-01 1.000000000 0.05360624
## weathersit 0.067135968 -0.088049869 -1.758894e-02 0.053606243 1.00000000
## temp 0.023197931 0.094622754 1.038633e-02 -0.007768081 -0.12267617
## hum 0.170176626 -0.143611637 -9.450112e-03 0.033250566 0.41196984
## windspeed -0.132505594 0.029645340 1.159437e-02 -0.014872236 -0.05001919
## isWorking -0.013761000 -0.024589912 -2.425512e-01 1.000000000 0.05360624
## monthCount 0.433614594 -0.011592106 1.275534e-02 -0.014963469 0.03978622
## dayWeek 0.007751764 0.024715511 -1.681113e-01 -0.698787618 -0.05490375
## workTime 0.005768616 0.611634311 1.875545e-01 -0.787363909 -0.10482421
## xformHr 0.003588295 0.906614222 -4.852017e-05 -0.104754247 -0.09344981
## cnt 0.070978505 0.033706352 -9.114978e-04 -0.039531007 -0.11356974
## temp hum windspeed isWorking monthCount
## mnth 0.023197931 0.170176626 -0.132505594 -0.013761000 0.433614594
## hr 0.094622754 -0.143611637 0.029645340 -0.024589912 -0.011592106
## holiday 0.010386327 -0.009450112 0.011594371 -0.242551219 0.012755335
## workingday -0.007768081 0.033250566 -0.014872236 1.000000000 -0.014963469
## weathersit -0.122676167 0.411969843 -0.050019188 0.053606243 0.039786217
## temp 1.000000000 -0.093830267 -0.008052581 -0.007768081 -0.049966065
## hum -0.093830267 1.000000000 -0.274872087 0.033250566 0.023745360
## windspeed -0.008052581 -0.274872087 1.000000000 -0.014872236 -0.080276591
## isWorking -0.007768081 0.033250566 -0.014872236 1.000000000 -0.014963469
## monthCount -0.049966065 0.023745360 -0.080276591 -0.014963469 1.000000000
## dayWeek -0.008090398 -0.055440865 0.008845523 -0.698787618 0.011940045
## workTime 0.065124023 -0.120032441 0.030861247 -0.787363909 0.008132094
## xformHr 0.099076182 -0.103655240 -0.001651065 -0.104754247 0.014612159
## cnt 0.296568467 -0.182872397 0.038725711 -0.039531007 0.281719259
## dayWeek workTime xformHr cnt
## mnth 0.007751764 0.005768616 3.588295e-03 0.0709785050
## hr 0.024715511 0.611634311 9.066142e-01 0.0337063517
## holiday -0.168111320 0.187554495 -4.852017e-05 -0.0009114978
## workingday -0.698787618 -0.787363909 -1.047542e-01 -0.0395310066
## weathersit -0.054903746 -0.104824215 -9.344981e-02 -0.1135697367
## temp -0.008090398 0.065124023 9.907618e-02 0.2965684666
## hum -0.055440865 -0.120032441 -1.036552e-01 -0.1828723968
## windspeed 0.008845523 0.030861247 -1.651065e-03 0.0387257114
## isWorking -0.698787618 -0.787363909 -1.047542e-01 -0.0395310066
## monthCount 0.011940045 0.008132094 1.461216e-02 0.2817192592
## dayWeek 1.000000000 0.555704931 8.814110e-02 0.0402850454
## workTime 0.555704931 1.000000000 6.468276e-01 0.0520637898
## xformHr 0.088141100 0.646827621 1.000000e+00 -0.0389455295
## cnt 0.040285045 0.052063790 -3.894553e-02 1.0000000000
# Preprando o plot
require(lattice)
plot.cors <- function(x, labs){
diag(x) <- 0.0
plot( levelplot(x,
main = paste("Plot de Correlação utilizando o Método:", labs),
scales = list(x = list(rot = 90), cex = 1.0)) )
}
# Mapa de Correlação
Map(plot.cors, cors, metodos)
## [[1]]
## NULL
##
## [[2]]
## NULL
Neste momente, após a exploraração de nosso conjunto de dados, será iniciado o estudo de “series temporis” em nosso conjuntos de dados. Será anlisado a demanda de bicicletas ao longo do tempo constuindo um time series plot para alguns determinados horários em dias úteis e dias de fim de semana, para que possamos começar a identificar relações e período de alta e baixa demanda de bicicletas.
library(ggplot2)
times <- c(7, 9, 12, 15, 18, 20, 22)
# Time Series Plot
tms.plot <- function(times){
ggplot(bikes[bikes$workTime == times, ], aes(x = dteday, y = cnt)) +
geom_line() +
ylab('Número de Bikes') +
xlab('Data dia') +
labs(title = paste('Demanda de Bikes as ', as.character(times), ':00', sep =''))+
theme(text = element_text(size = 20))
}
lapply(times, tms.plot)
## [[1]]
##
## [[2]]
##
## [[3]]
##
## [[4]]
##
## [[5]]
##
## [[6]]
##
## [[7]]
# Convertendo a variável dayWeek para fator ordenado e plotando em ordem de tempo
fact.conv <- function(inVec){
outVec <- as.factor(inVec)
levels(outVec) <- c("Segunda", "Terca", "Quarta",
"Quinta", "Sexta", "Sabado",
"Domingo")
outVec
}
bikes$dayWeek <- fact.conv(bikes$dayWeek)
# Convertendo a variável isWorking para fator ordenado e plotando em Dia não Útil e Dia Útil
fact.conv1 <- function(inVec){
outVec1 <- as.factor(inVec)
levels(outVec1) <- c("Dia não Útil", "Dia Útil")
outVec1
}
bikes$isWorking <- fact.conv1(bikes$isWorking)
# Convertendo a variável isWorking para fator ordenado e plotando em Dia não Útil e Dia Útil
fact.conv2 <- function(inVec){
outVec2 <- as.factor(inVec)
levels(outVec2) <- c("Primavera", "Verão","Outuno", "Inverso")
outVec2
}
bikes$weathersit <- fact.conv2(bikes$weathersit)
# Demanda de bikes x potenciais variáveis preditoras
labels <- list("Boxplots - Demanda de Bikes por Hora",
"Boxplots - Demanda de Bikes por Estação",
"Boxplots - Demanda de Bikes por Dia Útil",
"Boxplots - Demanda de Bikes por Dia da Semana")
xAxis <- list("hr", "weathersit", "isWorking", "dayWeek")
# Função para criar os boxplots
plot.boxes <- function(X, label){
ggplot(bikes, aes_string(x = X, y = "cnt", group = X)) +
ylab('Número de Bikes alugadas') +
geom_boxplot( ) +
ggtitle(label) +
theme(text = element_text(size = 18))
}
Map(plot.boxes, xAxis, labels)
## [[1]]
##
## [[2]]
##
## [[3]]
##
## [[4]]
Visualizando o relacionamento entre as variáveis preditoras e demanda por bicicletas.
labels <- c("Demanda de Bikes vs Temperatura",
"Demanda de Bikes vs Humidade",
"Demanda de Bikes vs Velocidade do Vento",
"Demanda de Bikes vs Hora")
xAxis <- c("temp", "hum", "windspeed", "hr")
# Função para os Density Plots
plot.scatter <- function(X, label){
ggplot(bikes, aes_string(x = X, y = "cnt")) +
geom_point(aes_string(colour = "cnt"), alpha = 0.1) +
scale_colour_gradient(low = "green", high = "blue") +
geom_smooth(method = "loess") +
ggtitle(label) +
theme(text = element_text(size = 20))
}
Map(plot.scatter, xAxis, labels)
## $temp
##
## $hum
##
## $windspeed
##
## $hr
# Explorando a interação entre tempo e dia, em dias da semana e fins de semana
labels <- list("Box plots - Demanda por Bikes as 09:00 para \n dias da semana e fins de semana",
"Box plots - Demanda por Bikes as 18:00 para \n dias da semana e fins de semana")
Times <- list(9, 18)
plot.box2 <- function(time, label){
ggplot(bikes[bikes$hr == time, ], aes(x = isWorking, y = cnt, group = isWorking)) +
geom_boxplot( ) + ggtitle(label) +
theme(text = element_text(size = 18)) }
Map(plot.box2, Times, labels)
## [[1]]
##
## [[2]]
A seleção de Atributos, ou o Feature Selection tem como objetivo a simpleficação do modelo, para facilitar sua interpretação, dredução do tempo de treinamento do modelo e melhoria da generalização do modelo, evitando overfitting. Utilizaremos a tecnicas de feaure selection para automitizar a seleção de variáveis com maior potencial para variáveis preditoras. Sendo uma espécia de filtro, que remove do seu dataset as variáveis qwue não serão úteis para a criação do modelo preditivo. Tem como principal objetivo a criação de um modelo preditoco com a maior precisão possível e que seja generalizável. As técnicas de Feaure Selection basicamente calculam o nível de signifiância de cada variável e eliminam aquelas com significância mais baixa.
dim(bikes)
## [1] 10342 16
any()
## [1] FALSE
Criando um modelo para identificar os atributos com maior importância para o modelo preditivo
library(randomForest)
Modelo <- randomForest(cnt ~.,
data = bikes,
ntree = 100,
nodesize = 10,
inportance = TRUE)
# Plotando as variáveis por grau de importância
varImpPlot(Modelo)
# Removendo variáveis colineares
Modelo <- randomForest(cnt ~ . - mnth
- hr
- workingday
- isWorking
- dayWeek
- xformHr
- workTime
- holiday
- windspeed
- monthCount
- weathersit,
data = bikes,
ntree = 100,
nodesize = 10,
importance = TRUE)
# Removendo variáveis colineares
varImpPlot(Modelo)
# Função para tratar as datas
set.asPOSIXct <- function(inFrame) {
dteday <- as.POSIXct(
as.integer(inFrame$dteday),
origin = "1970-01-01")
as.POSIXct(strptime(
paste(as.character(dteday),
" ",
as.character(inFrame$hr),
":00:00",
sep = ""),
"%Y-%m-%d %H:%M:%S"))
}
char.toPOSIXct <- function(inFrame) {
as.POSIXct(strptime(
paste(inFrame$dteday, " ",
as.character(inFrame$hr),
":00:00",
sep = ""),
"%Y-%m-%d %H:%M:%S")) }
model <- randomForest(cnt ~ xformWorkHr + dteday + temp + hum,
data = bikes,
ntree = 40,
nodesize = 5)
print(model)
##
## Call:
## randomForest(formula = cnt ~ xformWorkHr + dteday + temp + hum, data = bikes, ntree = 40, nodesize = 5)
## Type of random forest: regression
## Number of trees: 40
## No. of variables tried at each split: 1
##
## Mean of squared residuals: 5421.007
## % Var explained: 80.39
scores <- data.frame(actual = bikes$cnt,
prediction = predict(model, newdata = bikes))
inFrame <- scores[, c("actual", "prediction")]
refFrame <- bikes
rbind(head(scores), tail(scores))
summary(scores)
## actual prediction
## Min. :101.0 Min. :112.2
## 1st Qu.:167.0 1st Qu.:188.6
## Median :246.0 Median :256.3
## Mean :294.1 Mean :294.3
## 3rd Qu.:377.0 3rd Qu.:362.7
## Max. :977.0 Max. :874.1
# Criando um dataframe
inFrame[, c("dteday", "monthCount", "hr", "xformWorkHr")] <- refFrame[, c("dteday", "monthCount", "hr", "xformWorkHr")]
# Nomeando o dataframe
names(inFrame) <- c("cnt", "predicted", "dteday", "monthCount", "hr", "xformWorkHr")
# Time series plot mostrando a diferença entre valores reais e valores previstos
inFrame <- inFrame[order(inFrame$dteday),]
s <- c(7, 9, 12, 15, 18, 20, 22)
lapply(s, function(s){
ggplot() +
geom_line(data = inFrame[inFrame$hr == s, ],
aes(x = dteday, y = cnt)) +
geom_line(data = inFrame[inFrame$hr == s, ],
aes(x = dteday, y = predicted), color = "red") +
ylab("Numero de Bikes") +
labs(title = paste("Demanda de Bikes as ",
as.character(s), ":00", spe ="")) +
theme(text = element_text(size = 20))
})
## [[1]]
##
## [[2]]
##
## [[3]]
##
## [[4]]
##
## [[5]]
##
## [[6]]
##
## [[7]]
Conforme podemos observar a linha preta é exatamento os dados que temos nosso conjuto de dados original.
A linha vermelha demonstra as nossas previsões com o modelo.
inFrame <- mutate(inFrame, resids = predicted - cnt)
# Plotando os resíduos
ggplot(inFrame, aes(x = resids)) +
xlab('Resíduos') +
ylab("Quantidade") +
theme_classic() +
geom_histogram(binwidth = 1, fill = "white", color = "steelblue")
# Distribuição os resíduos
qqnorm(inFrame$resids)
qqline(inFrame$resids)
# Plotando os resíduos com as horas transformadas
inFrame <- mutate(inFrame, fact.hr = as.factor(hr),
fact.xformWorkHr = as.factor(xformWorkHr))
facts <- c("fact.hr", "fact.xformWorkHr")
lapply(facts, function(x){
ggplot(inFrame, aes_string(x = x, y = "resids"), fill = "steelblue") +
geom_boxplot( ) +
ggtitle("Residuos - Demanda de Bikes por Hora - Atual vs Previsto")})
## [[1]]
##
## [[2]]
head(inFrame)
# Mediana dos resíduos por hora
evalFrame <- inFrame %>%
group_by(hr) %>%
summarise(medResidByHr = format(round(
median(predicted - cnt), 2),
nsmall = 2))
# Computando a mediana dos resíduos
tempFrame <- inFrame %>%
group_by(monthCount) %>%
summarise(medResid = median(predicted - cnt))
summary(tempFrame)
## monthCount medResid
## Min. : 1.00 Min. :-0.9845
## 1st Qu.: 6.75 1st Qu.: 4.5589
## Median :12.50 Median : 6.0890
## Mean :12.50 Mean : 6.2618
## 3rd Qu.:18.25 3rd Qu.: 8.2514
## Max. :24.00 Max. :13.9239
head(evalFrame)