读书笔记数据科学入门————梯度下降

来源:互联网 发布:淘宝小二介入订单关闭 编辑:程序博客网 时间:2024/06/07 00:29

文章摘要:

从事数据科学的时候,常常面临这样的问题从某种特定情形中寻找出最佳的模型。“最佳”常常会被解读为类似于“最小化模型残差”或者“最大数据可能性”

这意味着解决一连串最优化问题。而梯度下降的问题适合从零开始逐步解决问题。


梯度下降的思想:

def sum_of_squares(v):
return sum(v_i**2 for v_i in v)

比如计算这个函数,梯度是指给出了输入值的方向,在这个方向上函数增长是最快的。最大化函数的方法是指首先从一个随机初始点开始,计算梯度,在梯度的方向

跨越一个小步,然后从一个新的初始点开始重复这个过程。

  但是这种方法的局限是如果这个函数有多个最小化点,那么这个方法是找不到这个点的。但是你也有有可能陷入死循环中,找不到最小值点。


那么梯度是如何进行估算的呢?

如果f是个单变量的函数,当x发生变化的时候f(x)也发生了变换。可以用导数的差商来进行衡量。

def difference_quotient(f,x,h):

   return (f(x+h) - f(x))/h;

其中h趋于0,导数就是(x,f(x))处的斜率

可以用partial偏函数来执行

from functools import partial

plt.plot(x,map(derivative,x),'rx',label='Actual')

通过导数定义来模拟估计

plt.plot(x,map(derivative_estimate,x),'b+',label='Estimate')



那么如果是多变量的函数呢。有多个偏导数,每个偏导数表示仅仅有一个输入变量变化的时候函数f也会变化

导数看作是第I个变量的函数,其他变量保持不变

def partial_difference_quotient(f,v,i,h):
w=[v_j+(h if j==i else 0)
  for j,v_j in enumerate(v)]
return (f(w)-f(v))/h

同样的方法计算梯度

def estimate_gradient(f,v,h=0.00001):
return [partial_difference_quotient(f,v,i,h)
for i,_ in enumerate(v)]


那么具体在程序中如何使用梯度收敛呢?

def step(v,direction,step_size):
return [v_i+step_size*direction_i
for v_i,direction_i in zip(v,direction)]

def sum_of_squares_gradient(v):
return [2*v_i for v_i in v]

随机选择一个初始值

v = [random.randint(-10,10) for i in range(3)]

tolerance = 0.0000001

while True:
gradient = sum_of_squares_gradient(v)
next_v = step(v,gradient,-0.01)
if distance(next_v,v)<tolerance:
break
v = next_v


选择正确的步长:

梯度是反向yi'donge lu

>>> step_size = [100,10,1,0.1,0.01,0.001,0.0001,0.00001]
>>> def safe(f):
def safe_f(*args,**kwargs):
try:
    return f(*args,**kwargs)
except:
return float('inf')
return safe_f

某些步长可能导致函数的输入无效,所以需要创建一个对无效输入值返回无限值得函数

0 0
原创粉丝点击