梯度下降原理及代碼實現,以及正規方程解法+二者的比較

梯度下降法是機器學習算法更新模型參數的常用的方法之一。

相關概念
梯度 : 表示某一函數在一點處變化率最快的方向向量(可理解爲這點的導數/偏導數)
樣本 : 實際觀測到的數據集,包括輸入和輸出(本文的樣本數量用 m 表述,元素下標 i 表示)
特徵 : 樣本的輸入(本文的特徵數量用 n 表示,元素下標 j 表示)
假設函數 : 用來擬合樣本的函數,記爲 $ h_θ(X) (θ 爲參數向量, X 爲特徵向量)$
代價函數 : 用於評估模型擬合的程度,訓練的目標是最小化代價函數,記爲 J(θ)J(θ) 通過代價函數使得假設函數更好的擬合給定數據
線性假設函數 :
$ h_θ(X) = θ_0 + θ_1x_1 + θ_2x_2 + …+ θ_nx_n = \sum_j^{n} θ_jx_j$
X,θjxjj(x0=1)其中 X 爲特徵向量, θ_j爲模型參數, x_j 是特徵向量的第 j 個元素(令x_0=1)。
經典的均方差損失函數;:
J(θ)=12mi=1m(hθ(Xi)yi)2J(\theta) = \frac{1}{2m}\sum_{i=1}^{m}(h_{\theta}(X_i) - y_i)^2
m,Xii()其中m爲樣本個數,X_i 爲樣本的特徵集合的第i個元素(是一個向量),
$ y_i是樣本輸出的第i個元素,h_{\theta}(X_i)是假設函數$
注意:輸入有多個特徵時,一個樣本特徵是一個向量。假設函數的輸入是一個特徵向量而不是特徵向量裏面的一個元素

梯度下降法
梯度下降法的目標是通過合理的方法更新假設函數h(θ)θ使J(θ)h_(\theta) 的參數 \theta 使得代價函數J(\theta)對於所有樣本最小

步驟如下:
1.根據經驗設計假設函數和代價函數,設置θ\theta的初始值
2.對代價函數求所有的θ:J(θ)θj\theta 的偏導數(梯度) : \frac{\partial J(\theta)}{\partial \theta_j}
3.使用假設樣本更新假設函數θ\theta ,梯度下降的公式爲 θj=θjαJ(θ)θj\theta_j = \theta_j - \alpha \frac{\partial J(\theta)}{\partial \theta_j}

其中α\alpha爲更新步長(學習率,需要調整學習率的靈敏度,學習率很小會導致收斂很慢,迭代次數需要很多;如果學習速率很大可能會發生振盪,導致無法收斂)

過程推導
線性迴歸的假設函數如下:
$ h_θ(X) = θ_0 + θ_1x_1 + θ_2x_2 + …+ θ_nx_n = \sum_j^{n} θ_jx_j$
X,θjxjj(x0=1)其中 X 爲特徵向量, θ_j爲模型參數, x_j 是特徵向量的第 j 個元素(令x_0=1)。
假設函數如下:
J(θ)=12mi=1m(hθ(Xi)yi)2J(\theta) = \frac{1}{2m}\sum_{i=1}^{m}(h_{\theta}(X_i) - y_i)^2 12)(\frac{1}{2} 是爲了後面求導時抵消,對數據擬合無影響)
θ:代價函數對\theta求偏導:
$ \frac{\partial J(\theta)}{\partial \theta_j} = \frac{\partial }{\partial \theta_j} \frac{1}{2m} \sum_{i = 1}{m}(h_{\theta}(X{(i)}) - y{(i)})2$
$ = \frac{\partial }{\partial \theta_j} {2} \frac{1}{2m} \sum_{i = 1}{m}(h_{\theta}(X{(i)}) - y^{(i)}) x_j$
=1mi=1m(hθ(X(i))y(i))xj\frac{1}{m}\sum_{i = 1}^{m} (h_{\theta}(X^{(i)}) - y^{(i)})x_j
Xj(i)X_j^{(i)}表示第i個樣本的第j個特徵
對於假設函數θ\theta依據梯度下降公式如下:
θj=θjα1mi=1m(hθ(X(i))y(i))xj\theta_j = \theta_j - \alpha \frac{1}{m}\sum_{i = 1}^{m} (h_{\theta}(X^{(i)}) - y^{(i)})x_j
使用所有樣本作爲輸入重複執行上述過程,直到代價函數的值滿足要求爲止。

例子:根據房屋的面積和房屋數來預測房價
PS:這裏採用批處理梯度下降法,還有有種叫做隨機梯度下降法。
批處理梯度下降需要的運算成本高,因爲每一個θ\theta的更新都要用到所有樣本的均方誤差,會導致計算量增大。
而隨機梯度下每次只是用一個樣本數據進行更新,(這個以後在說)

具體可以看這個簡書
還有這個

這裏只附上最基礎的python代碼:


import numpy as np
import random
from numpy import genfromtxt
import matplotlib.pyplot as plt

def getData(dataset):
	m,n = np.shape(dataset)
	trainData = np.ones((m,n))
	trainData[:,:-1] = dataset[:,:-1]
	trainLabel = dataset[:,-1]
	return trainData,trainLabel
	
def GradientDescent(x,y,theta,alpha,m,maxIterations):
	xTrains = x.transpose()
	for i in range(maxIterations):
		hypothesis = np.dot(x,theta)
		loss = hypothesis - y
		gradient = np.dot(xTrains,loss) / m
		theta = theta - alpha * gradient
	return theta
	
def prediect(x,theta):
	m,n = np.shape(x)
	xTest = np.ones((m,n + 1))
	xTest[:,:-1] = x
	yP = np.dot(xTest,theta)
	return yP
	
	
datapath = r'G:\\DATA\house.csv'

''' genfromtxt 讀取文件信息,用來處理數據信息
	np.genfromtxt("",delimiter = '',dtype = '')
	delimiter 分隔符
	dtype 獲取數據類型
'''
dataset = genfromtxt(datapath,delimiter = ',')
trainData ,trainLabel = getData(dataset)

'''np.shape() 查看矩陣或數組的維度'''

m,n = np.shape(trainData)
print(m)
print(n)
theta = np.ones(n) # 初始化theta
alpha = 0.1 # 可以選擇不同的學習率,然後畫出theta~J(theta)
找一個相對好的,0.001..0.003 0.1 0.3 ...
maxIterations = 5000 # 最大迭代次數
#根據給定的數據用線性迴歸擬合數據,採用均方差值來衡量
theta = GradientDescent(trainData,trainLabel,theta,alpha,m,
maxIterations)
# 要預測的數據
x = np.array([[3.1, 5.5], [3.3, 5.9], [3.5, 6.3], 
[3.7, 6.7], [3.9, 7.1]])
print(prediect(x,theta))

關於正規方程求θ\theta

先上結論:
θ=XTX)1XTY\theta = (X^TX)^{-1}X^TY

關於正規方程的證明: 其實需要用到矩陣的求導公式,對於上面提到過的代價函數J(θ)J(\theta) 因爲假設函數得到的值和y都是列向量,所以上式就可以化爲:
J(θ)=(hθ(X)y)T(hθ(X)y)J(\theta) = (h_{\theta}(X) - y)^T(h_{\theta}(X) - y)然後通過矩陣求導去極小值即可證明,證明見:寫的不錯
帶矩陣求導公式
可能還有其他的證明方法吧。這裏不列舉

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章