Linhas de ônibus de Curitiba

Os dados utilizados neste problema são referentes a geolocalização de linhas de ônibus da cidade de Curitiba. O dataset é composto de 9999 observações e 5 variáveis, sendo estas:

Para um primeiro pre-processamento utilizamos Spark. Os dados estavam inicialmente no formado

{“VEIC”:“AA005”,“LAT”:“-25,398433”,“LON”:“-49,211905”,“DTHR”:“20/10/2015 18:53:17”,“COD_LINHA”:“812”} {“VEIC”:“AA005”,“LAT”:“-25,398546”,“LON”:“-49,211925”,“DTHR”:“20/10/2015 18:43:16”,“COD_LINHA”:“812”} {“VEIC”:“AA005”,“LAT”:“-25,398448”,“LON”:“-49,21203”,“DTHR”:“20/10/2015 18:33:15”,“COD_LINHA”:“812”} {“VEIC”:“AA005”,“LAT”:“-25,398323”,“LON”:“-49,212036”,“DTHR”:“20/10/2015 18:23:14”,“COD_LINHA”:“812”} {“VEIC”:“AA005”,“LAT”:“-25,398595”,“LON”:“-49,21202”,“DTHR”:“20/10/2015 18:16:46”,“COD_LINHA”:“812”} {“VEIC”:“AA005”,“LAT”:“-25,398325”,“LON”:“-49,211991”,“DTHR”:“20/10/2015 18:11:12”,“COD_LINHA”:“812”} {“VEIC”:“AA005”,“LAT”:“-25,398426”,“LON”:“-49,212041”,“DTHR”:“20/10/2015 18:01:11”,“COD_LINHA”:“812”}

Utilizando Spark rodamos um pre-processamento. O código desse pré-processamento é:

lines = sc.textFile(“dados_2.txt”) lineLengths = lines.map(lambda s: s.split(‘:’)[1].split(‘,’)[0][1:-1] + “,” + s.split(‘:’)[2].split(‘,’)[0][1:] + “.” + s.split(‘:’)[2].split(‘,’)[1][0:4] + “,” + s.split(‘:’)[3].split(‘,’)[0][1:] + “.” + s.split(‘:’)[3].split(‘,’)[1][0:4] + “,” + s.split(‘:’)[4].split()[0].split(“/”)[0][1:] + “,” + s.split(‘:’)[4].split()[0].split(“/”)[1] + “,” + s.split(‘:’)[4].split()[0].split(“/”)[2] + “,” + s.split(‘:’)[4].split()[1] + “,” + s.split(‘:’)[5] + “,” + s.split(‘:’)[7][1:-2]) lineLengths.saveAsTextFile(‘output2’)

Após esse pré-processamento ficamos com os dados no formato (em csv)

AA005,-25.3984,-49.2119,20,10,2015,18,53,812 AA005,-25.3985,-49.2119,20,10,2015,18,43,812 AA005,-25.3984,-49.2120,20,10,2015,18,33,812 AA005,-25.3983,-49.2120,20,10,2015,18,23,812 AA005,-25.3985,-49.2120,20,10,2015,18,16,812 AA005,-25.3983,-49.2119,20,10,2015,18,11,812 AA005,-25.3984,-49.2120,20,10,2015,18,01,812 AA005,-25.3984,-49.2120,20,10,2015,17,51,812

Com o arquivo CSV preparado começamos a trabalhar no R.

Carregando as bibliotecas

library(dplyr)
## 
## Attaching package: 'dplyr'
## 
## The following object is masked from 'package:stats':
## 
##     filter
## 
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)
library(caret)
## Loading required package: lattice

Criando a coluna distância e tempo

data_3 <- read.csv("/home/rodolfo/Projetos/DataAnalysis/Bus_Hadoop/spark-1.6.1-bin-without-hadoop/output2/data_3.csv", header=FALSE, quote="")

#Criando a coluna distância
data_3$Distancia <- NA
temp_veic <- ""

for (i in 1:nrow(data_3)){
   if (i == 1){
     data_3[i,10] = 0
     temp_veic <- data_3[i,1]
  }
  else{
     if (data_3[i,1] == temp_veic){
       data_3[i,10] = data_3[i-1,10] + sqrt(
          (as.numeric(as.character(data_3[i,2])) - 
                                              as.numeric(as.character(data_3[i-1,2])))^2 + 
                                              (as.numeric(as.character(data_3[i,3])) - 
                                                 as.numeric(as.character(data_3[i-1,3])))^2)
       
       
     }
     else{
        data_3[i,10] = 0
        temp_veic <- data_3[i,1]
     }
  }
}

#Criando a variavel tempo
data_3$timestamp <- as.POSIXct(strptime(x = as.character(paste(data_3[,7], data_3[,8], sep = ":")),
                           format = "%H:%M"))
data_3$Duracao <- NA
temp_veic <- ""

for (i in 1:nrow(data_3)){
   if (i == 1){
     data_3[i,12] = 0
     temp_veic <- data_3[i,1]
  }
  else{
     if (data_3[i,1] == temp_veic){
              data_3[i,12] = data_3[i-1,12] + (data_3[i-1,11]- data_3[i,11])
     }
     else{
        data_3[i,12] = 0
        temp_veic <- data_3[i,1]
     }
  }
}

