Objetivo: Entender como aplicar a regressão linear e a regressão logística.
O rótulo $y$ (valor 0 ou 1 no nosso caso) pode ser pensado como o valor que desejamos predizer para uma observação $\mathbf{x}$ qualquer.
Portanto a ideia é isso mesmo. Usaremos aqui os mesmos dados do Exercício 0-1.
No plot a seguir, os exemplos positivos e negativos aparecem em alturas distintas no gráfico (diferentemente da forma vista no Exercício 0-1)
In [ ]:
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
# Criar um array com n números.
# Cada um desses números é um exemplo x
# Em seguida, estender os exemplos: x ---> (1,x)
N = 14
x = np.array([0.2, 0.5, 1, 1.1, 1.2, 1.8, 2, 4.3, 4.4, 5.7, 6.9, 7.5, 8, 8.2])
X = np.vstack(zip(np.ones(N), x))
print 'Dimensão do array X:', X.shape
# Supor que os exemplos na primeira metade são negativos e o restante são
# positivos
y = np.array([0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1])
print 'dimensão do array y:', y.shape
# show elements in distinct colors to discriminate negative from positive ones
for i in range(N):
if y[i]==1:
plt.plot(X[i,1], y[i], 'bo') # o (bolinhas) azuis (blue)
else:
plt.plot(X[i,1], y[i], 'ro') # o (bolinhas) vermelhas (red)
plt.ylim(-1,2)
plt.xlabel('x')
plt.ylabel('y (classe)')
plt.show()
In [ ]:
# Supomos que o arquivo funcoes.py já está criado
from funcoes import gradientDescent, computeCost
# chutar uns pesos iniciais e calcular o custo inicial
w = np.zeros(2)
initialCost = computeCost(X, y, w)
print 'Initial cost: ', initialCost
# Some gradient descent settings
iterations = 1500
alpha = 0.01
# run gradient descent
w, J_history = gradientDescent(X, y, w, alpha, iterations)
finalCost = computeCost(X, y, w)
print 'Final cost: ', finalCost
# plot do resultado
print 'Weight w found by gradient descent: (%f, %f)' % (w[0], w[1])
# Plot the linear fit
plt.plot(X[:7,1], y[:7], 'ro')
plt.plot(X[7:,1], y[7:], 'bo')
plt.plot(X[:,1], X.dot(w), '-')
plt.ylim(-1,2)
plt.xlabel('x')
plt.ylabel('y (classe)')
plt.show()
Hmmm, alguma coisa está estranha. Está ? Pense um pouco. Você consegue explicar esse resultado ?
Vamos aplicar a regressão logística. (Lembre-se: apesar do nome, a regressão logística não visa "ajustar" uma função às observações)
Na regressão logística, a combinação linear $\sum_{j=0}^{n} w_j\,x_j$ é processada pela função sigmoide $s(z) = \frac{1}{1+e^{-z}}$
Isto é, calcula-se:
$$
g(\mathbf{x}) = s(h(\mathbf{x})) = s(\sum_{j=0}^{n} w_j\,x_j)
$$
e compara-se $g(\mathbf{x})$ com $y$. A ideia é que $g(\mathbf{x})$ aproxime a posteriori $P(y=1|\mathbf{x})$.
Para esta parte, será necessário o arquivo funcoes2.py (que faz parte do kit)
In [ ]:
from funcoes2 import sigmoid, gradientDescent2, computeCost2
# chutar uns pesos iniciais e calcular o custo inicial
w = np.zeros(2)
initialCost = computeCost2(X, y, w)
print 'Initial cost: ', initialCost
# Some gradient descent settings
iterations = 1000
alpha = 0.005
# run gradient descent
w, J_history = gradientDescent2(X, y, w, alpha, iterations)
finalCost = computeCost2(X, y, w)
print 'Final cost: ', finalCost
print w
R = X.dot(w)
plt.plot(X[:,1], X.dot(w), '-')
for i in range(N):
if R[i] > 0.5:
plt.plot(X[i,1], y[i], 'bo')
else:
plt.plot(X[i,1], y[i], 'ro')
plt.xlabel('x')
plt.ylabel('y (class)')
plt.show()
Funcionou ?
É possível melhorar o resultado (encontrar uma reta que separa vermelhos dos azuis) ?