## 理论
回归问题通常用于连续值的预测,可以总结为给定x,在通过模型的结构f(x)后得到y,我们希望x能够逼近真实的数据y
在线性回归中我们添加了一个噪音,我们认为这个噪音是满足高斯分布的,我们的目标是得到w,和b,为了找到最佳的w和b我们构造了一个新的损失函数loss
我们认为当这个损失函数最小的时候能够得到不错的w和b从而获得不错的估计值,因此这个问题就转换成了找到loss的最小值,为了找到最小值我们要使用梯度下降算法
梯度下降算法的核心就是一个函数导数是指向函数值的增长方向的,因此当导数值变化的时候我们就可以得到这个函数的极小值,为了找到最小值,这个计算导数的最小值得方向应该是朝着导数变小的方向来前进,为了不要不要一步跨过最小点,我们需要使用学习率*导数,这个就是步长,这样就可以防止跨过最小点,从而能够逼急最小点,梯度下降在任一点都可以指向梯度下降最快的方法,在三维中也是一样的:
总结,目标是得到w’和b’,为了得到这两个值我们使用了一个损失函数,损失函数最小的时候的可以得到最优的w’和b’,为了得到最小的损失函数我们使用梯度下降方法:
- 构造损失函数
- 梯度下降找到最小的损失函数
就是这么简单!
实战
numpy的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
import numpy as np # y = wx + b def compute_error_for_line_given_points(b, w, points): totalError = 0 for i in range(0, len(points)): x = points[i, 0] y = points[i, 1] # computer mean-squared-error totalError += (y - (w * x + b)) ** 2 # average loss for each point return totalError / float(len(points)) def step_gradient(b_current, w_current, points, learningRate): b_gradient = 0 w_gradient = 0 N = float(len(points)) for i in range(0, len(points)): x = points[i, 0] y = points[i, 1] # grad_b = 2(wx+b-y) b_gradient += (2/N) * ((w_current * x + b_current) - y) # grad_w = 2(wx+b-y)*x w_gradient += (2/N) * x * ((w_current * x + b_current) - y) # update w' new_b = b_current - (learningRate * b_gradient) new_w = w_current - (learningRate * w_gradient) return [new_b, new_w] def gradient_descent_runner(points, starting_b, starting_w, learning_rate, num_iterations): b = starting_b w = starting_w # update for several times for i in range(num_iterations): b, w = step_gradient(b, w, np.array(points), learning_rate) return [b, w] def run(): points = np.genfromtxt("data.csv", delimiter=",") learning_rate = 0.0001 initial_b = 0 # initial y-intercept guess initial_w = 0 # initial slope guess num_iterations = 1000 print("Starting gradient descent at b = {0}, w = {1}, error = {2}" .format(initial_b, initial_w, compute_error_for_line_given_points(initial_b, initial_w, points)) ) print("Running...") [b, w] = gradient_descent_runner(points, initial_b, initial_w, learning_rate, num_iterations) print("After {0} iterations b = {1}, w = {2}, error = {3}". format(num_iterations, b, w, compute_error_for_line_given_points(b, w, points)) ) if __name__ == '__main__': run() |
使用到的数据:
迭代1000次的运行结果: