Regressão e classificação são tarefas de aprendizado supervisionado. A regressão é uma tarefa que tenta predizer um valor numérico e contínuo enquanto que a classificação tenta classificar o dado em uma classe que pertence a um conjunto discreto de classes.
Regressão linear é uma técnica estatística simples de regressão que tenta encontrar uma relação linear entre as variáveis explicativas e a variável resposta.
A equação a seguir descreve de maneira generalizada uma regressão linear:
-
$y$ é a variável resposta, ou seja, é a variável que o nosso modelo tenta prever e obter um valor. -
$x$ são nossas variáveis explicativas que são as entradas do nosso modelo - Os valores de
$\beta$ são os coeficientes, os quais são os parâmetros que nosso modelo procurar calcular para obter o melhor modelo possível -
$\beta_0$ é chamado de bias e é um coeficiente que não é acompanhado de nenhuma variável explicativa. Ou melhor, podemos considerar que há uma variável$x_0 = 1$ - Os coeficientes, junto com as variáveis explicativas, são chamados de componente sistemático do nosso modelo. Isso porque eles não são aleatórios e não variam uma vez que seus valores são determinados
-
$\varepsilon$ é o erro do nosso modelo. Nosso modelo gera um valor predito ,$\hat{y}$, que tem uma diferença do valor real da variável resposta$y$ . Afinal, estamos fazendo uma aproximação e isso significa que nem sempre nosso modelo irá acertar 100% o valor correto. Podemos chamar$\varepsilon$ de componente aleatório do nosso modelo, pois, em termos estatísticos, ele se trata de uma variável aleatória - Como toda variável aleatória,
$\varepsilon$ segue alguma distribuição de probabilidade. A regressão linear assume que o erro segue uma distribuição Normal.
Uma outra forma de representar a regressão linear é pela seguinte relação: $$ h_{\theta}(x) = \theta^Tx $$
Essa é uma representação vetorial em que
Agora que sabemos como é a função da regressão linear, como podemos encontrar os melhores valores para os coeficientes?
- Pensando de maneira lógica, se nós buscarmos uma maneira de minimizar o valor do erro, então a precisão de nossas predições será maximada.
- Dessa maneira, precisamos montar uma função que nos diz o quanto nós estamos errando. Esse tipo de função é chamado de função de custo
$J$ . - Na regressão linear a maneira mais utilizada de se calcular o erro aleatório é utilizando a métrica MSE que calcula a média dos quadrados das diferenças entre os valores previstos pelo modelo e os valores reais observados.
- Dessa forma, baseada na métrica MSE, temos a seguinte função de custo
$J(\theta)$ :
-
Observe, porém que nossa função
$J(\theta)$ divide a fórmula do MSE por 2. Isso é opcional e pode nos ajudar nos próximos passamos como veremos adiante. -
Agora que temos uma função de custo, minimizar essa função significa minimizar o erro e consequentemente otimizar nosso modelo.
-
Uma maneira natural de realizarmos essa minimização é calcularmos a derivada parcial para cada valor de
$\theta_i$ e igualarmos todas as equações a zero e assim encontrarmos os melhores valores de cada$\theta$ . -
Esse método, entretanto, é muito custoso e tem uma complexidade de
$O(N^3)$ .
Uma maneira mais otimizada de minimizar a função de custo e obter os valores dos coeficientes é utilizando a técnica do gradiente descendente. Mas o que é isso?
- A função gradiente é um conceito fundamental em cálculo vetorial e análise matemática.
- Sem entrar em muitos detalhes matemáticos, gradiente é uma função matemática que indica a direção em que a função original cresce mais rapidamente. Ou seja ele indica o caminho em que se deve percorrer se quer maximizar uma função
- No nosso caso, estamos interessado no negativo do gradiente (
$-\nabla f$ ), que nos indica a direção em que a função decresce mais rapidamente. Com isso podemos resolver problemas de minimização.
- O gradiente descendete é um método iterativo que utiliza o gradiente para minimizar uma função. Em cada interação, o gradiente descendente "caminha" uma certa quantidade na direção em que a função decresce mais rapidamente
- Basicamente, utilizamos o valor da última iteração do algoritmo e o gradiente da função para dar um novo passo na iteração atual
- O passo é definido pelo hiperparâmetro chamado de taxa de aprendizado (
$\alpha$ ). Esse hiperparâmetro é muito importante pois ele define o quanto vamos caminhar a cada interação. Se a taxa de aprendizado for muito pequena, então nosso algorítmo terá muitas iterações, várias desnecessárias, e teremos um custo computacional muito grande. Se a taxa de aprendizado for muito grande, então corremos o risco de na última iteração ultrapassarmos o ponto de mínimo da função, fazendo com que o algoritmo não consiga convergir.
- O que se faz na prática é ir alterando o valor do learning rate conforme as iterações vão ocorrendo. Dessa forma, começamos com passos grandes e o tamanho dos passos vão diminuindo a cada iteração até chegarmos em um ponto de parada.
-
Falando um pouco sobre como calcular o gradiente... Para a métrica MSE temos que: $$ \frac{\partial MSE}{\partial\theta_i} = \frac{2}{m}\sum\limits_{i=1}^{m} (h_\theta(x^{(i)}) - y^{(i)} )x_i $$
-
É aqui que a divisão por 2 da nossa função
$J(\theta)$ nos ajuda. Ele cancela a multiplicação por 2 e obtemos:
- A técnica do gradiente descendente caminha na direção em que a função decresce mais rapidamente. Entretanto, o gradiente descendente pode estar caminhando para um ponto de mínimo local. Ou seja, ele não garante que vamos chegar até o ponto de mínimo global. Tudo depende da função e da inicialização aleatória da primeira iteração.
- A regressão linear é um modelo de fácil interpretabilidade. Após o treinamento do modelo podemos observar o valor dos coeficientes para verificarmos quais variáveis possuem maior impacto no cálculo da saída.
- Há duas formas muito comuns de testar a linearidade dos dados:
- A primeira, e a mais simples, é basicamente fazer um plot com a variável resposta e cada uma das variáveis explicativas e verificar se há uma relação linear entre elas.
- A segunda maneira, e a mais utilizada, é após o treinamento do modelo, observar graficamente a dispersão dos resíduos com os valores preditos pelo modelo.
- Um resíduo é a diferença entre o valor real
$y$ e o valor predito$\hat{y}$ - O gráfico residual vs fitted é um gráfico em que no eixo
$x$ temos os valores preditos pelo nosso modelo e no eixo y temos os resíduos das predições - Uma relação linear entre os dados indica que não deve haver relação entre os resíduos e as predições. Dessa forma, teremos linearidade se nesse gráfico os pontos estiverem uniformemente distribuídos sobre uma linha horizontal
- Mas e caso não encontremos uma relação linear entre as variáveis?
- Muitas relações são possíveis de serem linearizadas através de um transformação que pode acontecer tanto em
$y$ quanto em$x$ - Ao aplicar transformações em
$y$ depois podemos apenas desfazer a transformação para obter o resultado original - Aplicar transformações em
$x$ implica em adicionar novas features em nosso modelo com essas novas transformações e isso deve ser feito com cuidado pois acabar levando o nosso modelo ao overfitting, principalmente com features polinomiais - Alguns exemplos:
$log(y)$ ,$x_2 = x_1^2$ ,$x_3 = x_1*x_2$
- É um modelo simples e eficiente
- Possui fácil interpretabilidade
- Muitas coisas possuem relações lineares, e muitas outras relações podem ser linearizadas
- Entender os fundamentos da regressão linear ajuda no entendimento de outros algortimos poderosos e complexos como o SVM e Redes Neurais.
# Instalando bibliotecas
# !pip install ISLP
# !pip install seaborn
#Importando bibliotecas
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from ISLP import load_data
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.datasets import load_diabetes
#Informações sobre o dataset em: https://islp.readthedocs.io/en/latest/datasets/Boston.html
df = load_data('Boston')
df.head()
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
crim | zn | indus | chas | nox | rm | age | dis | rad | tax | ptratio | lstat | medv | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0.00632 | 18.0 | 2.31 | 0 | 0.538 | 6.575 | 65.2 | 4.0900 | 1 | 296 | 15.3 | 4.98 | 24.0 |
1 | 0.02731 | 0.0 | 7.07 | 0 | 0.469 | 6.421 | 78.9 | 4.9671 | 2 | 242 | 17.8 | 9.14 | 21.6 |
2 | 0.02729 | 0.0 | 7.07 | 0 | 0.469 | 7.185 | 61.1 | 4.9671 | 2 | 242 | 17.8 | 4.03 | 34.7 |
3 | 0.03237 | 0.0 | 2.18 | 0 | 0.458 | 6.998 | 45.8 | 6.0622 | 3 | 222 | 18.7 | 2.94 | 33.4 |
4 | 0.06905 | 0.0 | 2.18 | 0 | 0.458 | 7.147 | 54.2 | 6.0622 | 3 | 222 | 18.7 | 5.33 | 36.2 |
df.columns
Index(['crim', 'zn', 'indus', 'chas', 'nox', 'rm', 'age', 'dis', 'rad', 'tax',
'ptratio', 'lstat', 'medv'],
dtype='object')
df.shape
(506, 13)
df.describe()
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
crim | zn | indus | chas | nox | rm | age | dis | rad | tax | ptratio | lstat | medv | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
count | 506.000000 | 506.000000 | 506.000000 | 506.000000 | 506.000000 | 506.000000 | 506.000000 | 506.000000 | 506.000000 | 506.000000 | 506.000000 | 506.000000 | 506.000000 |
mean | 3.613524 | 11.363636 | 11.136779 | 0.069170 | 0.554695 | 6.284634 | 68.574901 | 3.795043 | 9.549407 | 408.237154 | 18.455534 | 12.653063 | 22.532806 |
std | 8.601545 | 23.322453 | 6.860353 | 0.253994 | 0.115878 | 0.702617 | 28.148861 | 2.105710 | 8.707259 | 168.537116 | 2.164946 | 7.141062 | 9.197104 |
min | 0.006320 | 0.000000 | 0.460000 | 0.000000 | 0.385000 | 3.561000 | 2.900000 | 1.129600 | 1.000000 | 187.000000 | 12.600000 | 1.730000 | 5.000000 |
25% | 0.082045 | 0.000000 | 5.190000 | 0.000000 | 0.449000 | 5.885500 | 45.025000 | 2.100175 | 4.000000 | 279.000000 | 17.400000 | 6.950000 | 17.025000 |
50% | 0.256510 | 0.000000 | 9.690000 | 0.000000 | 0.538000 | 6.208500 | 77.500000 | 3.207450 | 5.000000 | 330.000000 | 19.050000 | 11.360000 | 21.200000 |
75% | 3.677083 | 12.500000 | 18.100000 | 0.000000 | 0.624000 | 6.623500 | 94.075000 | 5.188425 | 24.000000 | 666.000000 | 20.200000 | 16.955000 | 25.000000 |
max | 88.976200 | 100.000000 | 27.740000 | 1.000000 | 0.871000 | 8.780000 | 100.000000 | 12.126500 | 24.000000 | 711.000000 | 22.000000 | 37.970000 | 50.000000 |
# Plotting `Price` with remaining columns
plt.figure(figsize = (20, 15))
plotnumber = 1
for column in df:
if plotnumber <= 14:
ax = plt.subplot(3, 5, plotnumber)
sns.scatterplot(x = df['medv'], y = df[column])
plotnumber += 1
plt.tight_layout()
plt.show()
target = ['medv']
# features = [x for x in df.columns if x not in target]
features = ['lstat', 'rm']
y = df[target]
X = df[features]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model = LinearRegression()
model.fit(X_train,y_train)
y_pred = model.predict(X_test)
plt.scatter(y_test, y_pred)
plt.xlabel("Valores Reais")
plt.ylabel("Valores Previstos")
plt.title("Gráfico de Dispersão: Valores Reais vs Valores Previstos")
plt.show()
from sklearn import metrics
print('MAE:', metrics.mean_absolute_error(y_test, y_pred))
print('MSE:', metrics.mean_squared_error(y_test, y_pred))
print('RMSE:', np.sqrt(metrics.mean_squared_error(y_test, y_pred)))
MAE: 3.898759721382358
MSE: 31.243290601783627
RMSE: 5.589569804715174
residuos = y_test - y_pred
plt.scatter(y_pred, residuos)
plt.xlabel("Valores Previstos")
plt.ylabel("Resíduos")
plt.axhline(y=0, color='r', linestyle='--')
plt.title("Gráfico de Resíduos")
plt.show()
# Transformar os coeficientes em uma lista unidimensional
coeficientes_unidimensional = model.coef_.flatten()
# Criar o DataFrame com os coeficientes unidimensionais
coeficientes = pd.DataFrame(coeficientes_unidimensional, columns=['Coefficients'], index=X.columns)
coeficientes
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
Coefficients | |
---|---|
lstat | -0.632499 |
rm | 5.465099 |
model.intercept_
array([-3.84117708])
df.head()
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
crim | zn | indus | chas | nox | rm | age | dis | rad | tax | ptratio | lstat | medv | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0.00632 | 18.0 | 2.31 | 0 | 0.538 | 6.575 | 65.2 | 4.0900 | 1 | 296 | 15.3 | 4.98 | 24.0 |
1 | 0.02731 | 0.0 | 7.07 | 0 | 0.469 | 6.421 | 78.9 | 4.9671 | 2 | 242 | 17.8 | 9.14 | 21.6 |
2 | 0.02729 | 0.0 | 7.07 | 0 | 0.469 | 7.185 | 61.1 | 4.9671 | 2 | 242 | 17.8 | 4.03 | 34.7 |
3 | 0.03237 | 0.0 | 2.18 | 0 | 0.458 | 6.998 | 45.8 | 6.0622 | 3 | 222 | 18.7 | 2.94 | 33.4 |
4 | 0.06905 | 0.0 | 2.18 | 0 | 0.458 | 7.147 | 54.2 | 6.0622 | 3 | 222 | 18.7 | 5.33 | 36.2 |
df['medv_log'] = np.log(df['medv'])
df.drop('medv', axis = 1,inplace=True)
target = ['medv_log']
# features = [x for x in df.columns if x not in target]
features = ['lstat', 'rm']
y = df[target]
X = df[features]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model = LinearRegression()
model.fit(X_train,y_train)
y_pred = model.predict(X_test)
plt.scatter(y_test, y_pred)
plt.xlabel("Valores Reais")
plt.ylabel("Valores Previstos")
plt.title("Gráfico de Dispersão: Valores Reais vs Valores Previstos")
plt.show()
residuos = y_test - y_pred
plt.scatter(y_pred, residuos)
plt.xlabel("Valores Previstos")
plt.ylabel("Resíduos")
plt.axhline(y=0, color='r', linestyle='--')
plt.title("Gráfico de Resíduos")
plt.show()
results = y_test
results['y_pred'] = y_pred
results
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
medv_log | y_pred | |
---|---|---|
173 | 3.161247 | 3.188354 |
274 | 3.478158 | 3.444702 |
491 | 2.610070 | 2.786197 |
72 | 3.126761 | 3.271902 |
452 | 2.778819 | 2.860652 |
... | ... | ... |
412 | 2.884801 | 1.979498 |
436 | 2.261763 | 2.854283 |
411 | 2.844909 | 2.762125 |
86 | 3.113515 | 2.987545 |
75 | 3.063391 | 3.173820 |
102 rows × 2 columns
# Transformar os coeficientes em uma lista unidimensional
coeficientes_unidimensional = model.coef_.flatten()
# Criar o DataFrame com os coeficientes unidimensionais
coeficientes = pd.DataFrame(coeficientes_unidimensional, columns=['Coefficients'], index=X.columns)
coeficientes
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
Coefficients | |
---|---|
lstat | -0.037781 |
rm | 0.140859 |
A Regressão Logística é um método estatístico que modela a probabilidade de determinado evento pertencer ou não a uma classe a partir de um conjunto de variáveis independentes. Assim, a Regressão Logística, diferente da Regressão Linear, é um algoritmo de classificação binária. A principal vantagem da regressão logística é a interpretabilidade.
- A variável resposta Y deve ser binária, i.e.,
$y_i \in {0,1}$ , spam ou não spam, fraude ou não fraude; - Ausência de multicolineariedade: as variáveis preditoras X$ = (x_1,x_2,...,x_n)$ devem ser independentes entre si;
- A relação entre as variáveis preditoras e a função preditora sigmóide é linear.
Diferente da regressão linear, a regressão logística não presspõe:
- homocedasticidade(variância constante);
- normalidade dos resíduos;
- relação linear entre variáveis preditoras e variável predita.
A função logística é definida por:
A chance (
Quando aplicamos a função logarítmica em ambos os lados da equação, temos o log da chance ou
O Método de Máxima Verossimilhança é um método estatístico para a estimação de parâmetros de um modelo estatístico.
Maximizar a Máxima Verossimilhança equivale a maximizar o logarítmo da função de Máxima Verossimilhança, já que a função logarítmica é uma função monótona (ou seja, ela preserva a relação de ordem). Consequentemente, se multiplicarmos a verossimilhança por -1, obtemos a Log Verossimilhança Negativa e encontrar seu ponto de mínimo equivale a encontrar o ponto de máximo da verossimilhança.
A Log Verossimilhança Negativa também é chamada de
Assim, a função de custo para regressão logística é chamada de
O modelo da Regressão Logística pode ser extendido para classificações de uma variável resposta em mais de duas categorias, isto é, para classificação multiclasse. Podemos usar a técnica de One-vs-All ou a Regressão Logística Multinomial:
- Aula Data Joao Guilherme
- Aula Data Luisa
- Wikipedia Regressão Linear
- Medium Gradiente Descendent
- Regressão Linear com gradiente descendente
- Interpretando gráfico de resíduos
- Um pouco mais sobre as funções de custo
- Logistic Regression: Maximum Likelihood Estimation & Gradient Descent
- REGRESSÃO LOGÍSTICA – ALGORITMOS DE APRENDIZADO DE MÁQUINAS
- Plot multinomial and One-vs-Rest Logistic Regression