赞
踩
线性回归是一种线性模型,它假设输入变量x与单个输出变量y之间存在线性关系。具体的说,就是利用线性回归模型,从一组输入变量的线性组合中,计算出输出变量y。
如果有两个或者两个以上的自变量,这样的线性回归分析,就是多元线性回归。其实,在实际生活中,一个现象往往受多个因素的影响,所以多元线性回归比一元线性回归的应用更广。
假如说:我想买西瓜,此时,我应该挑选自己满意的西瓜,那么怎么挑选呢,我们应该从从色泽,根蒂,敲打的声音等多个维度考察西瓜的质量,假如每个影响西瓜的因素和瓜的质量是线性关系,就可以写成入下线性的关系:
使用梯度下降法求解多元线性回归:
其中J为损失函数,对损失函数中的参数求偏导得到梯度,带到梯度下降公式中,使得梯度不断下降,即沿着负梯度方向,使得损失函数越来越小,即误差最小,模型越来越好。
负梯度方向:函数变化减少最快的方向,即变量沿此方向变化时,函数减少最快。
损失函数是系数的函数,如果系数沿着损失函数的负梯度变化,此时损失函数减少最快,能够以最快速度下降到最小值。
其中,梯度下降公式入下:
其中α叫做步长,也叫做学习率,这意味着我们可以通过控制及步长来控制每一步走的距离,保证不要走太快,防止错过了最低点,同时也要保证尽快收敛,故α在梯度下降中还是比较重要的,既不能太大,也不能太小。
如果觉得多元线性回归的梯度下降不好理解,我们可以退回到一元线性回归的梯度下降进行观察,如下所示,其实就是不停的更新参数值,使得损失函数越来越小
线性回归求解可以使用最小二乘法和梯度下降法,下面我们针对两种方法进行对比:
1-相同点:本质和目标相同,两种都是经典的学习算法,在给定已知数据的情况下,利用求导算出一个模型(函数),使得损失函数最小,然后对给定的新数据进行估算预测。
2-不同点:损失函数的选择:最小二乘法必须使用平方损失函数,而梯度下降可以选取其它函数;实现方法不同,最小二乘法是实现全局最小,而梯度下降是一种迭代法;一般最小二乘法一定可以得到全局最小,但对于多元计算繁琐,且复杂情况下未必有解,而梯度下降的迭代比较简单,但找到的一般是局部最小,即极小值,仅在目标函数是下凸函数是才是全局最小,到最小点的收敛速度会变慢,且对初始点的选择极为敏感,而且步长的选择对损失函数也有影响。
使用梯度下降求解线性回归代码如下所示,
demo同步已经能上传至github,包含源代码和数据集,链接如下:https://github.com/wgdwg/-1
#梯度下降求解线性回归 import numpy as np #导入计算包 import matplotlib.pyplot as plt #导入绘图包 #1.加载数据源,并画出散点图 points = np.genfromtxt('data.csv', delimiter=',') #提取points的两列数据,分别作为x,y x = points[:,0] #第一列数据 y = points[:,1] #第2列数据 #用plt画出散点图 plt.scatter(x,y) plt.show() #2.定义损失函数,损失函数是系数的函数 def cost_function(w, b, points): total_const = 0 #初始化损失函数 m = len(points) #数据个数 #逐点计算平方误差,然后求平均数 for i in range(m): x = points[i,0] #第i行,第1列 y = points[i,1] #第i行,第2列 total_const += (y - w * x - b) ** 2 return total_const / m #3.定义模型的超参数 alpha = 0.0001 #学习速率 init_w = 0 #初始参数 init_b = 0 #初始参数 num_iter = 10 #迭代次数 #4.定义核心梯度下降算法函数 def grad_desc(points, init_w, init_b, num_iter): w = init_w b = init_b #定义一个列表cost_list保存所有损失函数值 cost_list = [] for i in range(num_iter): cost_list.append(cost_function(w,b,points)) #存入损失函数 w, b = step_grad_desc(w,b,alpha,points) #不挺的更新参数w,b return [w, b, cost_list] def step_grad_desc(current_w, current_b, alpha, points): sum_grad_b = 0 sum_grad_w = 0 m = len(points) #对每个点,带入公式求和 for i in range(m): x = points[i, 0] # 第i行,第1列 y = points[i, 1] # 第i行,第2列 sum_grad_w += (current_w * x + current_b - y) * x sum_grad_b += (current_w * x + current_b - y) ; #求当前的偏导 grad_w = 2 / m * sum_grad_w grad_b = 2 / m * sum_grad_b #梯度下降,沿负梯度方向,更新当前的w和b update_w = current_w - alpha * grad_w update_b = current_b - alpha * grad_b return update_w, update_b #5.测试,运行梯度下降,计算最优的w和b w, b, cost_list = grad_desc(points, init_w, init_b, num_iter) cost = cost_function(w,b,points) #得到损失函数 print("参数w = ", w) print("参数b = ", b) print("损失函数 = ", cost) plt.plot(cost_list) plt.show() #6.画出拟合曲线 plt.scatter(x,y) #原始的散点图 pred_y = (w * x) + b #预测的y plt.plot(x,pred_y,c='r') #红色的拟合直线 plt.show() #显示绘图
梯度下降,迭代数次后,损失函数趋于最小,110左右。
散点图的拟合直线如下所示:
控制台输出的损失函数相对于最小二乘法稍大,即误差稍大。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。