A--python梯度下降算法实践
In [1]:
import numpy as np import pandas as pd import matplotlib import matplotlib.pyplot as plt %matplotlib inline
In [ ]:
w=w-a*x.T(X*W-Y)/M
In [4]:
#参数分别为 数据集 学习率(步长) 简单粗暴的设置最高迭代次数 def gradDescent_0(dataSet,eps=0.01,numIt=50000): xMat = np.mat(dataSet.iloc[:, :-1].values)#分别为截取 x与y 放到矩阵(matrix)中 yMat = np.mat(dataSet.iloc[:, -1].values).T xMat = regularize(xMat) #分别对X 与Y 进行归一化 yMat = regularize(yMat) m,n = xMat.shape weights = np.zeros((n,1)) #设我们的初始系数(权重) B=0 for k in range(numIt): #迭代次数 grad = xMat.T * (xMat * weights - yMat) / m #计算梯度 B= weights = weights - eps * grad#更新权重 return weights
In [7]:
aba = pd.read_table('abalone.txt', header = None)#该数据集源于UCI,记录了鲍⻥的⽣物属性,⽬标字段是该⽣物的年龄 aba.head()
Out[7]:
In [8]:
aba.shape
Out[8]:
In [12]:
aba.tail()
Out[12]:
In [13]:
aba.info()
In [29]:
aba[1].isnull().value_counts()
Out[29]:
In [30]:
#计算
2
gradDescent_0(aba,eps=0.01,numIt=5000)
Out[30]:
In [31]:
#用最小二乘得出结论以对比结果 xMat = np.mat(aba.iloc[:, :-1].values) yMat = np.mat(aba.iloc[:, -1].values).T xMat = regularize(xMat) yMat = regularize(yMat) xTx = xMat.T*xMat ws = xTx.I * (xMat.T*yMat) ws
Out[31]:
In [32]:
aba[0].mean()
Out[32]:
In [34]:
weights = np.zeros((9,1))
weights
Out[34]:
SGD随机梯度下降法
随机梯度下降法,其实和批量梯度下降法原理类似,区别在与求梯度时没有⽤所有的m个样本的数据,⽽是仅仅选取⼀个样本j来求梯度。
另:由于是随机抽取一部分做梯度,随机性太强,所以最好加大迭代次数到6为数左右
又:由于随机梯度下降输出系数随机性较大,所以不适合用来解线性回归
In [39]:
#可见基本操作都是一样的,区别在于我们对数据集进行了有放回抽样 def gradDescent_1(dataSet,eps=0.01,numIt=500000): dataSet = dataSet.sample(numIt, replace=True)#sample函数进行随机抽样多少次,参数 replace=True 表示 是有放回的 dataSet.index = range(dataSet.shape[0])#对index 进行规整化 xMat = np.mat(dataSet.iloc[:, :-1].values) yMat = np.mat(dataSet.iloc[:, -1].values).T xMat = regularize(xMat) yMat = regularize(yMat) m, n = xMat.shape weights = np.zeros((n,1)) for i in range(m): #迭代次数 grad = xMat[i].T * (xMat[i] * weights - yMat[i])#这里每次计算梯度时 只选取一条 weights = weights - eps * grad return weights
In [42]:
import time %time gradDescent_1(aba)#几次计算的系数均不一致,是因为结果本身就是一个解空间,最终sse 可能差别不大
Out[42]:
In [ ]:
def sseCal(dataSet, regres):#设置参数为 数据集 与 回归方法 n = dataSet.shape[0] y = dataSet.iloc[:, -1].values ws = regres(dataSet) yhat = dataSet.iloc[:, :-1].values * ws yhat = yhat.reshape([n,]) rss = np.power(yhat - y, 2).sum() return rss
In [45]:
%%time n=aba.shape[0] y=aba.iloc[:,-1].values ws=gradDescent_1(aba) yhat=aba.iloc[:,:-1].values * ws yhat=yhat.reshape([n,]) rss = np.power(yhat - y, 2).sum() rss Wall time: 46.9 s
In [46]:
rss
Out[46]:
In [48]:
#封装R**2 def rSquare(dataSet, regres):#设置参数为 数据集 与 回归方法 sse = sseCal(dataSet, regres) y = dataSet.iloc[:, -1].values sst = np.power(y - y.mean(), 2).sum() return 1 - sse / sst
In [49]:
rSquare(aba, gradDescent_1)
Out[49]: