Como um dos objetivos principais este relatório ira demonstrar como criar um modelo de rede neural e depois comparar o resultado com um modelo de regressão.
O banco de dados utilizado foi obtido pelo site Kaggle,< https://www.kaggle.com/c/house-prices-advanced-regression-techniques>.
suppressMessages(suppressWarnings(library(keras)))
suppressMessages(suppressWarnings(library(tidyverse)))
suppressMessages(suppressWarnings(library(MASS)))
suppressMessages(suppressWarnings(library(gridExtra)))
train <- read_csv("/opt/datasets/houseprices/train.csv", na = "")
Antes de inciar a crição dos modelos, vamos começar com um breve analise descritiva.
Começando com a análise da variável resposta SalePrice.
train %>%
select_at(.vars = vars(ends_with("Price"))) %>%
select_if(is.numeric) %>%
gather(var,value) %>%
ggplot(aes(x = value)) +
geom_histogram(bins = 25,
fill = "ivory3",
colour = "pink") +
theme_light() +
facet_wrap(~var, scales = "free")
Tem-se que a variável resposta é bastante assimétrica à direita.Vamos tentar corrigir aplicando a transformação log.
train %>%
select_at(.vars = vars(ends_with("Price"))) %>%
select_if(is.numeric) %>%
gather(var,value) %>%
ggplot(aes(x = log(value))) +
geom_histogram(bins = 25,
fill = "ivory3",
colour = "pink") +
theme_light() +
facet_wrap(~var, scales = "free")
Após a transformação a variável resposta apresentou uma grande melhora. Como temos uma grande quantidade de variaveis, para a exibição dos graficos sera pre selecionado uma palavra e todas as que se referem a ela, serão analizadas.
Análise das variáveis relacionadas a vendas.
train %>%
select_at(.vars = vars(ends_with("Sold"))) %>%
select_if(is.numeric) %>%
gather(var,value) %>%
ggplot(aes(x = value)) +
geom_histogram(bins = 10,
fill = "ivory3",
colour = "pink") +
theme_light() +
facet_wrap(~var, scales = "free")
A variável MoSoldapresenta um comportamento proximo ao normal e a variável YrSoldpossuis informações por anos.
Análise das variáveis relacionadas a área.
train %>%
select_at(.vars = vars(ends_with("Area"))) %>%
select_if(is.numeric) %>%
gather(var,value) %>%
ggplot(aes(x = value)) +
geom_histogram(bins = 25,
fill = "ivory3",
colour = "pink") +
theme_light() +
facet_wrap(~var, scales = "free")
As variáveis relacionadas com a área aparentam possuir fortes assimetrias.
Para seleção das variáveis de nossa base de dados, sera selecionado apenas as variáveis quantitativas e aplicado a transformação log.
set.seed(100)
train_num <- train %>%
select_if(is.numeric) %>%
mutate_at(vars(ends_with("Area")), function(x){log(x+1)}) %>%
mutate_at(vars(ends_with("Sold")), function(x){log(x+1)}) %>%
mutate_at(vars(ends_with("Price")), function(x){log(x+1)}) %>%
mutate_at(-1, scale) %>%
mutate(Flag = sample(c("Test", "Train"),
n(),
replace = TRUE,
prob = c(.2,.8)))
Separando a base de dados.
train_all <- train_num %>%
filter(Flag=="Train") %>%
dplyr::select(-Id, -Flag, -TotalBsmtSF) %>%
as.data.frame()
test<- train_num %>%
filter(Flag=="Test") %>%
dplyr::select(-Id, -Flag, - TotalBsmtSF) %>%
as.data.frame()
modelo <- lm(SalePrice ~. , data=train_all )
summary(modelo)
##
## Call:
## lm(formula = SalePrice ~ ., data = train_all)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.4432 -0.1706 0.0126 0.1892 1.6053
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.003646 0.010625 -0.343 0.731581
## MSSubClass -0.029016 0.014822 -1.958 0.050524 .
## LotArea 0.106289 0.014681 7.240 8.32e-13 ***
## OverallQual 0.275891 0.018999 14.521 < 2e-16 ***
## OverallCond 0.145724 0.013157 11.076 < 2e-16 ***
## YearBuilt 0.214969 0.021308 10.089 < 2e-16 ***
## YearRemodAdd 0.050505 0.016090 3.139 0.001740 **
## BsmtFinSF1 0.122274 0.024808 4.929 9.52e-07 ***
## BsmtFinSF2 0.035048 0.012713 2.757 0.005930 **
## BsmtUnfSF 0.069603 0.021815 3.191 0.001459 **
## `1stFlrSF` -0.154595 0.041676 -3.709 0.000218 ***
## `2ndFlrSF` -0.161762 0.041230 -3.923 9.26e-05 ***
## LowQualFinSF -0.010467 0.011313 -0.925 0.355033
## GrLivArea 0.484446 0.049801 9.728 < 2e-16 ***
## BsmtFullBath 0.069334 0.015926 4.353 1.46e-05 ***
## BsmtHalfBath -0.004703 0.011631 -0.404 0.686063
## FullBath 0.040461 0.018298 2.211 0.027223 *
## HalfBath 0.001871 0.015525 0.121 0.904082
## BedroomAbvGr -0.034111 0.016441 -2.075 0.038238 *
## KitchenAbvGr -0.043520 0.013809 -3.152 0.001667 **
## TotRmsAbvGrd 0.047195 0.023969 1.969 0.049199 *
## Fireplaces 0.051945 0.013472 3.856 0.000122 ***
## GarageCars 0.135730 0.020626 6.581 7.18e-11 ***
## GarageArea -0.008589 0.016893 -0.508 0.611260
## WoodDeckSF 0.032710 0.011660 2.805 0.005113 **
## OpenPorchSF -0.011998 0.011494 -1.044 0.296784
## EnclosedPorch 0.012983 0.011987 1.083 0.278998
## `3SsnPorch` 0.014473 0.011297 1.281 0.200425
## ScreenPorch 0.045322 0.010714 4.230 2.52e-05 ***
## PoolArea -0.025883 0.011308 -2.289 0.022267 *
## MiscVal -0.003328 0.010805 -0.308 0.758132
## MoSold 0.013870 0.010943 1.268 0.205229
## YrSold -0.016876 0.010734 -1.572 0.116204
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.3598 on 1121 degrees of freedom
## Multiple R-squared: 0.873, Adjusted R-squared: 0.8693
## F-statistic: 240.7 on 32 and 1121 DF, p-value: < 2.2e-16
Como muitas variáveis não foram significativas para o modelo, sera utilizado o critério de seleção AIC.
modelo2 <- stepAIC(modelo)
summary(modelo2)
##
## Call:
## lm(formula = SalePrice ~ MSSubClass + LotArea + OverallQual +
## OverallCond + YearBuilt + YearRemodAdd + BsmtFinSF1 + BsmtFinSF2 +
## BsmtUnfSF + `1stFlrSF` + `2ndFlrSF` + GrLivArea + BsmtFullBath +
## FullBath + BedroomAbvGr + KitchenAbvGr + TotRmsAbvGrd + Fireplaces +
## GarageCars + WoodDeckSF + ScreenPorch + PoolArea + YrSold,
## data = train_all)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.4951 -0.1647 0.0119 0.1944 1.6128
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.003607 0.010612 -0.340 0.734004
## MSSubClass -0.031651 0.014673 -2.157 0.031207 *
## LotArea 0.104403 0.014549 7.176 1.30e-12 ***
## OverallQual 0.278228 0.018802 14.798 < 2e-16 ***
## OverallCond 0.143943 0.012848 11.204 < 2e-16 ***
## YearBuilt 0.209942 0.018769 11.185 < 2e-16 ***
## YearRemodAdd 0.050607 0.015848 3.193 0.001445 **
## BsmtFinSF1 0.117732 0.024447 4.816 1.66e-06 ***
## BsmtFinSF2 0.032954 0.012560 2.624 0.008816 **
## BsmtUnfSF 0.066961 0.021699 3.086 0.002079 **
## `1stFlrSF` -0.147996 0.039245 -3.771 0.000171 ***
## `2ndFlrSF` -0.154866 0.038073 -4.068 5.08e-05 ***
## GrLivArea 0.479278 0.046080 10.401 < 2e-16 ***
## BsmtFullBath 0.071603 0.015158 4.724 2.61e-06 ***
## FullBath 0.041406 0.016649 2.487 0.013026 *
## BedroomAbvGr -0.032488 0.016278 -1.996 0.046196 *
## KitchenAbvGr -0.040554 0.013536 -2.996 0.002796 **
## TotRmsAbvGrd 0.039502 0.023510 1.680 0.093190 .
## Fireplaces 0.053132 0.013384 3.970 7.65e-05 ***
## GarageCars 0.131896 0.015024 8.779 < 2e-16 ***
## WoodDeckSF 0.032166 0.011528 2.790 0.005354 **
## ScreenPorch 0.042811 0.010539 4.062 5.20e-05 ***
## PoolArea -0.027236 0.011055 -2.464 0.013899 *
## YrSold -0.017651 0.010580 -1.668 0.095531 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.3595 on 1130 degrees of freedom
## Multiple R-squared: 0.8722, Adjusted R-squared: 0.8696
## F-statistic: 335.2 on 23 and 1130 DF, p-value: < 2.2e-16
Após a seleção final, iremos realizar a análise de residuos,
Através dos gráficos da análise de residuo, pode-se notar que o modelo esta bem ajustado. Para confirmar, utiliza-se o gráfico de envelope.
Com o gráfico de envelope, pode-se verificar que o modelo não apresentou um otimo ajuste.
Análisando o erro quadratico médio, tem-se:
EQM<-lms$sigma
EQM
## [1] 0.3594616
#Variáveis preditoras na base de treino
x_train <- train_num %>%
filter(Flag == "Train") %>%
dplyr::select(-Id, -Flag, -SalePrice) %>%
as.matrix()
#Variável resposta na base de treino
y_train <- train_num %>%
filter(Flag == "Train") %>%
dplyr::select(SalePrice) %>%
as.matrix()
#Variáveis preditoras na base de teste
x_test <- train_num %>%
filter(Flag == "Test") %>%
dplyr::select(-Id, -Flag, -SalePrice) %>%
as.matrix()
#Variável resposta na base de teste
y_test<- train_num %>%
filter(Flag == "Test") %>%
dplyr::select(SalePrice) %>%
as.matrix()
Para construção da rede neural, será utilizada 3 camadas, sendo a primeira com 32 neurônios, a segunda com 16 e a última camada com apenas 1 neurônio, que representa a previsão do preço.
model <- keras_model_sequential() %>%
layer_dense(units = 32, activation = "relu",
input_shape = ncol(train_num) - 3, kernel_initializer='normal') %>%
layer_dense(units =16, activation = "relu", kernel_initializer='normal') %>%
layer_dense(units = 1)
model %>% compile(
optimizer = optimizer_adam(),
loss = 'mse',
metrics = list("mean_absolute_error")
)
Na criação do modelo tem que utilizar um critério de parada, e para este problema o escolhido foi o número de iterações igual a 50.
history <- model %>% fit(
x_train, y_train,
epochs = 50,
validation_split = 0.2,
verbose = 1,
shuffle = TRUE,
callbacks = list(
callback_early_stopping(monitor = "val_mean_absolute_error", min_delta = 0.01,
patience = 25,
verbose = 0,
mode = "auto",
restore_best_weights = TRUE)
))
plot(history)
O valor do erro quadratico médio foi:
evaluate(model, x_test, y_test)
## $loss
## [1] 0.08720855
##
## $mean_absolute_error
## [1] 0.2139383