Tabela atual

head(data_3)
##      V1       V2       V3 V4 V5   V6 V7 V8  V9    Distancia
## 1 AA005 -25.3984 -49.2119 20 10 2015 18 53 812 0.0000000000
## 2 AA005 -25.3985 -49.2119 20 10 2015 18 43 812 0.0001000000
## 3 AA005 -25.3984 -49.2120 20 10 2015 18 33 812 0.0002414214
## 4 AA005 -25.3983 -49.2120 20 10 2015 18 23 812 0.0003414214
## 5 AA005 -25.3985 -49.2120 20 10 2015 18 16 812 0.0005414214
## 6 AA005 -25.3983 -49.2119 20 10 2015 18 11 812 0.0007650282
##             timestamp Duracao
## 1 2016-04-12 18:53:00       0
## 2 2016-04-12 18:43:00      10
## 3 2016-04-12 18:33:00      20
## 4 2016-04-12 18:23:00      30
## 5 2016-04-12 18:16:00      37
## 6 2016-04-12 18:11:00      42

A princípio iremos fazer uma análise descritiva dos dados e uma análise de correlação das variáveis para identificar possíveis redundâncias.

colnames(data_3) <- c("Veic", "Lat", "Log", "Dia", "Mes", "Ano", "Hora", "Min", "Linha", "Distancia", "timestamp", "Duracao")

plot(data_3$Duracao)

plot(data_3$Distancia)

Podemos notar que essas duas variáveis sugere uma relação linear

Iremos agora construir o nosso primeiro modelo. Esse modelo será bem basico com apenas uma variável e vai servir como base para os outros modelos.

mod_1 <- lm(Duracao ~ Distancia, data = data_3)
summary(mod_1)
## 
## Call:
## lm(formula = Duracao ~ Distancia, data = data_3)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -292.264  -76.940    5.136   90.640  315.612 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -38.800      2.290  -16.94   <2e-16 ***
## Distancia    611.622      2.398  255.05   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 123.3 on 9997 degrees of freedom
## Multiple R-squared:  0.8668, Adjusted R-squared:  0.8668 
## F-statistic: 6.505e+04 on 1 and 9997 DF,  p-value: < 2.2e-16

É possível notar que temos alta a significância de que é pouco provável o fato de que não exista nenhuma relação entre as variáveis Duracao e Distancia,. Há evidência de que a relação entre essas duas variáveis seja forte, dado que o R-squared igual à 0,86. O que siginifica que a variável escolhidas explica em 83% a variável resposta (Duracao).

Iremos agora construir o um novo modelo. Adicionando a variável hora e min

mod_2 <- lm(Duracao ~ Distancia + Hora + Min, data = data_3)
summary(mod_2)
## 
## Call:
## lm(formula = Duracao ~ Distancia + Hora + Min, data = data_3)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -291.85  -77.04    4.89   89.86  317.83 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -39.36185    4.25574  -9.249   <2e-16 ***
## Distancia   611.57092    2.40182 254.628   <2e-16 ***
## Hora          0.11754    0.18980   0.619    0.536    
## Min          -0.03976    0.07436  -0.535    0.593    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 123.3 on 9995 degrees of freedom
## Multiple R-squared:  0.8668, Adjusted R-squared:  0.8668 
## F-statistic: 2.168e+04 on 3 and 9995 DF,  p-value: < 2.2e-16

Verificamos que as variáveis Hora e Min tem pouca significancia para o modelo. Por isso, iremos ficar com o modelo anterior.

Depois de escolhido o modelo, iremos divir os dados em 4. Onde cada conjunto vai ter os dados de apenas uma linha de ônibus (812 222 822 827). Dessa forma iremos descobrir qual é a linha de ônibus mais pontual

mod_812 <- lm(Duracao ~ Distancia, data = filter(data_3, Linha == "812"))
l_812 <- summary(mod_812)$r.squared

mod_222 <- lm(Duracao ~ Distancia, data = filter(data_3, Linha == "222"))
l_222 <- summary(mod_222)$r.squared

mod_822 <- lm(Duracao ~ Distancia, data = filter(data_3, Linha == "822"))
l_822 <- summary(mod_822)$r.squared

mod_827 <- lm(Duracao ~ Distancia, data = filter(data_3, Linha == "827"))
l_827 <- summary(mod_827)$r.squared

toPlot <- data.frame(R_Squared = c(l_812, l_222, l_822, l_827), 
                     Linha = c("812", "222", "822", "827"))


ggplot(toPlot, aes(x=reorder(Linha, -R_Squared), y=R_Squared)) + 
  geom_bar(stat="identity") + 
  labs(x='Linha', y='R_Squared') +
   theme(axis.text.x = element_text(angle = 45, hjust = 1), panel.background=element_blank()) +
  coord_flip()

As linhas 822 e 222 são as mais pontuais. Já a linha 827 é a menos pontual.