import numpy as np
def sigmod(z):
return 1/(1+np.exp(-z)
def gradAscent(data,label):
dataMatrix=np.mat(data)
classLabels=mat(label).transpose()
m,n = shape(dataMatrix)
a=0.001 #梯度幅度
maxCycles=500 #迭代次數
weights = ones((n,1))
for i in range(maxCycles):
h=sigmod(dataMatrix*weights)
error = label-h
weight=weight+a*error* dataMatrix.transpose()
return array(weights)
由於處理的數據有不同的量綱和量綱單位,導致不同維度的數據之間尺度差異很大,如下圖(左)所示,目標函數的等高線是橢圓形的。這樣在通過最小化目標函數尋找最優解的過程中,梯度下降法所走的路線是鋸齒狀的,需要經過的迭代次數過多,嚴重影響了算法的效率。
爲了解決這個問題,可以對數據進行歸一化,例如採用min-max標準化將輸入數據範圍統一到[0,1]之間,處理後的結果如上圖(右)所示,經過很少次數的迭代就可以達到目標函數的最低點,極大提高算法的執行效率。
2. 牛頓法
數據歸一化是從數據預處理的角度解決梯度下降法迭代次數過多這個問題的,若從目標函數優化的角度去思考,可以用牛頓法替代梯度下降法,從而提高參數最優值的求解速度。
有n個變量的函數J(θ)J(θ)的一階導數爲:
二階導數(也稱爲Hessian矩陣)爲:
目標函數J(θ)J(θ)的包含二階導數的泰勒展開式爲:
將J(θ+Δθ)J(θ+Δθ)看做ΔθΔθ的函數的話,其最小值在其偏導數等於0處取得:
θ+Δθθ+Δθ是對目標函數取得最小值時參數的一個較好的估計,在牛頓法中會在ΔθΔθ的基礎上乘以一個步長αα(取值小於1,比如0.001)。 使用牛頓法迭代過程爲:
for i in xrange(0, num_passes):
Jprime = X_expand.T.dot(sigmoid(X_expand.dot(theta))-y.reshape(X.shape[0],1))
for j in xrange(0, num_examples):
H_theta = sigmoid(X_expand[j,:].dot(theta))
A[j,j] = H_theta*(1-H_theta) + 0.0001
Jprime2 = X_expand.T.dot(A).dot(X_expand)
delta_theta = np.linalg.solve(Jprime2,Jprime)
delta_theta += reg_lambda*theta
theta += -al*delta_theta
return theta