【Python多元线性回归】梯度下降法实现
梯度下降法是一种非常常用的优化方法(由于介绍该算法的博文很多,我就不对理论细节进行讲解了,原理只是简单的求导,高中生估计都学得会),我们在最开始学习该算法的时候往往是从线性回归开始,算法原理的直观性也吸引着许多爱好编程的同学练手。本文便着手在python环境打造一个简单的梯度下降方法:【你只需要输入df格式的自变量因变量数据、学习率、迭代最大次数阈值和最小误差阈值这几个数据,便可以算出回归系数和截距,真正的懒人福利!!!】
首先给出我的数据集【Real estate valuation data set.csv(点击进入网盘链接下载)】(房价数据相信学习统计机器学习这门课的朋友都不会陌生)
我们的目标是:使用梯度下降法求解回归系数,并完成对房价(Y)的预测
首先来构建方法
import numpy as npimport pandas as pd'''构建一个grad方法用于求梯度构建一个grad_descent方法用于计算回归系数'''def grad(x,y,theta):G=[]x=np.c_[np.ones(x.shape[0]),x]for j in range(len(theta)): # i(维数)固定gi=0for i in range(len(x)):x_ij = x [(i),(j)]y_i = float ( y [i] )theta_0 = float( theta[0] )theta_j = float ( theta[j] )y_hat = theta_0+theta_j*x_ijgi += (y_hat-y_i)*x_ij*(1/len(x))G.append(gi)G=np.array(G)G[np.isnan(G)]=0return(G)def grad_descent(x,y,LearnRate,maxtime,error): # x 和 y 都是 dataFrame格式 i=0x=np.array(x)y=np.array(y)theta=np.random.randint(-1,1,size=(x.shape[1]+1,1))while ( i < maxtime):i+=1theta_old=theta.Tdirect=LearnRate*grad(x,y,theta)theta2=theta.T-directdistant=np.sqrt(np.sum(direct**2)) if distant < error:break theta=theta2.Tprint('迭代次数:%d'%i)print('最后一次迭代误差:%s'%distant)theta[np.isnan(theta)]=0return(theta)
然后导入数据:
data=pd.read_csv('Real estate valuation data set.csv',encoding='utf-8')x=data.iloc[:,0:5] #选取自变量数据y=data.iloc[:,7] #选取因变量数据(房价)Theta=grad_descent(x,y,0.0045,1500,5) #这里设置参数#输出算得的回归系数(第一行为截距,之后为x_1~x_j的回归系数)print(Theta) #运行结果:迭代次数:129最后一次迭代误差:2.391452832764519[[13.02036305][ 0. ][ 0. ][-0.27471118][ 0. ][ 5.00072764]]
最后画图展示拟合效果(随机选择了一个维度)
import matplotlib.pyplot as pltX=pd.DataFrame(np.c_[np.ones(x.shape[0]),x])[4]Y=pd.DataFrame(np.array(data.iloc[:,7]))[0]Y_hat=pd.DataFrame(np.dot(np.c_[np.ones(x.shape[0]),x],Theta))[0]plt.scatter(X,Y)plt.scatter(X,Y_hat)
拟合效果其实不一定好,而且每次拟合的结果也不一定一样(如图),这也是梯度下降法这类数值解法的缺点所在:起始点是随机生成的,所以可能会陷入不同的局部最优点,此外参数的选择不同也会对回归的结果造成影响。
蓝色是原数据,橙色是预测值
鉴于本文的主要目标在于求解,对回归系数的拟合优度检验、显著性检验便不再继续深入。