Exercício 1-3: Classificação

Objetivo: Entender como aplicar a regressão linear e a regressão logística.

1. Como aplicar regressão em um problema de classificação

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()

2. Regressão linear

Vamos aplicar a regressão linear, usando o método gradiente descendente.
Se não lembrar do método, volte para o Exercício 1-1

Neste ponto, você já deve ter criado o arquivo funcoes.py


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 ?

3. Regressão logística

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) ?