• Roger Sampaio

Desvendando as Métricas dos Modelos Preditivos do Azure 2-2


Fala meus guerreiros. Como estão vocês? Espero que bem, caso contrário procurem ficar, afinal somente coisas incríveis acontecem com pessoas do bem. Continuando nossa jornada sobre avaliação de modelos preditivos no Azure, no último artigo exploramos em detalhes sobre métricas de classificação , hoje abordaremos sobre as métricas de regressão linear: R², R² ajustado, Erro Quadrado Médio (MSE), valor p, Raiz do Erro Quadrado Médio (RMSE) utilizando um framework chamado statsmodels e sklearn. Apertem os cintos porque vamos decolar.


  1. Algumas Considerações sobre a Regressão Linear.

Existem diversos tipos de modelos de regressão como, por exemplo, linear e logística. A regressão logística se trata de um exemplo de classificação no qual o resultado final é uma categoria ou label podendo ser representado inclusive por valores inteiros, enquanto a regressão linear gerará um número contínuo. Exemplo de regressão linear: prever o valor de aluguel de uma casa (1000 - 5000) utilizando o número de quartos, área do lote e localização. A regressão linear pode ser simples ou múltipla. Simples é quando utilizamos apenas uma variável preditora, enquanto a múltipla utilizamos várias. Durante o processo de treinamento do algoritmo de regressão logística encontramos os coeficientes. Veja:


Regressão Linear Simples y = a + b*x

Regressão Linear Múltipla y = a + b1*x1 + b2*x2 + ...


Observações: a,b são os coeficientes, x é variável preditora, y é o valor a ser encontrado. a é chamado de viés, b é a inclinação da reta. O gráfico dessa função será uma reta, note abaixo que enquanto mais próximo a reta estiver dos pontos observados, ou seja, dados reais, melhor será o desempenho do modelo.

Como é de se esperar o algoritmo cometerá erros, o que desejamos como cientista de dados é seja a menor taxa possível. Contextualizando o problema de negócio estamos diante do seguinte desafio: prever a nota G3 de alunos de duas escolas GP (Gabriel Pereira) ou MS (Mousinho da Silveira). Coletamos dados históricos de 395 alunos com 33 variáveis. Utilizamos apenas: sexo, idade, endereço, número de faltas, a nota G1 e nota G2. Veja a descrição da base aqui.


2. Erro Quadrado Médio (MSE)

Observando o gráfico acima o modelo pode ter acertado ou errado a cada ponto. Em caso de erro, calcularemos a distância traçando uma reta plana entre a reta da função e ponto vermelho observado. Quando mais comprida for a reta plana rosa, maior será o erro. Veja alguns exemplos (não destacamos todos os erros por questões didáticas).

Para essa métrica, dado um ponto qualquer de dado, calcularemos a diferença entre o valor previsto e valor real, elevamos o resultado ao quadrado. Faremos a mesma coisa para todos os demais pontos de dados, soma-os e divide-os pelo número de elementos preditos. O valor da métrica inicia em zero, quanto maior significa que pior será o desempenho do modelo.


Exemplo: Considere dois pontos: A e B. O ponto A o valor real seja 15 e o modelo previu 10, logo teremos:

R1 = (valor previsto - valor real)²
R1 = 15 - 10
R1 = 5
R1 = 5²
R1 = 25

Para o ponto B, o valor correto seja 20, modelo previu 5.

R2 = (valor previsto - valor real)²
R2 = 20 - 5
R2 = 15
R2 = 15²
R2 = 30

Ao final teremos:

S = (R1 + R2) / 2
S = (25 + 30) / 2
S =  55/2
S = 27,2

Matematicamente, a formula é:


gif

Agora vamos ao código, porque sei que vocês gostam.

# Importação de pacotes
import pandas as pd
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
import statsmodels.api as sm
# Leitura da base de dados
alunos = pd.read_csv('student-mat.csv')
# Análise Exploratória Breve
alunos['age'].describe()

O comando describe fornece um resumo estatístico breve sobre uma variável quantitativa. Note que as idades variam entre 15 a 22, e a média das idades é 16.

count    395.000000
mean      16.696203
std        1.276043
min       15.000000
25%       16.000000
50%       17.000000
75%       18.000000
max       22.000000
Name: age, dtype: float64

Vamos explorar um pouco a varíavel absences, que representam as faltas. Veja:

alunos['absences'].describe()

O número de faltas variam entre 0 a 75, a média de faltas é 5.

count    395.000000
mean       5.708861
std        8.003096
min        0.000000
25%        0.000000
50%        4.000000
75%        8.000000
max       75.000000
Name: absences, dtype: float64

Não iremos explorar as demais variáveis, porque o foco desse artigo é a modelagem em si. Um ponto de alerta é que cabe ao Cientista de Dados preparar os dados sempre antes de iniciar a modelagem, cerca de 80% do tempo será nessa etapa. Remover valores outliers, corrigir valores missing, compreender como os dados estão distribuídos, eliminar colunas não relevantes fazem parte dos procedimentos aplicados nessa etapa.

[sexo, idade, endereço, número de faltas, a nota G1 e nota G2.]

Vamos para a modelagem.

