Para optimizar los parametros de la regresion, debemos hacer:
${y = \frac{1}{(1+e^{-(b1x_1+b2x_2+c)})}}$
Cada dato : ${p(y="c"|experimentos) = p(y_1="C")*p(y_2="C") }$
${p(y=1|d) = 1/n \prod_{i=1}^{n}} (1-p(y))^{1-y}. (p(y))^{y}$
$l = \prod_{i=1}^{n}(1- \frac{1}{(1+e^{-(b1x+b2x_2+c)})} )^{(1-y)}* (\frac{1}{(1+e^{-(b1x+b2x_2+c)})})^y$
$\log(l) = \sum_{i=1}^{n} +(1-y) \log(1- \frac{1}{(1+e^{-(b_1x+b_2x_2+c)})} ) + y \log(\frac{1}{(1+e^{-(b_1x+b_2x_2+c)})})$
${\frac{dl}{db_1} = \frac{dl}{du}\frac{du}{db_1} }$
${\frac{dl}{db_1} = y\log([1+e^{-(b_1x+b_2x_2+c)}]^{-1}) + (1-y)\log(\frac{e^{-(b_1x+b_2x_2+c)}}{1+e^{-(b_1x+b_2x_2+c)}}) }$
${\frac{dl}{db_1} = -y\log(1+e^{-(b_1x+b_2x_2+c)}) + (1-y)[ \log(e^{-(b_1x+b_2x_2+c)}) - \log(1 +e^{-(b_1x+b_2x_2+c)})] }$
${\frac{dl}{db_1} = \log(e^{-(b_1x+b_2x_2+c)}) -\log(1 +e^{-(b_1x+b_2x_2+c)}) −y \log(e^{-(b_1x+b_2x_2+c)}) }$
${\frac{dl}{db_1} = \frac{-(b_1x_1+b_2x_2+c)}{db_1} -\frac{\log(1 +e^{-(b_1x_1+b_2x_2+c)})}{db_1} −\frac{y ({-(b_1x_1+b_2x_2+c)})}{db_1} }$
${ = -x_1 - (1 +e^{-(b_1x_1+b_2x_2+c)})^{-1} (e^{-(b_1x_1+b_2x_2+c)})(-x_1)) +yx_1 }$
${ = -x_1 - (-x_1 )(\frac{1}{1+e^{(b_1x_1+b_2x_2+c)}}) +yx_1 }$
${ = -x_1 - (-x_1 )(\frac{1}{1+e^{(b_1x_1+b_2x_2+c)}}) +yx_1 }$
${ = \frac{-x_1+x_1+ -x_1 e^{(b_1x_1+b_2x_2+c)}}{1+e^{(b_1x_1+b_2x_2+c)}}) +yx_1 }$
${ = x_1 (y-\frac{ e^{(b_1x_1+b_2x_2+c)}}{1+e^{(b_1x_1+b_2x_2+c)}} ) }$
${\frac{dl}{db_1} = x_1 (y-\frac{ 1}{1+e^{-(b_1x_1+b_2x_2+c)}} ) }$
${\frac{dl}{dc} = \log(e^{-(b_1x_1+b_2x_2+c)}) -\log(1 +e^{-(b_1x_1+b_2x_2+c)}) −y \log(e^{-(b_1x+b_2x_2+c)}) }$
${\frac{dl}{dc} = \frac{-(b_1x_1+b_2x_2+c)}{dc} -\frac{\log(1 +e^{-(b_1x_1+b_2x_2+c)})}{dc} −\frac{y ({-(b_1x_1+b_2x_2+c)})}{dc} }$
${\frac{dl}{dc} = -1 - (-1 )(\frac{1}{1+e^{(b_1x_1+b_2x_2+c)}}) }$ +y
${\frac{dl}{dc} = y-\frac{ e^{(b_1x_1+b_2x_2+c)}}{1+e^{(b_1x_1+b_2x_2+c)}} ) }$
${\frac{dl}{dc} = y-\frac{ 1}{1+e^{-(b_1x_1+b_2x_2+c)}} }$
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import math
import random
import pandas as pd
import numpy as np
%matplotlib inline
Esta funcion es en forma de S, el rango va de 0 a 1. Y el objetivo es encontrar la funcion que mejor precide los valores de y
f = lambda x : 1/(1+math.exp(-x))
plt.plot(range(-10,10),[f(d) for d in range(-10,10)])
plt.show()
En este ejemlo vamos a generar los valores de Y. De esta forma esperamos que la regresion encuentre los coeficientes. En este caso vamos a predicr si un estudiante pasara o no el proximo examen, basado en las 2 ultimas notas.
n_est = 100
x_1 = [random.random()*5.0 for i in range(n_est)]
x_2 = [random.random()*5.0 for i in range(n_est)]
y = [1 if (x1_i+ x2_i)/2>3.0 else 0 for x1_i,x2_i in zip(x_1,x_2)]
df = pd.DataFrame({"n1":x_1,"n2":x_2,"y":y})
df.head(10)
fig, ax = plt.subplots(nrows=1, ncols=2)
df.boxplot(column='n1',by='y',ax=ax[0])
df.boxplot(column='n2',by='y',ax=ax[1])
plt.show()
class LogisticRegression():
def __init__(self, lr=0.1, is_norm=False):
self.lr = 0.1
self.b = [0.0, 0.0]
self.c = 0.0
self.is_norm = is_norm
def train(self, x , y):
# Copiamos las variables y hacemos la actualziacion despues de calcular
b = self.b[:]
c = self.c
if np.array(x).ndim < 2 :
b[0] = b[0] + self.lr * x[0]*(y - self.sigmoid(x))
b[1] = b[1] + self.lr * x[1]*(y - self.sigmoid(x))
if not self.is_norm:
c = c + self.lr * (y - self.sigmoid(x))
else:
n_row = np.array(x).shape[0]
b[0] = b[0] + self.lr *(sum([x[i][0]*(y[i] -self.sigmoid(x[i]))
for i in range(n_row)])/float(n_row))
b[1] = b[1] + self.lr *(sum([x[i][1]*(y[i] -self.sigmoid(x[i]))
for i in range(n_row)])/float(n_row))
if not self.is_norm:
c = c + self.lr *(sum([y[i] -self.sigmoid(x[i])
for i in range(n_row)])/float(n_row))
self.b = b
self.c = c
def predict(self,x):
y_hat = None
if np.array(x).ndim < 2 :
y_hat = 1 if self.predict_proba(x)>0.5 else 0
else:
y_hat = [1 if ypr_i>0.5 else 0 for ypr_i in self.predict_proba(x)]
return y_hat
def predict_proba(self,x):
y_prob = []
if np.array(x).ndim < 2 :
y_prob = self.sigmoid(x)
else:
for x_i in x:
y_prob.append(self.sigmoid(x_i))
return y_prob
def sigmoid(self,x):
return 1.0/(1.0+math.exp(-1*(self.b[0]*x[0]+self.b[1]*x[1]+self.c)))
def __repr__(self):
return "Log model param:{}, constant: {}".format(self.b, self.c)
Entrenaremos el modelo con una observacion. Comparado con todas las observaciones varias interaciones. Ademas, dividiremos los datos en 80% porciento para entrenamiento y el 20% para test
def measure_acc(y_pred, y_test):
m_acc = np.mean(np.array([1.0 if y_h == y_t else 0.0
for y_h, y_t in zip(y_hat,y_test) ]))
return m_acc
def norm_x(x):
x_mean, x_std = np.mean(x), np.std(x)
norm_x = [(x_i - x_mean)/x_std for x_i in x]
return norm_x
x = list(zip(x_1,x_2))
ix = list(range(len(x)))
random.shuffle(ix)
cut = int(len(x)*0.8)
x_train = x[:cut]
y_train = y[:cut]
x_test = x[cut:]
y_test = y[cut:]
model_1 = LogisticRegression(lr=0.05)
for i in range(10000):
model_1.train(x_train,y_train)
y_hat = []
y_hat = model_1.predict(x_test)
print("Model 1", measure_acc(y_hat, y_test))
print("Model1", model_1)
model_2 = LogisticRegression(lr=0.05)
for i in range(1000):
for x_i, y_i in zip(x_train,y_train):
model_2.train(x_i, y_i)
y_hat = model_2.predict(x_test)
print("Model 2", measure_acc(y_hat, y_test))
print("Model2", model_2)
Despues de aprender, vamos a ver como clasifica
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
from matplotlib.colors import LinearSegmentedColormap
def create_surface(model,x_1, x_2):
g_x1 = np.arange(min(x_1), max(x_1), 0.25)
g_x2 = np.arange(min(x_2), max(x_2), 0.25)
g_x1, g_x2 = np.meshgrid(g_x1, g_x2)
g_z = np.array(zip(g_x1, g_x2))
print (np.array(g_z).shape)
f_sigmoid = np.apply_along_axis(lambda x: model.predict_proba(x), 1, g_z)
return g_x1, g_x2, f_sigmoid
def plot_matplolib(model_1, x_1, x_2, y):
g_x1, g_x2, f_sigmoid = create_surface(model_1, x_1, x_2)
fig = plt.figure(figsize=plt.figaspect(0.4))
ax = fig.add_subplot(1, 2, 1, projection='3d')
ax2 = fig.add_subplot(1, 2, 2, projection='3d')
color = ['red' if y_i == 1 else 'blue' for y_i in y]
cdict4 = {'red': ((0.0, 0.0, 0.0),
(0.25, 0.0, 0.0),
(0.5, 0.8, 1.0),
(0.75, 1.0, 1.0),
(1.0, 0.4, 1.0)),
'green': ((0.0, 0.0, 0.0),
(0.25, 0.0, 0.0),
(0.5, 0.9, 0.9),
(0.75, 0.0, 0.0),
(1.0, 0.0, 0.0)),
'blue': ((0.0, 0.0, 0.4),
(0.25, 1.0, 1.0),
(0.5, 1.0, 0.8),
(0.75, 0.0, 0.0),
(1.0, 0.0, 0.0))
}
cdict4['alpha'] = ((0.0, 1.0, 1.0),
# (0.25,1.0, 1.0),
(0.5, 0.3, 0.3),
# (0.75,1.0, 1.0),
(1.0, 1.0, 1.0))
blue_red1 = LinearSegmentedColormap('BlueRedAlpha', cdict4)
ax.scatter(x_1, x_2, y, color=color)
surf = ax.plot_surface(g_x1, g_x2, f_sigmoid, cmap=blue_red1,
linewidth=0, antialiased=False)
fig.colorbar(surf, shrink=0.5, aspect=10)
# pintar solo los puntos
ax2.scatter(x_1, x_2, y, color=color)
return fig
figure = plot_matplolib(model_1, x_1, x_2, y)
plt.show()
#Install plotly offline
# download from
#mv plotly.min.js /Users/millenium/anaconda/lib/python2.7/site-packages/plotly/offline/
def plot_plotly(model_1, x_1, x_2, y):
def get_text(z,x,y):
textz = [['x:'+'{:0.5f}'.format(x[i][j])+'<br>y:'+'{:0.5f}'.format(y[i][j])+
'<br>z:'+'{:0.5f}'.format(z[i][j])
for j in range(z.shape[1])] for i in range(z.shape[0])]
return textz
g_x1, g_x2, f_sigmoid = create_surface(model_1, x_1, x_2)
color = ['red' if y_i == 1 else 'blue' for y_i in y]
scatter = dict(
mode = "markers",
name = "y",
type = "scatter3d",
x = x_1, y = x_2, z =y,
marker = dict( size=2, color=color )
)
data = [
scatter,
go.Surface(
x=tuple(g_x1),
y=tuple(g_x2),
z=tuple(f_sigmoid),
text= np.array(get_text(f_sigmoid,g_x1,g_x2)),
hoverinfo='text',
opacity=0.50
)
]
layout = go.Layout(
title='Logistic Function',
autosize=False,
width=500,
height=500,
margin=dict(
l=0.75,
r=0.5,
b=0.25,
t=0
)
)
fig = go.Figure(data=data, layout=layout)
return fig
try:
import plotly.graph_objs as go
import plotly.offline as py
import holoviews as hv
import plotly
py.init_notebook_mode()
fig = plot_plotly(model_1, x_1, x_2, y)
py.iplot(fig)
except:
print("Error important plotly")
model_1 = LogisticRegression(lr=0.05, is_norm=True)
x1_norm = norm_x(np.array(x_train)[:,0])
x2_norm = norm_x(np.array(x_train)[:,1])
x_norm_train = zip(x1_norm, x2_norm)
x1_norm_t = norm_x(np.array(x_test)[:,0])
x2_norm_t = norm_x(np.array(x_test)[:,1])
x_norm_test = zip(x1_norm_t, x2_norm_t)
for i in range(10000):
model_1.train(x_norm_train, y_train)
y_hat = []
y_hat = model_1.predict(x_norm_test)
print("Model 1", measure_acc(y_hat, y_test))
print("Model1", model_1)
try:
import plotly.graph_objs as go
import plotly.offline as py
import holoviews as hv
import plotly
py.init_notebook_mode()
fig = plot_plotly(model_1, norm_x(x_1), norm_x(x_2), y)
py.iplot(fig)
except:
print("Error important plotly")