A base de dados que será usada nesse estudo consiste em dados sobre as votações que candidatos à Câmara Federal de Deputados receberam nos anos de 2006 e 2010 (fonte: http://www.tse.jus.br), além de informações sobre arreadação de campanha, partido, escolaridade, etc.. dos mesmos.
eleicoes_data <- read_csv(
here('./eleicoes_2006_e_2010.csv'),
local= locale("br"),
col_types = cols(
ano = col_integer(), # ano de referencia
sequencial_candidato = col_character(), # id do candidato
quantidade_doacoes = col_integer(),
quantidade_doadores = col_integer(), # número de doadores diferentes
total_receita = col_double(), # soma em R$ das doações
media_receita = col_double(), # média das doações
recursos_de_outros_candidatos.comites = col_double(), # quantia em R$ das doações provenientes de outros candidatos ou comite partidário
recursos_de_pessoas_fisicas = col_double(), # quantia em R$ das doações provenientes de outros CPFs
recursos_de_pessoas_juridicas = col_double(), # quantia em R$ das doações provenientes de outros CNPJ
recursos_proprios = col_double(), # quantia em R$ das doações provenientes do próprio candidato
`recursos_de_partido_politico` = col_double(), # quantia em R$ das doações provenientes do partido político do candidato
quantidade_despesas = col_integer(),
quantidade_fornecedores = col_integer(), # número de fornecedores/despesas diferentes
total_despesa = col_double(), # soma em R$ das despesas de campanha
media_despesa = col_double(), # média das despesas de campanha
votos = col_integer(), # variável alvo. Se refere ao número de votos na campanha de 2006 ou 2010
.default = col_character()))
eleicoes_data %>%
glimpse()
## Observations: 7,476
## Variables: 24
## $ ano <int> 2006, 2006, 2006, 2006, ...
## $ sequencial_candidato <chr> "10001", "10002", "10002...
## $ nome <chr> "JOSÉ LUIZ NOGUEIRA DE S...
## $ uf <chr> "AP", "RO", "AP", "MS", ...
## $ partido <chr> "PT", "PT", "PT", "PRONA...
## $ quantidade_doacoes <int> 6, 13, 17, 6, 48, 6, 14,...
## $ quantidade_doadores <int> 6, 13, 16, 6, 48, 6, 7, ...
## $ total_receita <dbl> 16600.00, 22826.00, 1581...
## $ media_receita <dbl> 2766.67, 1755.85, 9301.2...
## $ recursos_de_outros_candidatos.comites <dbl> 0.00, 6625.00, 2250.00, ...
## $ recursos_de_pessoas_fisicas <dbl> 9000.00, 15000.00, 34150...
## $ recursos_de_pessoas_juridicas <dbl> 6300.00, 1000.00, 62220....
## $ recursos_proprios <dbl> 1300.00, 201.00, 59500.0...
## $ recursos_de_partido_politico <dbl> 0, 0, 0, 0, 0, 0, 0, 0, ...
## $ quantidade_despesas <int> 14, 24, 123, 8, 133, 9, ...
## $ quantidade_fornecedores <int> 14, 23, 108, 8, 120, 9, ...
## $ total_despesa <dbl> 16583.60, 20325.99, 1460...
## $ media_despesa <dbl> 1184.54, 846.92, 1187.09...
## $ cargo <chr> "DEPUTADO FEDERAL", "DEP...
## $ sexo <chr> "MASCULINO", "FEMININO",...
## $ grau <chr> "ENSINO MÉDIO COMPLETO",...
## $ estado_civil <chr> "CASADO(A)", "SOLTEIRO(A...
## $ ocupacao <chr> "VEREADOR", "SERVIDOR PÚ...
## $ votos <int> 8579, 2757, 17428, 1193,...
sample_n(eleicoes_data %>% select(ano, nome, uf, partido), 7)
sapply(eleicoes_data , class)
## ano
## "integer"
## sequencial_candidato
## "character"
## nome
## "character"
## uf
## "character"
## partido
## "character"
## quantidade_doacoes
## "integer"
## quantidade_doadores
## "integer"
## total_receita
## "numeric"
## media_receita
## "numeric"
## recursos_de_outros_candidatos.comites
## "numeric"
## recursos_de_pessoas_fisicas
## "numeric"
## recursos_de_pessoas_juridicas
## "numeric"
## recursos_proprios
## "numeric"
## recursos_de_partido_politico
## "numeric"
## quantidade_despesas
## "integer"
## quantidade_fornecedores
## "integer"
## total_despesa
## "numeric"
## media_despesa
## "numeric"
## cargo
## "character"
## sexo
## "character"
## grau
## "character"
## estado_civil
## "character"
## ocupacao
## "character"
## votos
## "integer"
Agora separamos os conjuntos de dados das duas eleições.
data_2006 = eleicoes_data %>%
filter(ano == 2006)
data_2010 = eleicoes_data %>%
filter(ano == 2010)
Com os dados separados vamos uma exploração inicial de alguns pontos quanto aos dados que estão sendo tema de discussão atualmente, como por exemplo, participação femininina, escolaridade e ocupação dos candidatos além da origem da verba de suas campanhas.
eleicoes_data %>%
group_by(sexo, ano) %>%
summarize(n = n()) %>%
ggplot(aes(reorder(sexo,n), n)) +
geom_bar(stat = "identity") +
labs(x="Gender",
y="Absolute Count") +
facet_grid(. ~ano)
parties_with_more_candidates_2006 = data_2006 %>%
group_by(partido) %>%
summarise(num = n()) %>%
top_n(5, num)
data_2006 %>%
filter(partido %in% parties_with_more_candidates_2006$partido) %>%
group_by(partido, sexo) %>%
summarise(num = n()) %>%
ggplot(aes(reorder(sexo, num), num)) +
geom_col(stat = "identity") +
labs(x="Gender",
y="Absolute Count") +
facet_grid(. ~partido)
## Warning: Ignoring unknown parameters: stat
Como podemos ver, tanto em números gerais quanto para todos os partidos apresentados
# escolaridade
schooling = data_2006 %>%
group_by(grau) %>%
summarise(num = n())
schooling %>%
ggplot(aes(x = reorder(grau, num), y = num)) +
geom_col() +
labs(x="Degree of schooling",
y="Absolute Count") +
coord_flip()
Vemos que maioria dos candidatos estão em um nível de entre ensino médio completo e ensino superior completo, o que pode parecer até uma noticia animadora.
accupation = data_2006 %>%
filter(ocupacao != "OUTROS") %>%
group_by(ocupacao) %>%
summarise(num = n()) %>%
top_n(10, num)
accupation %>%
ggplot(aes(x = reorder(ocupacao, num), y = num)) +
geom_col() +
labs(x="Occupation",
y="Absolute Count") +
coord_flip()
Vemos que maioria dos cadidatos são advogados ou empresários, remetendo a uma dominancia das classes mais bem afortunadas da sociedade, além de uma grande participação de politicos que já se declaram estritamente politicos.
parties_with_more_money_2006 = data_2006 %>%
group_by(partido) %>%
summarise(
total = sum(total_receita),
self = sum(recursos_proprios) + sum(recursos_de_partido_politico),
donations = sum(recursos_de_pessoas_fisicas) + sum(recursos_de_pessoas_juridicas),
by_people = sum(recursos_de_pessoas_fisicas),
by_companies = sum(recursos_de_pessoas_juridicas)) %>%
top_n(5, total)
p1 <- parties_with_more_money_2006 %>%
ggplot(aes(x = reorder(partido, total), y = total)) +
geom_col() +
labs(x="Party",
y="Amount") +
labs(title = "Parties with more money") +
coord_flip()
p2 <- parties_with_more_money_2006 %>%
ggplot(aes(x = reorder(partido, self), y = self)) +
geom_col() +
labs(x="Party",
y="Amount") +
labs(title = "Parties with more own money") +
coord_flip()
p3 <- parties_with_more_money_2006 %>%
ggplot(aes(x = reorder(partido, donations), y = donations)) +
geom_col() +
labs(x="Party",
y="Amount") +
labs(title = "Parties with more money donated") +
coord_flip()
p4 <- parties_with_more_money_2006 %>%
ggplot(aes(x = reorder(partido, by_people), y = by_people)) +
geom_col() +
labs(x="Party",
y="Amount") +
labs(title = "Parties with more money donated by people") +
coord_flip()
p5 <- parties_with_more_money_2006 %>%
ggplot(aes(x = reorder(partido, by_companies), y = by_companies)) +
geom_col() +
labs(x="Party",
y="Amount") +
labs(title = "Parties with more money donated by companies") +
coord_flip()
grid.arrange(p1, p2, p3, p4, p5, nrow = 3)
data_2006 %>%
select(-partido,
-uf,-nome,
-estado_civil,
-ocupacao,-ano,
-cargo,-grau,-sexo,
-sequencial_candidato) %>%
na.omit() %>%
ggcorr(palette = "RdBu",
color = "grey50",
label = TRUE, hjust = 1,
label_size = 3, size = 4,
nbreaks = 5, layout.exp = 7) +
ggtitle("Correlation plot for 2006 elections")
data_2010 %>%
select(-partido,
-uf,-nome,
-estado_civil,
-ocupacao,-ano,
-cargo,-grau,-sexo,
-sequencial_candidato) %>%
na.omit() %>%
ggcorr(palette = "RdBu",
color = "grey50",
label = TRUE, hjust = 1,
label_size = 3, size = 4,
nbreaks = 5, layout.exp = 7) +
ggtitle("Correlation plot for 2010 elections")
Agora, apresentados os dados, vamos tabalhar em uma regressão linear para explicar o numero de votos que o candidato conseguiu, e atráves disso, responder a uma série de perguntas que serão apresentadas no decorrer desse estudo.
Passaremos não somente pela criação e simples avaliação de um modelo, mas também pela análise de residuas e validação, nesse caminho, algumas outras questões serão respondidas, serão destacadas para o leitor, para que não hajam dúvidas.
Primeiramente vamos transformar todas as variáveis qualitativas em fatores, e depois novamente separar os dados em dois conjuntos, um para cada uma das eleições.
eleicoes_data = eleicoes_data %>%
mutate(uf = as.factor(uf),
nome = as.factor(nome),
sexo = as.factor(sexo),
grau = as.factor(grau),
nome = as.factor(nome),
cargo = as.factor(cargo),
partido = as.factor(partido),
ocupacao = as.factor(ocupacao),
estado_civil = as.factor(estado_civil),
sequencial_candidato = as.numeric(sequencial_candidato))
data_2006 = eleicoes_data %>%
filter(ano == 2006)
data_2010 = eleicoes_data %>%
filter(ano == 2010)
Agora temos os conjuntos de dados com os seguintes datatypes em suas colunas
data_2006 %>%
glimpse()
## Observations: 3,436
## Variables: 24
## $ ano <int> 2006, 2006, 2006, 2006, ...
## $ sequencial_candidato <dbl> 10001, 10002, 10002, 100...
## $ nome <fct> JOSÉ LUIZ NOGUEIRA DE SO...
## $ uf <fct> AP, RO, AP, MS, RO, PI, ...
## $ partido <fct> PT, PT, PT, PRONA, PT, P...
## $ quantidade_doacoes <int> 6, 13, 17, 6, 48, 6, 14,...
## $ quantidade_doadores <int> 6, 13, 16, 6, 48, 6, 7, ...
## $ total_receita <dbl> 16600.00, 22826.00, 1581...
## $ media_receita <dbl> 2766.67, 1755.85, 9301.2...
## $ recursos_de_outros_candidatos.comites <dbl> 0.00, 6625.00, 2250.00, ...
## $ recursos_de_pessoas_fisicas <dbl> 9000.00, 15000.00, 34150...
## $ recursos_de_pessoas_juridicas <dbl> 6300.00, 1000.00, 62220....
## $ recursos_proprios <dbl> 1300.00, 201.00, 59500.0...
## $ recursos_de_partido_politico <dbl> 0, 0, 0, 0, 0, 0, 0, 0, ...
## $ quantidade_despesas <int> 14, 24, 123, 8, 133, 9, ...
## $ quantidade_fornecedores <int> 14, 23, 108, 8, 120, 9, ...
## $ total_despesa <dbl> 16583.60, 20325.99, 1460...
## $ media_despesa <dbl> 1184.54, 846.92, 1187.09...
## $ cargo <fct> DEPUTADO FEDERAL, DEPUTA...
## $ sexo <fct> MASCULINO, FEMININO, FEM...
## $ grau <fct> ENSINO MÉDIO COMPLETO, S...
## $ estado_civil <fct> CASADO(A), SOLTEIRO(A), ...
## $ ocupacao <fct> VEREADOR, SERVIDOR PÚBLI...
## $ votos <int> 8579, 2757, 17428, 1193,...
Agora vamos criar o conjunto de treino, para iniciarmos a modelagem da função linear, criando primeiramente uma semente para que o estudo possa ser reproduzido com os mesmo resultados.
set.seed(1) # for reproducible example
data_2006$id <- 1:nrow(data_2006)
E também um conjunto de testes e outro de validação, com o de treino com 60% dos dados, os outros 40% serão usados para geração dos conjuntos de validação e testes.
training_data_2006 = data_2006 %>%
sample_frac(.6)
encoding <- build_encoding(dataSet = training_data_2006,
cols = c("uf","sexo","grau",
"partido","estado_civil"),
verbose = F)
training_data_2006 <- one_hot_encoder(dataSet = training_data_2006,
encoding = encoding,
drop = TRUE,
verbose = F)
remaining_2006 = anti_join(data_2006, training_data_2006, by = 'id')
testing_data_2006 = remaining_2006 %>%
sample_frac(.5)
testing_data_2006 <- one_hot_encoder(dataSet = testing_data_2006,
encoding = encoding,
drop = TRUE,
verbose = F)
validate_data_2006 = anti_join(remaining_2006, testing_data_2006, by = 'id')
validate_data_2006 <- one_hot_encoder(dataSet = validate_data_2006,
encoding = encoding,
drop = TRUE,
verbose = F)
rm(remaining_2006)
model_2006 = lm(votos ~ partido.PSDB + partido.PT + quantidade_doacoes + quantidade_doadores + total_receita + media_receita
+ recursos_de_outros_candidatos.comites + recursos_de_pessoas_fisicas + recursos_de_pessoas_juridicas
+ recursos_proprios + recursos_de_partido_politico + quantidade_despesas + quantidade_fornecedores
+ total_despesa + media_despesa + sexo.MASCULINO + `grau.SUPERIOR COMPLETO` + sexo.FEMININO
+ `grau.ENSINO FUNDAMENTAL COMPLETO` + `grau.ENSINO FUNDAMENTAL INCOMPLETO` + `grau.ENSINO MÉDIO COMPLETO`
+ `grau.ENSINO MÉDIO INCOMPLETO` + `grau.LÊ E ESCREVE` + `grau.SUPERIOR INCOMPLETO` + partido.DEM
+ `partido.PC do B` + `partido.PDT` + partido.PHS + partido.PMDB + partido.PP + partido.PPS + partido.PR
+ partido.PSB + partido.PSL + partido.PSOL + partido.PTB + partido.PV + estado.civil.CASADO.A. + estado.civil.DIVORCIADO.A.
+ `estado.civil.SEPARADO.A. JUDICIALMENTE` + `estado.civil.SOLTEIRO.A.` + `estado.civil.VIÚVO.A.`,
data = testing_data_2006)
Agora que temos o modelo pronto, famos fazeer uma pequena análise de suas significancia.
glance(model_2006)
Nossa estatistica de R² mostra ser moderada, explicando cerca de 54% da variação dos dados, e tendo um diferença mínima para o R² ajustado, o que é muito pouco satisfatória, tendo em vista a quantidade de variáveis usadas, existe o risco de uma estar atrapalhando outra.
data_2010$id <- 1:nrow(data_2010)
training_data_2010 = data_2010 %>%
sample_frac(.6)
encoding <- build_encoding(dataSet = training_data_2010,
cols = c("uf","sexo","grau",
"partido","estado_civil"),
verbose = F)
training_data_2010 <- one_hot_encoder(dataSet = training_data_2010,
encoding = encoding,
drop = TRUE,
verbose = F)
remaining_2010 = anti_join(data_2010, training_data_2010, by = 'id')
testing_data_2010 = remaining_2010 %>%
sample_frac(.5)
testing_data_2010 <- one_hot_encoder(dataSet = testing_data_2010,
encoding = encoding,
drop = TRUE,
verbose = F)
validate_data_2010 = anti_join(remaining_2010, testing_data_2010, by = 'id')
validate_data_2010 <- one_hot_encoder(dataSet = validate_data_2010,
encoding = encoding,
drop = TRUE,
verbose = F)
rm(remaining_2010)
model_2010 = lm(votos ~ partido.PSDB + partido.PT + quantidade_doacoes + quantidade_doadores + total_receita + media_receita
+ recursos_de_outros_candidatos.comites + recursos_de_pessoas_fisicas + recursos_de_pessoas_juridicas
+ recursos_proprios + recursos_de_partido_politico + quantidade_despesas + quantidade_fornecedores
+ total_despesa + media_despesa + sexo.MASCULINO + `grau.SUPERIOR COMPLETO` + sexo.FEMININO
+ `grau.ENSINO FUNDAMENTAL COMPLETO` + `grau.ENSINO FUNDAMENTAL INCOMPLETO` + `grau.ENSINO MÉDIO COMPLETO`
+ `grau.ENSINO MÉDIO INCOMPLETO` + `grau.LÊ E ESCREVE` + `grau.SUPERIOR INCOMPLETO` + partido.DEM
+ `partido.PC do B` + `partido.PDT` + partido.PHS + partido.PMDB + partido.PP + partido.PPS + partido.PR
+ partido.PSB + partido.PSL + partido.PSOL + partido.PTB + partido.PV + estado.civil.CASADO.A. + estado.civil.DIVORCIADO.A.
+ `estado.civil.SEPARADO.A. JUDICIALMENTE` + `estado.civil.SOLTEIRO.A.` + `estado.civil.VIÚVO.A.`,
data = testing_data_2010)
glance(model_2010)
Vemos que, para os dados de 2010, o modelo com todas as variáveis se torna um pouco mais representativo, explicando cerca de 64% da mudança nos dados, e com um R² ajustado bem próximo disso, então acho que podemos considerar que o modelo com todas as variáveis não seria válido para esses dados.
Pórem, uma análise embasada somento no R² e R² ajustado pode estar nos levando a uma opinião muito inocente sobre o modelo, então, a seguir, faremos uma série de outras análises em cima do modelo, para podermos ter uma opinião mais fortemente embasado sobre sua eficacia.
Quais variáveis conseguem explicar melhor o número de votos? Compare essas variáveis entre os modelos. Mesma coisa para as variáveis menos explicativas.
Primeiro vamos ver quais variáveis tiveram um p-valor mais alto, ou seja, os que se mostram menos confiáveis.
# preditores com p valor alto
tidy(model_2006,
conf.int = TRUE,
conf.level = .97) %>%
top_n(3, p.value) %>%
ggplot(aes(reorder(term, p.value), p.value)) +
geom_point() +
labs(x = "Variable",
y = "Estimation (97% of confidence)")
E agora, no extremo contrário, as variáveis com p-valor mais baixo.
# preditores com um p valor baixo
tidy(model_2006,
conf.int = TRUE,
conf.level = 0.97) %>%
arrange(p.value) %>%
slice(1:3) %>%
ggplot(aes(reorder(term, p.value), p.value)) +
geom_hline(yintercept = 0.05) +
geom_point(size = 3.5) +
labs(x = "Variable",
y = "Estimated value (97% of confidence)")
E agora para os dados de 2010, primeiramente para p-valor alto
tidy(model_2010,
conf.int = TRUE,
conf.level = .97) %>%
top_n(3, p.value) %>%
ggplot(aes(reorder(term, p.value), p.value)) +
geom_point() +
labs(x = "Variable",
y = "Estimation (97% of confidence)")
e agora, p-valor baixo
tidy(model_2010,
conf.int = TRUE,
conf.level = 0.97) %>%
arrange(p.value) %>%
slice(1:3) %>%
ggplot(aes(reorder(term, p.value), p.value)) +
geom_hline(yintercept = 0.05) +
geom_point(size = 3.5) +
labs(x = "Variable",
y = "Estimated value (97% of confidence)")
Nos gráficos acima, podemos perceber em linhas gerais que variáveis ligadas ao montante de dinheiro que os partidos investem eu suas campanhas parecem mais seguramente relacionadas ao número de vostos adquiridos em ambas as campanhas, com a excessão da presensa da variável partido-PR para 2010, e como variáveis suspeitas de não terem relação com o número de votos estão as relacionadas com qual o partido politico e escolaridade do cadidato, juntamente com seu estado civil, que se torna menos importante ainda, nas eleições de 2010.
model_2006 %>%
ggplot(aes(.fitted, .resid)) +
geom_point() +
stat_smooth(method="loess") +
geom_hline(col="red",
yintercept = 0,
linetype="dashed") +
labs(y="Residuals",
x="Fitted values",
title="Residual vs Fitted Plot (2006)")
E agora para os dados de 2010
model_2010 %>%
ggplot(aes(.fitted, .resid)) +
geom_point() +
stat_smooth(method="loess") +
geom_hline(col="red",
yintercept = 0,
linetype="dashed") +
labs(y="Residuals",
x="Fitted values",
title="Residual vs Fitted Plot (2010)")
Para ambos os conjuntos de dados, vemos que a distribuição dos pontos não é aleatoria nem igualmente distribuida ao longo do eixo x, o que pode mostrar que o modelo pode não estar considerando relações não lineares, ou indicar que variáveis que seriam importantes ao modelo não foram incluidas.
model_2006 %>%
ggplot(aes(.fitted,
sqrt(abs(.stdresid)))) +
geom_point(na.rm=TRUE) +
stat_smooth(method="loess",
na.rm = TRUE) +
labs(title = "Scale-Location (2006)",
x= "Fitted Value",
y = expression(sqrt("|Standardized residuals|")))
model_2010 %>%
ggplot(aes(.fitted,
sqrt(abs(.stdresid)))) +
geom_point(na.rm=TRUE) +
stat_smooth(method="loess",
na.rm = TRUE) +
labs(title = "Scale-Location (2010)",
x= "Fitted Value",
y = expression(sqrt("|Standardized residuals|")))
Novamente, ambos o modelos não mostram homocedasticidade e mostrarem um certo padrão, pode não estar considerando variáveis que são as reais responsáveis pela votação de um candidato, ou o excesso de variáveis que podem estar atrapalhando o modelo, além do erro irredutivel.
model_2006 %>%
ggplot(aes(.hat, .stdresid)) +
geom_point(aes(size=.cooksd), na.rm=TRUE) +
stat_smooth(method="loess", na.rm=TRUE) +
xlab("Leverage")+ylab("Standardized Residuals") +
ggtitle("Residual vs Leverage Plot (2006)") +
scale_size_continuous("Cook's Distance", range=c(1,5)) +
theme(legend.position="bottom")
model_2010 %>%
ggplot(aes(.hat, .stdresid)) +
geom_point(aes(size=.cooksd), na.rm=TRUE) +
stat_smooth(method="loess", na.rm=TRUE) +
xlab("Leverage") +
ylab("Standardized Residuals") +
ggtitle("Residual vs Leverage Plot (2010)") +
scale_size_continuous("Cook's Distance", range=c(1,5)) +
theme(legend.position="bottom")
Para ambas as eleições vemos muitos valores com distancias de cook muito altas, o que mostra o o modelo é distoante com muitos dos valores, o que pode nos dizer que o modelo é bom, pois existem muitos dados que se mostram grandes influenciadores do modelo, mesmo quando a modelagem pode os ver como ouliers.
predictions <- model_2006 %>% predict(validate_data_2006)
## Warning in predict.lm(., validate_data_2006): prediction from a rank-
## deficient fit may be misleading
data.frame( R2 = R2(predictions, validate_data_2006$votos),
RMSE = RMSE(predictions, validate_data_2006$votos),
MAE = MAE(predictions, validate_data_2006$votos),
ERR = RMSE(predictions, validate_data_2006$votos)/
mean(validate_data_2006$votos))
O modelo conseguiu um R² de 0,57, isso significa que esse modelo explica aproximadamente 57% da variabilidade da variável resposta. A diferença média entre os valores de resultados conhecidos observados e os valores previstos pelo modelo (RMSE) foi de aproximadamente 28340,5 issod quer dizer que o modelo erraria aproximadamente 28340, ou seja, se o candidato tivesse um milhão de votos, nós preveríamos até 28340 mais/menos do que deveríamos A diferença absoluta média entre os resultados observados e previstos (MAE) foi de aproximadamente 15924.48. A taxa de erro de previsão (ERR) foi de 1.109683.
predictions <- model_2006 %>% predict(testing_data_2006)
## Warning in predict.lm(., testing_data_2006): prediction from a rank-
## deficient fit may be misleading
data.frame( R2 = R2(predictions, testing_data_2006$votos),
RMSE = RMSE(predictions, testing_data_2006$votos),
MAE = MAE(predictions, testing_data_2006$votos),
ERR = RMSE(predictions, testing_data_2006$votos)/
mean(testing_data_2006$votos))
O modelo conseguiu um R² de 0,54, isso significa que esse modelo explica aproximadamente 54% da variabilidade da variável resposta. A diferença média entre os valores de resultados conhecidos observados e os valores previstos pelo modelo (RMSE) foi de aproximadamente 28056.78 isso quer dizer que o modelo erraria aproximadamente 28056, ou seja, se o candidato tivesse um milhão de votos, nós preveríamos até 28056 mais/menos do que deveríamos A diferença absoluta média entre os resultados observados e previstos (MAE) foi de aproximadamente 13190.14. A taxa de erro de previsão (ERR) foi de 1.304018.
predictions <- model_2010 %>% predict(validate_data_2010)
## Warning in predict.lm(., validate_data_2010): prediction from a rank-
## deficient fit may be misleading
data.frame( R2 = R2(predictions, validate_data_2010$votos),
RMSE = RMSE(predictions, validate_data_2010$votos),
MAE = MAE(predictions, validate_data_2010$votos),
ERR = RMSE(predictions, validate_data_2010$votos)/
mean(validate_data_2010$votos))
O modelo conseguiu um R² de 0,44, isso significa que esse modelo explica aproximadamente 56% da variabilidade da variável resposta. A diferença média entre os valores de resultados conhecidos observados e os valores previstos pelo modelo (RMSE) foi de aproximadamente 31995.79 issod quer dizer que o modelo erraria aproximadamente 31995, ou seja, se o candidato tivesse um milhão de votos, nós preveríamos até 31995 mais/menos do que deveríamos A diferença absoluta média entre os resultados observados e previstos (MAE) foi de aproximadamente 14931.24. A taxa de erro de previsão (ERR) foi de 1.399707.
predictions <- model_2010 %>% predict(testing_data_2010)
## Warning in predict.lm(., testing_data_2010): prediction from a rank-
## deficient fit may be misleading
data.frame( R2 = R2(predictions, testing_data_2010$votos),
RMSE = RMSE(predictions, testing_data_2010$votos),
MAE = MAE(predictions, testing_data_2010$votos),
ERR = RMSE(predictions, testing_data_2010$votos)/
mean(testing_data_2010$votos))
O modelo conseguiu um R² de 0,56, isso significa que esse modelo explica aproximadamente 56% da variabilidade da variável resposta. A diferença média entre os valores de resultados conhecidos observados e os valores previstos pelo modelo (RMSE) foi de aproximadamente 29604.97 issod quer dizer que o modelo erraria aproximadamente 29604, ou seja, se o candidato tivesse um milhão de votos, nós preveríamos até 29604 mais/menos do que deveríamos A diferença absoluta média entre os resultados observados e previstos (MAE) foi de aproximadamente 14371.57. A taxa de erro de previsão (ERR) foi de 1.399707.
Agora vamos construir um modelo apenas com as variáveis que foram jugadas como importantes pela análise de correlação e medição do p-valor.
mod_2006 <- lm(votos ~ total_receita * total_despesa * recursos_de_pessoas_juridicas,
data = training_data_2006)
glance(mod_2006)
Nossa estatistica de R² émoderada/baixa, explicando cerca de 50% da variação dos dados, e tendo um diferença mínima para o R² ajustado, o que é pouco satisfatória, porém mais análises podem ser feitas.
mod_2006 %>%
ggplot(aes(.fitted, .resid)) +
geom_point() +
stat_smooth(method="loess") +
geom_hline(col="red",
yintercept=0,
linetype="dashed") +
labs(y="Residuals",
x="Fitted values",
title="Residual vs Fitted Plot (2006)")
Vemos que o novo modelo acomoda melhor a distribuição dos dados em tono do eixo x, mais ainda não de forma não tão satisfatória, tendo mais pontos para um lado que para outro, e um lado mais espalhado que o outro, isso pode indicar a falta de alguma variável importante no modelo.
mod_2006 %>%
ggplot(aes(.fitted,
sqrt(abs(.stdresid)))) +
geom_point(na.rm=TRUE) +
stat_smooth(method="loess",
na.rm = TRUE) +
labs(title = "Scale-Location (2006)",
x= "Fitted Value",
y = expression(sqrt("|Standardized residuals|")))
Novamente, o modelo mostra certa homocedasticidade mas tem também os problemas coma aleatoriedade, tendo em vista que os pontos não são distribuidos igualmente, algo que pode estar não só atrelado ao erro irredutivel, mas ainda sim, mostra uma melhora significativa se comparado ao modelo com todas as variáveis.
mod_2006 %>%
ggplot(aes(.hat, .stdresid)) +
geom_point(aes(size=.cooksd), na.rm=TRUE) +
stat_smooth(method="loess", na.rm=TRUE) +
xlab("Leverage") +
ylab("Standardized Residuals") +
ggtitle("Residual vs Leverage Plot (2006)") +
scale_size_continuous("Cook's Distance", range=c(1,5)) +
theme(legend.position="bottom")
Vemos também valores bem menores para distancia de cook e para bem menos pontos distoantes, o que pode nos dizer que o modelo se encontra em conformidade considerável com a variação os dados.
predictions <- mod_2006 %>% predict(validate_data_2006)
data.frame( R2 = R2(predictions, validate_data_2006$votos),
RMSE = RMSE(predictions, validate_data_2006$votos),
MAE = MAE(predictions, validate_data_2006$votos),
ERR = RMSE(predictions, validate_data_2006$votos)/
mean(validate_data_2006$votos))
O modelo conseguiu um R² de 0,71, isso significa que esse modelo explica aproximadamente 71% da variabilidade da variável resposta. A diferença média entre os valores de resultados conhecidos observados e os valores previstos pelo modelo (RMSE) foi de aproximadamente 23389.79 issod quer dizer que o modelo erraria aproximadamente 29604, ou seja, se o candidato tivesse um milhão de votos, nós preveríamos até 29326 mais/menos do que deveríamos A diferença absoluta média entre os resultados observados e previstos (MAE) foi de aproximadamente 12379.08 A taxa de erro de previsão (ERR) foi de 0.9158357.
predictions <- mod_2006 %>% predict(testing_data_2006)
data.frame( R2 = R2(predictions, testing_data_2006$votos),
RMSE = RMSE(predictions, testing_data_2006$votos),
MAE = MAE(predictions, testing_data_2006$votos),
ERR = RMSE(predictions, testing_data_2006$votos)/
mean(testing_data_2006$votos))
O modelo conseguiu um R² de 0,48, isso significa que esse modelo explica aproximadamente 48% da variabilidade da variável resposta. A diferença média entre os valores de resultados conhecidos observados e os valores previstos pelo modelo (RMSE) foi de aproximadamente 30105.75 issod quer dizer que o modelo erraria aproximadamente 30105, ou seja, se o candidato tivesse um milhão de votos, nós preveríamos até 30105 mais/menos do que deveríamos A diferença absoluta média entre os resultados observados e previstos (MAE) foi de aproximadamente 12779.06. A taxa de erro de previsão (ERR) foi de 1.399249.
mod_2010 <- lm(votos ~ total_receita * total_despesa * recursos_de_pessoas_juridicas,
data = training_data_2010)
glance(mod_2010)
Nossa estatistica de R² baixa, explicando cerca de 46% da variação dos dados, e tendo um diferença mínima para o R² ajustado, o que é pouco satisfatória, porém por ser bem mais simples do que a com todas as variáveis alguma diminuição era esperanda, vamos fazer análises de residuos então.
mod_2010 %>%
ggplot(aes(.fitted, .resid)) +
geom_point() +
stat_smooth(method="loess") +
geom_hline(col="red",
yintercept=0,
linetype="dashed") +
labs(y="Residuals",
x="Fitted values",
title="Residual vs Fitted Plot (2010)")
Vemos que o novo modelo acomoda muito melhor a distribuição dos dados em tono do eixo x, mais ainda não de forma não tão satisfatória, tendo mais pontos para um lado que para outro, e um lado um pouco mais espalhado que o outro, mostrando que o modelo não se ajusta totalmente.
mod_2010 %>%
ggplot(aes(.fitted,
sqrt(abs(.stdresid)))) +
geom_point(na.rm=TRUE) +
stat_smooth(method="loess",
na.rm = TRUE) +
labs(title = "Scale-Location (2010)",
x= "Fitted Value",
y = expression(sqrt("|Standardized residuals|")))
O modelo mostra certa homocedasticidade mas tem também os problemas coma aleatoriedade, tendo em vista que os pontos não são distribuidos igualmente, algo que pode estar não só atrelado ao erro irredutivel, mas ainda sim, mostra uma melhora significativa se comparado ao modelo com todas as variáveis.
mod_2010 %>%
ggplot(aes(.hat, .stdresid)) +
geom_point(aes(size=.cooksd), na.rm=TRUE) +
stat_smooth(method="loess", na.rm=TRUE) +
xlab("Leverage") +
ylab("Standardized Residuals") +
ggtitle("Residual vs Leverage Plot (2006)") +
scale_size_continuous("Cook's Distance", range=c(1,5)) +
theme(legend.position="bottom")
Vemos também valores extremamente menores para distancia de cook e para bem menos pontos distoantes, o que pode nos dizer que o modelo se encontra em conformidade considerável com os a variação dos dados.
predictions <- mod_2010 %>% predict(validate_data_2010)
data.frame( R2 = R2(predictions, validate_data_2010$votos),
RMSE = RMSE(predictions, validate_data_2010$votos),
MAE = MAE(predictions, validate_data_2010$votos),
ERR = RMSE(predictions, validate_data_2010$votos)/
mean(validate_data_2010$votos))
O modelo conseguiu um R² de 0.55, isso significa que esse modelo explica aproximadamente 48% da variabilidade da variável resposta. A diferença média entre os valores de resultados conhecidos observados e os valores previstos pelo modelo (RMSE) foi de aproximadamente 28410.54 issod quer dizer que o modelo erraria aproximadamente 28410, ou seja, se o candidato tivesse um milhão de votos, nós preveríamos até 28410 mais/menos do que deveríamos A diferença absoluta média entre os resultados observados e previstos (MAE) foi de aproximadamente 11804.81. A taxa de erro de previsão (ERR) foi de 1.428713.
predictions <- mod_2010 %>% predict(testing_data_2010)
data.frame( R2 = R2(predictions, testing_data_2010$votos),
RMSE = RMSE(predictions, testing_data_2010$votos),
MAE = MAE(predictions, testing_data_2010$votos),
ERR = RMSE(predictions, testing_data_2010$votos)/
mean(testing_data_2010$votos))
O modelo conseguiu um R² de 0,57, isso significa que esse modelo explica aproximadamente 57% da variabilidade da variável resposta. A diferença média entre os valores de resultados conhecidos observados e os valores previstos pelo modelo (RMSE) foi de aproximadamente 29194.57 isso quer dizer que o modelo erraria aproximadamente 29194, ou seja, se o candidato tivesse um milhão de votos, nós preveríamos até 29194 mais/menos do que deveríamos A diferença absoluta média entre os resultados observados e previstos (MAE) foi de aproximadamente 11922.71.
A taxa de erro de previsão (ERR) foi de 1.380304.
eleicoes_data$id <- 1:nrow(eleicoes_data)
training_data = eleicoes_data %>%
sample_frac(.6)
encoding <- build_encoding(dataSet = training_data,
cols = c("uf","sexo","grau",
"partido","estado_civil"),
verbose = F)
training_data <- one_hot_encoder(dataSet = training_data,
encoding = encoding,
drop = TRUE,
verbose = F)
remaining = anti_join(eleicoes_data, training_data, by = 'id')
testing_data = remaining %>%
sample_frac(.5)
testing_data <- one_hot_encoder(dataSet = testing_data,
encoding = encoding,
drop = TRUE,
verbose = F)
validate_data = anti_join(remaining, testing_data, by = 'id')
validate_data <- one_hot_encoder(dataSet = validate_data,
encoding = encoding,
drop = TRUE,
verbose = F)
rm(remaining)
mod <- lm(votos ~ total_receita * total_despesa * recursos_de_pessoas_juridicas,
data = training_data)
glance(mod)
A estatistica de R² está um pouco baixa, explicando cerca de 48% da variação dos dados, e tendo um diferença mínima para o R² ajustado, o que é pouco satisfatória, vamos agora a análise de residuos para termos um panorama mais completos
mod %>%
ggplot(aes(.fitted, .resid)) +
geom_point() +
stat_smooth(method="loess") +
geom_hline(col="red",
yintercept=0,
linetype="dashed") +
labs(y="Residuals",
x="Fitted values",
title="Residual vs Fitted Plot")
Vemos que o novo modelo acomoda bem a distribuição dos dados em tono do eixo x,mesmo que só ocupando a parte central do gráfico a dispersão parae aleatória, o que é um bom sinal.
mod %>%
ggplot(aes(.fitted,
sqrt(abs(.stdresid)))) +
geom_point(na.rm=TRUE) +
stat_smooth(method="loess",
na.rm = TRUE) +
labs(title = "Scale-Location",
x= "Fitted Value",
y = expression(sqrt("|Standardized residuals|")))
Nesta análise ele também mostra ter um dispersão parcialmente aleatória, muito concentrada no meio pra cima do gráfico
mod %>%
ggplot(aes(.hat, .stdresid)) +
geom_point(aes(size=.cooksd), na.rm=TRUE) +
stat_smooth(method="loess", na.rm=TRUE) +
xlab("Leverage") +
ylab("Standardized Residuals") +
ggtitle("Residual vs Leverage Plot") +
scale_size_continuous("Cook's Distance", range=c(1,5)) +
theme(legend.position="bottom")
Vemos também valores um pouco altos para distancia de cookmas para poucos pontos, o que pode nos dizer que o modelo se encontra em conformidade considerável com os a variação dos dados.
predictions <- mod %>% predict(validate_data)
data.frame( R2 = R2(predictions, validate_data$votos),
RMSE = RMSE(predictions, validate_data$votos),
MAE = MAE(predictions, validate_data$votos),
ERR = RMSE(predictions, validate_data$votos)/
mean(validate_data$votos))
O modelo conseguiu um R² de 0,52, isso significa que esse modelo explica aproximadamente 52% da variabilidade da variável resposta. A diferença média entre os valores de resultados conhecidos observados e os valores previstos pelo modelo (RMSE) foi de aproximadamente 32477.57 isso quer dizer que o modelo erraria aproximadamente 32477, ou seja, se o candidato tivesse um milhão de votos, nós preveríamos até 32477 mais/menos do que deveríamos A diferença absoluta média entre os resultados observados e previstos (MAE) foi de aproximadamente 13833.14.
A taxa de erro de previsão (ERR) foi de
predictions <- mod %>% predict(testing_data)
data.frame( R2 = R2(predictions, testing_data$votos),
RMSE = RMSE(predictions, testing_data$votos),
MAE = MAE(predictions, testing_data$votos),
ERR = RMSE(predictions, testing_data$votos)/
mean(testing_data$votos))
O modelo conseguiu um R² de 0,45, isso significa que esse modelo explica aproximadamente 57% da variabilidade da variável resposta. A diferença média entre os valores de resultados conhecidos observados e os valores previstos pelo modelo (RMSE) foi de aproximadamente 37515.32 isso quer dizer que o modelo erraria aproximadamente 37515, ou seja, se o candidato tivesse um milhão de votos, nós preveríamos até 37515 mais/menos do que deveríamos A diferença absoluta média entre os resultados observados e previstos (MAE) foi de aproximadamente 13578.44.
A taxa de erro de previsão (ERR) foi de 1.686544.
Com base nesses dados posso afirmar que o modelo não é muito satisfátório, porem pode ser bastante melhorado, principalmente porque algumas das suas estatisticas de residuos mostram problemas e seu R² ainda pode ser considerado muito baixo, pois foi um pouco inferior aos encontrados nos modelos com todas as variáveis, mas muito mais simples.