Data Science do zero: Primeiras regras com o Python


def negate(f): """retorna uma função que, para qualquer entrada, x retorna -f(x)""" return lambda



Baixar 5.26 Mb.
Pdf preview
Página69/75
Encontro24.07.2022
Tamanho5.26 Mb.
#24344
1   ...   65   66   67   68   69   70   71   72   ...   75
Data Science do zero - Primeiras regras
def negate(f):
"""retorna uma função que, para qualquer entrada, x retorna -f(x)"""
return lambda *args, **kwargs: -f(*args, **kwargs)


def negate_all(f):
"""o mesmo quando f retorna uma lista de números"""
return lambda *args, **kwargs: [-y for y in f(*args, **kwargs)]
def maximize_batch(target_fn, gradient_fn, theta_0, tolerance=0.000001):
return minimize_batch(negate(target_fn),
negate_all(gradient_fn),
theta_0,
tolerance)


Gradiente Descendente Estocástico
Conforme mencionamos anteriormente, usaremos com frequência o gradiente
descendente para escolher os parâmetros de um modelo de modo que minimize
alguma noção de erro. Ao usar o grupo de abordagens anteriores, cada passo
gradiente requer que nós façamos uma previsão e computemos o gradiente para
o conjunto de dados inteiro, fazendo com que cada passo leve mais tempo.
Normalmente, essas funções de erro são aditivas, o que significa que o erro
previsto no conjunto de dados inteiro é simplesmente a soma dos erros preditivos
para cada ponto.
Quando o caso é esse, podemos aplicar uma técnica chamada gradiente
descendente estocástico, que computa o gradiente (e anda um passo) apenas um
ponto de cada vez. Ele circula sobre nossos dados repetidamente até alcançar um
ponto de parada.
Durante cada ciclo, vamos querer iterar sobre nossos dados em ordem aleatória:
def in_random_order(data):
"""gerador retorna os elementos do dado em ordem aleatória"""
indexes = [i for i, _ in enumerate(data)]# cria uma lista de índices
random.shuffle(indexes) # os embaralha
for i in indexes: # retorna os dados naquela ordem
yield data[i]
Andaremos um passo gradiente para cada ponto de dados. Esse método deixa a
possibilidade de circularmos próximos a um mínimo para sempre, então quando
pararmos de obter melhorias, diminuiremos o tamanho do passo e,
eventualmente, pararemos:
def minimize_stochastic(target_fn, gradient_fn, x, y, theta_0, alpha_0=0.01):
data = zip(x, y)
theta = theta_0 # palpite inicial
alpha = alpha_0 # tamanho do passo inicial
min_theta, min_value = None, float("inf") # o mínimo até agora
iterations_with_no_improvement = 0
# se formos até 100 iterações sem melhorias, paramos
while iterations_with_no_improvement < 100:
value = sum( target_fn(x_i, y_i, theta) for x_i, y_i in data )
if value < min_value:


# se achou um novo mínimo, lembre-se
# e volte para o tamanho do passo original
min_theta, min_value = theta, value
iterations_with_no_improvement = 0
alpha = alpha_0
else:
# do contrário, não estamos melhorando, portanto tente
# diminuir o tamanho do passo
iterations_with_no_improvement += 1
alpha *= 0.9
# e ande um passo gradiente para todos os pontos de dados
for x_i, y_i in in_random_order(data):
gradient_i = gradient_fn(x_i, y_i, theta)
theta = vector_subtract(theta, scalar_multiply(alpha, gradient_i))
return min_theta
A versão estocástica será tipicamente mais rápida do que a versão batch.
Naturalmente, vamos querer uma versão que maximize da mesma forma:

Baixar 5.26 Mb.

Compartilhe com seus amigos:
1   ...   65   66   67   68   69   70   71   72   ...   75




©historiapt.info 2022
enviar mensagem

    Página principal