(一)梯度下降法简介:
梯度下降算法(Gradient Descent Optimization)是迭代法的一种,其背后原理:目标函数关于参数的梯度将是目标函数上升最快的方向。对于最小化优化问题,只需要将参数沿着梯度相反的方向前进一个步长,就可以实现目标函数的下降。这个步长又称为学习速率。在求解机器学习算法的模型参数,即无约束优化问题时,梯度下降(Gradient Descent)是最常采用的方法之一,另一种常用的方法是最小二乘法。在求解损失函数的最小值时,可以通过梯度下降法来一步步地迭代求解,得到最小化的损失函数和模型参数值。反过来,如果我们需要求解损失函数的最大值,这时就需要用梯度上升法来迭代了。在机器学习中,基于基本的梯度下降法发展了两种梯度下降方法,分别为随机梯度下降法和批量梯度下降法。
举一个非常简单的例子,如求函数: 的最小值。
利用梯度下降的方法解题步骤如下:
1、求梯度,
2、向梯度相反的方向移动 ,如下 ,其中, 为步长。如果步长足够小,则可以保证每一次迭代都在减小,但可能导致收敛太慢,如果步长太大,则不能保证每一次迭代都减少,也不能保证收敛。
3、循环迭代步骤2,直到 的值变化到使得 在两次迭代之间的差值足够小,比如0.0000001,也就是说,直到两次迭代计算出来 的基本没有变化,则说明此 已经达到局部最小值了。
4、此时,输出 ,这个 就是使得函数 最小时的 的取值 。
缺点:
1. 靠近极小值时收敛速度减慢。
2. 可能会“之字形”地下降。
优点:样本数目很大时,梯度下降法优势明显。
(二)实现原理代码(参考《机器学习实战》):
from numpy import *
def loadDataSet():
dataMat =[]; labelMat = []
fr =open('testSet.txt')
for line infr.readlines():
lineArr= line.strip().split()
dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])
labelMat.append(int(lineArr[2]))
returndataMat,labelMat
def gradAscent(dataMatIn, classLabels):
dataMatrix = mat(dataMatIn)
#convert to NumPy matrix
labelMat =mat(classLabels).transpose() #convert to NumPy matrix
m,n =shape(dataMatrix)
alpha =0.001
maxCycles =500
weights =ones((n,1))
for k in range(maxCycles):
#heavy on matrix operations
h =sigmoid(dataMatrix*weights) #matrixmult
error =(labelMat - h) #vectorsubtraction
weights= weights + alpha * dataMatrix.transpose()* error
return weights
(二)sklearn中梯队下降法应用举例:
(1)、SGD对于数据的缩放很敏感,所以首先使用sklearn.preprocessing模块对数据进行缩放(scale)处理。
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)
(2)、通过sklearn.grid_search.GridSearchCV进行交叉验证参数设置,这样可以针对当前样本数据取得最佳值。
大致过程如下:
from sklearn import grid_search
from sklearn.linear_model import SGDClassifier
parameters={'alpha’:[0.01,0.1,1,10]}
sgd=SGDClassifier()
clf=grid_search.GridSearchCV(sgd,parameters)
clf.fit(iris.data,iris.target)
得到的模型clf即可用于对新数据进行分类。
(3)、通过大量试验得知,SGD分类器模型一般在对10^6个样本数据进行计算后收敛,所以对于迭代次数设置时,可以为取10**6/n,其中n是训练数据集样本数目。