# Divisão entre a variável preditora e a target
X = alunos[['age','absences','G1','G2']]
y = alunos[['G3']]
# Divisão entre dados de treino e teste. Utilizaremos a proporção 70 (treino)/30(teste).
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.30, random_state=42)
print('Tamanho da base: %d' % X.shape[0])
print('Quantidade de registros para treino: %d' % X_train.shape[0])
print('Quantidade de registros para teste: %d' % X_test.shape[0])

Após executar a célula acima, estaremos com:

Tamanho da base: 395
Quantidade de registros para treino: 276
Quantidade de registros para teste: 119

Retomando ao modelo:

# Treinamento
modelo = LinearRegression().fit(X_train, y_train)
# Efetuando previsões com os dados de teste
previsoes = modelo.predict(X_test)
# Calculando a MSE
MSE = mean_squared_error(y_test,previsoes)
print('%.2f' % MSE)

O resultado foi 4.27, o que não é nada mal, significando que o modelo teve uma baixa taxa de erros.

3. R²


Trata-se de uma das métricas mais conhecidas em modelos de regressão linear. Chamado também de Coeficiente de Determinação, explica o percentual da variabilidade dos dados da variável target, pode ser explicado pelas variáveis preditoras. O valor varia entre 0 a 1, representado em porcentagem. Enquanto maior, melhor será o desempenho do modelo preditivo.

Se, por exemplo, o valor R² = 75%, significa que 75% da variância dos dados podem ser explicados pelo modelo, enquanto os restantes é uma mera variância residual. Parece muito confuso, guerreiro? Pense nessa métrica para calcular o quão próximos estão os pontos previstos da reta de regressão desenhada. Veja abaixo:

No gráfico da esquerda, com R²= 0.99, veja como os pontos previstos se ajustam muito bem a reta de regressão traçada. Matematicamente o cálculo do R² é:

Resumidamente, calcula-se a razão entre a soma dos quadrados previstos e a soma das quadrados reais. Para cada ponto, devemos efetuar a diferença entre o valor previsto e valor real, elevar o resultado ao quadrado e depois somar todos os resultados. Retomando ao código:

#R2
r2 = r2_score(y_test, previsoes)
print('%.2f' % r2)

O resultado foi 0.81, o que é excelente.


3. R² Ajustado


A métrica R² apresenta o seguinte problema: há um viéis quando aumentamos o número de features ou acréscimo de novos dados, mesmo que não contribuam significamente para o modelo. Para contornar esse dilema, surgiu o R² ajustado, que penaliza o valor de uma feature caso não contribua de forma significativa para o modelo. Veja a fórmula matemática:

N é a quantidade de amostras, p representa o número de features, R² é o valor da métrica R². Assim como R², ela varia entre 0 - 1, enquanto mais alta, melhor será o desempenho do modelo. O valor de R² ajustado é sempre menor que R². É uma boa métrica para comparar versões de diferentes modelos utilizando algoritmos diferentes, variando a quantidade de features ou amostras. Usando como referência o blog medium, vamos 'codar':


def adjusted_r2(y_test, y_pred,X_train):
    
  from sklearn.metrics import r2_score

  adj_r2 = (1 - ((1 - r2_score(y_test, y_pred)) * (len(y_test) - 1)) / 
          (len(y_test) - X_train.shape[1] - 1))
    
  return adj_r2
adjusted_r2(y_test,previsoes,X_train)

O valor de R² ajustado foi de 0.79, o que é muito bom.


4. Valor-p


Da mesma forma que podemos avaliar o desempenho do modelo tendo uma visão geral, é possível determinar como cada variável preditora contribui individualmente para explicar a variância da target. O valor-p é aplicado a cada coefiente e um valor baixo (< 0,05) significa que esse recurso é útil para a target podendo ser mantido no modelo. O valor-p não está disponível no framework sklearn e sim no statsmodels, logo vamos precisar construir o modelo nesse framework também:

# Criação de um constante obrigatória
X2 = sm.add_constant(X)
# Construção do modelo e treinamento
est = sm.OLS(y, X2)
est2 = est.fit()
# Avaliação
print(est2.summary())

Executando a célula acima, vamos nos ater a essa parte de resultados:

Note que todos os coeficientes estão abaixo de 0,05, significando que todas elas contribuem de forma significativa para explicação da target.


5. Raiz do Erro Quadrado Médio (RMSE)


É uma melhoria do Erro do Quadrado Médio visando simplificar a interpretabilidade da métrica, acertando a unidade. O valor dela será menor que o Erro Quadrado Médio. A fórmula e código abaixo:


RMSE = mean_squared_error(y_test,previsoes,squared=False) 
print('%.2f' % RMSE)

O resultado foi 2.07, o que é bom.


6. Avaliando com Cuidado as Métricas e Boas Práticas


Não existe uma métrica mestre, ou seja, que anule o resultado de todas as demais, servindo como ponto de corte para o desempenho do modelo. Existem diversas métricas disponíveis conforme discutimos (R², R² Ajustado, Valor-p, MSE, RMSE) e cabe ao Cientista de Dados escolher quais delas serão usadas e por fim alinhar com a área de negócio, mostrando o resultado do desempenho do modelo preditivo. O código do projeto está aqui. Beijos no coração. Até a próxima.

gif





110 visualizações0 comentário