library(caret)
library(tidyverse)
library(neuralnet)Base de Seguros
um exemplo de RNA para regressão
O Problema
Considere a base de dados insurance.csv, composta pelas variáveis: age, sex, bmi, children, smoker, region, married, charges.
Vamos ajustar diferentes modelos de regressão para prever o custo (charge) de um cliente a partir das suas características como idade, gênero, índice de massa corporal, número de filhos, hábito de fumar, região de residência e se é casado ou não.
Pacotes necessários
O primeiro passo será carregar os pacotes necessários.
Leitura da base de dados
Em seguida faremos a leitura da base de dados. Nesse momento é preciso verificar o tipo das variáveis e todas as variáveis categóricas precisam ser transformadas em factor.
base = read_csv("insurance.csv")
glimpse(base)Rows: 1,338
Columns: 9
$ age <dbl> 19, 18, 28, 33, 32, 31, 46, 37, 37, 60, 25, 62, 23, 56, 27, 1…
$ sex <chr> "female", "male", "male", "male", "male", "female", "female",…
$ bmi <dbl> 27.900, 33.770, 33.000, 22.705, 28.880, 25.740, 33.440, 27.74…
$ children <dbl> 0, 1, 3, 0, 0, 0, 1, 3, 2, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0…
$ smoker <chr> "yes", "no", "no", "no", "no", "no", "no", "no", "no", "no", …
$ region <chr> "southwest", "southeast", "southeast", "northwest", "northwes…
$ charges <dbl> 16884.924, 1725.552, 4449.462, 21984.471, 3866.855, 3756.622,…
$ married <chr> "yes", NA, "yes", "no", "yes", "yes", "yes", "yes", "yes", NA…
$ country <chr> "usa", "usa", "usa", "usa", "usa", "usa", "usa", "usa", "usa"…
base$sex = factor(base$sex)
base$smoker = factor(base$smoker)
base$region = factor(base$region)
base$married = factor(base$married)
base$country = factor(base$country)
glimpse(base)Rows: 1,338
Columns: 9
$ age <dbl> 19, 18, 28, 33, 32, 31, 46, 37, 37, 60, 25, 62, 23, 56, 27, 1…
$ sex <fct> female, male, male, male, male, female, female, female, male,…
$ bmi <dbl> 27.900, 33.770, 33.000, 22.705, 28.880, 25.740, 33.440, 27.74…
$ children <dbl> 0, 1, 3, 0, 0, 0, 1, 3, 2, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0…
$ smoker <fct> yes, no, no, no, no, no, no, no, no, no, no, yes, no, no, yes…
$ region <fct> southwest, southeast, southeast, northwest, northwest, southe…
$ charges <dbl> 16884.924, 1725.552, 4449.462, 21984.471, 3866.855, 3756.622,…
$ married <fct> yes, NA, yes, no, yes, yes, yes, yes, yes, NA, NA, yes, NA, N…
$ country <fct> usa, usa, usa, usa, usa, usa, usa, usa, usa, usa, usa, usa, u…
Divisão da base em treino e teste
Em seguida dividimos a base em treino e teste de forma que 70% ficará no treino e 30% no teste. Para garantir a reprodutibilidade do código devemos fixar a semente antes de realizar a partição.
set.seed(123456789)
N = dim(base)[1]
indices_treino = createDataPartition(1:N,p=0.7)[[1]]
base_treino = base[indices_treino,]
base_teste = base[-indices_treino,]Tratamento das NAs
A partir de agora vamos usar somente a base de treino. A base de teste só volta ao uso quando quisermos medir a qualidade das previsões fora da amostra.
Sobre o tratamento das NAs, temos a alternativa de eliminar as linhas, de imputar valores ou eliminar colunas. Neste exemplo, vamos simplesmente eliminar as linhas que contém algum NA de forma a simplificar esta etapa, mas nem sempre está é a alternativa mais interessante.
sum(is.na(base_treino)) #num total de NAs na base[1] 384
base_treino = na.omit(base_treino)Padronização das variáveis independentes numéricas
As variáveis independentes (aquelas que não são a variável resposta) numéricas devem ser padronizadas e podem ser padronizadas pela forma \[ \tilde{X} = \dfrac{X - \bar{X}}{sd(X)} \] E esta padronização pode ser realizada com a função scale.
age_ = scale(base_treino$age)
attr(age_,"scaled:center")[1] 40.09009
attr(age_,"scaled:scale")[1] 14.32938
bmi_ = scale(base_treino$bmi)
children_ = scale(base_treino$children)Padronização das variáveis dependente numérica
A padronização da variável dependente tem que ser feita de forma que so valores padronizados estejam contidos na imagem da função de ativação escolhida para o problema.
No caso de usarmos a função de ativação logistica, vamos padronizar a variável resposta de forma que seus valores fiquem dentro do intervalo \([0,1]\). A operação realizada será: \[ \tilde{Y} = \dfrac{Y - \min\{Y\}}{\max\{Y\}- \min\{Y\}} \]
charges_log = (base_treino$charges - min(base_treino$charges))/(
max(base_treino$charges) - min(base_treino$charges)
)Já para o caso de usarmos a função de ativação tangente hiperbólica, vamos padronizar a variável resposta de forma que seus valores fiquem dentro do intervalo \([-1,1]\). A operação realizada será: \[ \tilde{Y} = 2 \dfrac{Y - \min\{Y\}}{\max\{Y\}- \min\{Y\}} - 1 \]
charges_tan = 2*((base_treino$charges - min(base_treino$charges))/(
max(base_treino$charges) - min(base_treino$charges)
)) - 1Tratamento nas variáveis categóricas
As variáveis categóricas precisam ser transformadas em indicadoras antes do ajuste de uma rede neural pela função neuralnet. Para isso vamos primeiro criar uma base de dados com as variáveis numéricas padronizadas e as variáveis categóricas como factor. Depois usamos a função modelmatrix e por último eliminamos a coluna intersept.
Vamos fazer duas bases, uma que será usada no ajuste do modelo com função de ativação logística e outro com função de ativação tangente hiperbólica. Primeiro a base para a logística, onde a variável charge foi padronizada de forma que seus valores estão dentro de \([0,1]\).
base_treino_log = tibble(
age = as.numeric(age_),
bmi = as.numeric(bmi_),
children = as.numeric(children_),
charges = as.numeric(charges_log),
sex = base_treino$sex,
smoker = base_treino$smoker,
region = base_treino$region,
married = base_treino$married
)
glimpse(base_treino_log)Rows: 555
Columns: 8
$ age <dbl> -1.471807263, -0.843727188, -0.564580488, -0.634367163, -0.21…
$ bmi <dbl> -0.4625470253, 0.3568875837, -0.3050870416, -0.8096016832, -0…
$ children <dbl> -0.9223682, 1.4999394, -0.9223682, -0.9223682, 1.4999394, 0.6…
$ charges <dbl> 2.514957e-01, 5.296955e-02, 4.366851e-02, 4.190869e-02, 9.818…
$ sex <fct> female, male, male, female, female, male, female, female, mal…
$ smoker <fct> yes, no, no, no, no, no, yes, no, yes, no, no, yes, no, no, y…
$ region <fct> southwest, southeast, northwest, southeast, northwest, northe…
$ married <fct> yes, yes, yes, yes, yes, yes, yes, no, yes, yes, no, yes, yes…
base_treino_final_log =
model.matrix( ~ age + sex + bmi +
children + smoker +
region + charges + married,
data = base_treino_log)
base_treino_final_log = base_treino_final_log[,-1]
head(base_treino_final_log) age sexmale bmi children smokeryes regionnorthwest
1 -1.4718073 0 -0.4625470 -0.9223682 1 0
2 -0.8437272 1 0.3568876 1.4999394 0 0
3 -0.5645805 1 -0.3050870 -0.9223682 0 1
4 -0.6343672 0 -0.8096017 -0.9223682 0 0
5 -0.2156471 0 -0.4882548 1.4999394 0 1
6 -0.2156471 1 -0.1524473 0.6925035 0 0
regionsoutheast regionsouthwest charges marriedyes
1 0 1 0.25149567 1
2 1 0 0.05296955 1
3 0 0 0.04366851 1
4 1 0 0.04190869 1
5 0 0 0.09818175 1
6 0 0 0.08421129 1
Agora a base para a tangente hiporbólica, onde a variável charge foi padronizada de forma que seus valores estão dentro de \([-1,1]\).
base_treino_tan = tibble(
age = as.numeric(age_),
bmi = as.numeric(bmi_),
children = as.numeric(children_),
charges = as.numeric(charges_tan),
sex = base_treino$sex,
smoker = base_treino$smoker,
region = base_treino$region,
married = base_treino$married
)
glimpse(base_treino_tan)Rows: 555
Columns: 8
$ age <dbl> -1.471807263, -0.843727188, -0.564580488, -0.634367163, -0.21…
$ bmi <dbl> -0.4625470253, 0.3568875837, -0.3050870416, -0.8096016832, -0…
$ children <dbl> -0.9223682, 1.4999394, -0.9223682, -0.9223682, 1.4999394, 0.6…
$ charges <dbl> -0.49700866, -0.89406090, -0.91266297, -0.91618262, -0.803636…
$ sex <fct> female, male, male, female, female, male, female, female, mal…
$ smoker <fct> yes, no, no, no, no, no, yes, no, yes, no, no, yes, no, no, y…
$ region <fct> southwest, southeast, northwest, southeast, northwest, northe…
$ married <fct> yes, yes, yes, yes, yes, yes, yes, no, yes, yes, no, yes, yes…
base_treino_final_tan =
model.matrix( ~ age + sex + bmi +
children + smoker +
region + charges + married,
data = base_treino_tan)
base_treino_final_tan = base_treino_final_tan[,-1]
head(base_treino_final_tan) age sexmale bmi children smokeryes regionnorthwest
1 -1.4718073 0 -0.4625470 -0.9223682 1 0
2 -0.8437272 1 0.3568876 1.4999394 0 0
3 -0.5645805 1 -0.3050870 -0.9223682 0 1
4 -0.6343672 0 -0.8096017 -0.9223682 0 0
5 -0.2156471 0 -0.4882548 1.4999394 0 1
6 -0.2156471 1 -0.1524473 0.6925035 0 0
regionsoutheast regionsouthwest charges marriedyes
1 0 1 -0.4970087 1
2 1 0 -0.8940609 1
3 0 0 -0.9126630 1
4 1 0 -0.9161826 1
5 0 0 -0.8036365 1
6 0 0 -0.8315774 1
Ajuste do Modelo de Rede Neural com um único neurônio
A função usada para isso será a neuralnet do pacote neuralnet.
Modelo Completo função de ativação logística
modelo_completo_log = neuralnet(
formula = charges ~ age + sexmale + bmi + children + smokeryes + regionnorthwest + regionsoutheast + regionsouthwest + marriedyes,
data = base_treino_final_log,
hidden = 0,
linear.output = FALSE)Podemos visualizar o modelo criado com a função plot:
plot(modelo_completo_log)Podemos acessar os valores estimados pelos pesos sinápticos da seguinte forma:
modelo_completo_log$weights[[1]][[1]][,1] [1] -1.99083022 0.36206068 -0.02352808 0.33361323 0.05788218 2.08576409
[7] 0.00951367 -0.04113100 -0.05965614 -0.02054949
Podemos acessar os valores estimados para os dados de treinamento da seguinte forma:
head(modelo_completo_log$net.result[[1]]) [,1]
1 0.32610481
2 0.10195972
3 0.08432553
4 0.06877423
5 0.10377077
6 0.10680884
Faça na mão a estimativa para a primeira observação da base e verifique se está correta:
(pesos = modelo_completo_log$weights[[1]][[1]][,1]) [1] -1.99083022 0.36206068 -0.02352808 0.33361323 0.05788218 2.08576409
[7] 0.00951367 -0.04113100 -0.05965614 -0.02054949
(x = as.numeric(modelo_completo_log$data[1,c("age","sexmale","bmi","children","smokeryes","regionnorthwest","regionsoutheast","regionsouthwest","marriedyes")]))[1] -1.4718073 0.0000000 -0.4625470 -0.9223682 1.0000000 0.0000000 0.0000000
[8] 1.0000000 1.0000000
(x = c(1,x)) [1] 1.0000000 -1.4718073 0.0000000 -0.4625470 -0.9223682 1.0000000
[7] 0.0000000 0.0000000 1.0000000 1.0000000
soma = sum(x*pesos)
1/(1+exp(-soma))[1] 0.3261048
modelo_completo_log$net.result[[1]][1][1] 0.3261048
Modelo Completo função de ativação tengente hiperbólica
modelo_completo_tan = neuralnet(
formula = charges ~ age + sexmale + bmi + children + smokeryes + regionnorthwest + regionsoutheast + regionsouthwest + marriedyes,
data = base_treino_final_tan,
hidden = 0,
linear.output = FALSE,
act.fct = "tanh")Podemos visualizar o modelo criado com a função plot:
plot(modelo_completo_tan)Podemos acessar os valores estimados pelos pesos sinápticos da seguinte forma:
modelo_completo_tan$weights[[1]][[1]][,1] [1] -1.002586152 0.181463022 -0.010513825 0.166835300 0.028957945
[6] 1.045127119 0.009503453 -0.016271079 -0.025206976 -0.007440047
Podemos acessar os valores estimados para os dados de treinamento da seguinte forma:
head(modelo_completo_tan$net.result[[1]]) [,1]
1 -0.3461506
2 -0.7957585
3 -0.8309185
4 -0.8625425
5 -0.7923363
6 -0.7875898
Faça na mão a estimativa para a primeira observação da base e verifique se está correta:
(pesos = modelo_completo_tan$weights[[1]][[1]][,1]) [1] -1.002586152 0.181463022 -0.010513825 0.166835300 0.028957945
[6] 1.045127119 0.009503453 -0.016271079 -0.025206976 -0.007440047
(x = as.numeric(modelo_completo_tan$data[1,c("age","sexmale","bmi","children","smokeryes","regionnorthwest","regionsoutheast","regionsouthwest","marriedyes")]))[1] -1.4718073 0.0000000 -0.4625470 -0.9223682 1.0000000 0.0000000 0.0000000
[8] 1.0000000 1.0000000
(x = c(1,x)) [1] 1.0000000 -1.4718073 0.0000000 -0.4625470 -0.9223682 1.0000000
[7] 0.0000000 0.0000000 1.0000000 1.0000000
soma = sum(x*pesos)
(exp(2*soma)-1)/(exp(2*soma)+1)[1] -0.3461506
modelo_completo_tan$net.result[[1]][1][1] -0.3461506
Modelo sem Região com função de ativação logística
modelo_sem_regiao_log = neuralnet(
formula = charges ~ age + sexmale + bmi + children + smokeryes + marriedyes,
data = base_treino_final_log,
hidden = 0,
linear.output = FALSE)Podemos visualizar o modelo criado com a função plot:
plot(modelo_sem_regiao_log)Podemos acessar os valores estimados pelos pesos sinápticos da seguinte forma:
modelo_sem_regiao_log$weights[[1]][[1]][,1][1] -2.01778552 0.36350674 -0.02936911 0.32816140 0.05786849 2.08962353
[7] -0.01458207
Podemos acessar os valores estimados para os dados de treinamento da seguinte forma:
head(modelo_sem_regiao_log$net.result[[1]]) [,1]
1 0.33560945
2 0.10298204
3 0.08162582
4 0.07030456
5 0.10117980
6 0.10432384
Faça na mão a estimativa para a primeira observação da base e verifique se está correta:
(pesos = modelo_sem_regiao_log$weights[[1]][[1]][,1])[1] -2.01778552 0.36350674 -0.02936911 0.32816140 0.05786849 2.08962353
[7] -0.01458207
(x = as.numeric(modelo_sem_regiao_log$data[1,c("age","sexmale","bmi","children","smokeryes","marriedyes")]))[1] -1.4718073 0.0000000 -0.4625470 -0.9223682 1.0000000 1.0000000
(x = c(1,x))[1] 1.0000000 -1.4718073 0.0000000 -0.4625470 -0.9223682 1.0000000 1.0000000
soma = sum(x*pesos)
(1)/(1+exp(-soma))[1] 0.3356094
modelo_sem_regiao_log$net.result[[1]][1][1] 0.3356094
Medidas de Qualidade na base de treino - problemas de Regressão
Vamos comparar o desempenho dos três modelos de RNA ajustados para prever o custo do cliente. Para isso, primeiro, vamos guardar em um objeto do R os valores previstos.
y_completo_log_ = modelo_completo_log$net.result[[1]]
y_completo_tan_ = modelo_completo_tan$net.result[[1]]
y_sem_regiao_log_ = modelo_sem_regiao_log$net.result[[1]]Repare que o valor previsto pelo modelo é para a variável resposta transformada. Mas para calcular os erros de previsão precisamos da previsão para a variável na unidade original e para isso precisaremos “desfazer” a transformação.
Para desfazer a transformação feita para a função de ativação logística:
\[ Y = \tilde{Y} \times (\max\{Y\}- \min\{Y\}) + \min\{Y\} \]
por isso precisamos ter guadrado os valores usados para transformação.
min = min(base_treino$charges)
max = max(base_treino$charges)y_completo_log = y_completo_log_ * (max - min) + min
y_sem_regiao_log = y_sem_regiao_log_ * (max - min) + minPara desfazer a transformação feita para a função de ativação tangente hiperbólica:
\[ Y = \dfrac{\tilde{Y} + 1}{2} \times (\max\{Y\}- \min\{Y\}) + \min\{Y\} \]
y_completo_tan = ((y_completo_tan_ + 1)/2) * (max - min) + minPara facilitar as contas que seguem, vamos primeiro definir o erro cometido em cada modelo para cada indivíduo.
erro_completo_log = y_completo_log - base_treino$charges
erro_completo_tan = y_completo_tan - base_treino$charges
erro_sem_regiao_log = y_sem_regiao_log - base_treino$chargesSoma dos Erros Quadráticos
A Soma dos Erros Quadráticos (SSE - Sum of Squared Errors) é definida por
\[ SSE = \sum_{i=1}^N (y_i - \hat{y}_i)^2 \]
No R podemos calculá-la assim:
(sse_completo_log = sum((erro_completo_log)^2))[1] 19606415513
(sse_completo_tan = sum((erro_completo_tan)^2))[1] 19605612636
(sse_sem_regiao_log = sum((erro_sem_regiao_log)^2))[1] 19634551106
barplot(c(completo_log = sse_completo_log,
completo_tan = sse_completo_tan,
sem_regiao_log = sse_sem_regiao_log))Erro Quadrático Médio
O Erro Quadrático Médio (Mean Squared Error - MSE) é definido por
\[ MSE = \dfrac{1}{N} \sum_{i=1}^N (y_i - \hat{y}_i)^2 \]
No R podemos calculá-la assim:
n = nrow(base_treino)
(mse_completo_log = sse_completo_log/n)[1] 35326875
(mse_completo_tan = sse_completo_tan/n)[1] 35325428
(mse_sem_regiao_log = sse_sem_regiao_log/n)[1] 35377570
barplot(c(completo_log = mse_completo_log,
completo_tan = mse_completo_tan,
sem_regiao_log = mse_sem_regiao_log))Coeficiente de Determinação \(R^2\)
O Coeficiente de Determinação \(R^2\) é definido por:
\[ R^2 = 1 - \dfrac{SSE}{SST} = 1 - \dfrac{\sum_{i=1}^N (y_i - \hat{y}_i)^2 }{\sum_{i=1}^N (y_i - \bar{y})^2 } \quad \text{ sendo, }\quad SST = \sum_{i=1}^N (y_i - \bar{y})^2 \]
sst = sum((base_treino$charges - mean(base_treino$charges))^2)
(R2_completo_log = 1 - sse_completo_log/sst)[1] 0.7703043
(R2_completo_tan = 1 - sse_completo_tan/sst)[1] 0.7703137
(R2_sem_regiao_log = 1 - sse_sem_regiao_log/sst)[1] 0.7699746
barplot(c(completo_log = R2_completo_log,
completo_tan = R2_completo_tan,
sem_regiao_log = R2_sem_regiao_log))Medidas de Qualidade na base de teste - problemas de Regressão
glimpse(base_teste)Rows: 400
Columns: 9
$ age <dbl> 33, 46, 23, 23, 56, 30, 37, 59, 63, 31, 22, 18, 19, 63, 28, 6…
$ sex <fct> male, female, male, male, male, female, male, female, female,…
$ bmi <dbl> 22.705, 33.440, 34.400, 23.845, 40.300, 32.400, 28.025, 27.72…
$ children <dbl> 0, 1, 0, 0, 0, 1, 2, 3, 0, 2, 0, 0, 5, 0, 1, 3, 1, 0, 1, 3, 2…
$ smoker <fct> no, no, no, no, no, no, no, no, no, yes, yes, no, no, no, yes…
$ region <fct> northwest, southeast, southwest, northeast, southwest, southw…
$ charges <dbl> 21984.471, 8240.590, 1826.843, 2395.172, 10602.385, NA, 6203.…
$ married <fct> no, yes, NA, yes, yes, NA, NA, NA, yes, yes, yes, no, NA, yes…
$ country <fct> usa, usa, usa, usa, usa, usa, usa, usa, usa, usa, usa, usa, u…
Transformações na Base de Teste
Para calcular as medidas de qualidades do ajuste na base de teste, primeiro é preciso realizar na base de teste as mesmas transformações feitas na base de treino, que para esse exemplo foram: retiradas das linhas com NAs e transforações nas variáveis.
base_teste = na.omit(base_teste)
m_age = attr(age_,"scaled:center")
s_age = attr(age_,"scaled:scale")
age_teste = (base_teste$age - m_age)/s_age
m_bmi = attr(bmi_,"scaled:center")
s_bmi = attr(bmi_,"scaled:scale")
bmi_teste = (base_teste$bmi - m_bmi)/s_bmi
m_children = attr(children_,"scaled:center")
s_children = attr(children_,"scaled:scale")
children_teste = (base_teste$children - m_children)/s_childrenAgora vamos criar a base de teste transformada (sem a variável resposta - charge) e realizar o tratamento nas variáveis categóricas.
base_teste_ = tibble(
age = age_teste,
bmi = bmi_teste,
children = children_teste,
sex = base_teste$sex,
smoker = base_teste$smoker,
region = base_teste$region,
married = base_teste$married
)
base_teste_final = model.matrix( ~ age + sex + bmi + children + smoker + region + married,
data = base_teste_)
base_teste_final = base_teste_final[,-1]É importante que as variáveis categóricas criadas pela função model.matrix sejam as mesmas que foram criadas para a base de treino. Vamos verificar.
colnames(base_treino_final_tan) [1] "age" "sexmale" "bmi" "children"
[5] "smokeryes" "regionnorthwest" "regionsoutheast" "regionsouthwest"
[9] "charges" "marriedyes"
colnames(base_treino_final_log) [1] "age" "sexmale" "bmi" "children"
[5] "smokeryes" "regionnorthwest" "regionsoutheast" "regionsouthwest"
[9] "charges" "marriedyes"
colnames(base_teste_final)[1] "age" "sexmale" "bmi" "children"
[5] "smokeryes" "regionnorthwest" "regionsoutheast" "regionsouthwest"
[9] "marriedyes"
Previsão do modelo
Agora a base de teste está pronta para realizarmos as previsões, que virão na unidade transformada.
pred_completo_log_ = predict(modelo_completo_log,newdata = base_teste_final)
pred_completo_tan_ = predict(modelo_completo_tan,newdata = base_teste_final)
pred_sem_regiao_log_ = predict(modelo_sem_regiao_log,newdata = base_teste_final)E podemos retornar a previsão da variável resposta para a unidade original.
pred_completo_log = pred_completo_log_ * (max - min) + min
pred_completo_tan = ((pred_completo_tan_ + 1)/2)* (max - min) + min
pred_sem_regiao_log = pred_sem_regiao_log_ * (max - min) + minMedidas de Qualidade
O processo será o mesmo realizado na base de treino.
Primeiro vamos definir o erro cometido em cada modelo para cada indivíduo.
erro_completo_log_teste = pred_completo_log - base_teste$charges
erro_completo_tan_teste = pred_completo_tan - base_teste$charges
erro_sem_regiao_log_teste = pred_sem_regiao_log - base_teste$charges(sse_completo_log_teste = sum((erro_completo_log_teste)^2))[1] 5352061647
(sse_completo_tan_teste = sum((erro_completo_tan_teste)^2))[1] 5347251528
(sse_sem_regiao_log_teste = sum((erro_sem_regiao_log_teste)^2))[1] 5331857323
barplot(c(completo_log = sse_completo_log_teste,
completo_tan = sse_completo_tan_teste,
sem_regiao_log = sse_sem_regiao_log_teste))n = nrow(base_teste)
(mse_completo_log_teste = sse_completo_log_teste/n)[1] 20906491
(mse_completo_tan_teste = sse_completo_tan_teste/n)[1] 20887701
(mse_sem_regiao_log_teste = sse_sem_regiao_log_teste/n)[1] 20827568
barplot(c(completo_log = mse_completo_log_teste,
completo_tan = mse_completo_tan_teste,
sem_regiao_log = mse_sem_regiao_log_teste))Atenção no código a seguir, a média usada no cálculo do SST será sempre a da base de treino.
sst_teste = sum((base_teste$charges - mean(base_treino$charges))^2)
(R2_completo_log_teste = 1 - sse_completo_log_teste/sst)[1] 0.9372988
(R2_completo_tan_teste = 1 - sse_completo_tan_teste/sst)[1] 0.9373552
(R2_sem_regiao_log_teste = 1 - sse_sem_regiao_log_teste/sst)[1] 0.9375355
barplot(c(completo_log = R2_completo_log_teste,
completo_tan = R2_completo_tan_teste,
sem_regiao_log = R2_sem_regiao_log_teste))