梯度下降法是機器學習算法更新模型參數的常用的方法之一。
相關概念
梯度 : 表示某一函數在一點處變化率最快的方向向量(可理解爲這點的導數/偏導數)
樣本 : 實際觀測到的數據集,包括輸入和輸出(本文的樣本數量用 m 表述,元素下標 i 表示)
特徵 : 樣本的輸入(本文的特徵數量用 n 表示,元素下標 j 表示)
假設函數 : 用來擬合樣本的函數,記爲 $ h_θ(X) (θ 爲參數向量, X 爲特徵向量)$
代價函數 : 用於評估模型擬合的程度,訓練的目標是最小化代價函數,記爲 通過代價函數使得假設函數更好的擬合給定數據
線性假設函數 :
$ h_θ(X) = θ_0 + θ_1x_1 + θ_2x_2 + …+ θ_nx_n = \sum_j^{n} θ_jx_j$
經典的均方差損失函數;:
$ y_i是樣本輸出的第i個元素,h_{\theta}(X_i)是假設函數$
注意:輸入有多個特徵時,一個樣本特徵是一個向量。假設函數的輸入是一個特徵向量而不是特徵向量裏面的一個元素
梯度下降法
梯度下降法的目標是通過合理的方法更新假設函數
步驟如下:
1.根據經驗設計假設函數和代價函數,設置的初始值
2.對代價函數求所有的
3.使用假設樣本更新假設函數 ,梯度下降的公式爲
其中爲更新步長(學習率,需要調整學習率的靈敏度,學習率很小會導致收斂很慢,迭代次數需要很多;如果學習速率很大可能會發生振盪,導致無法收斂)
過程推導
線性迴歸的假設函數如下:
$ h_θ(X) = θ_0 + θ_1x_1 + θ_2x_2 + …+ θ_nx_n = \sum_j^{n} θ_jx_j$
假設函數如下:
$ \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$
=
表示第i個樣本的第j個特徵
對於假設函數依據梯度下降公式如下:
使用所有樣本作爲輸入重複執行上述過程,直到代價函數的值滿足要求爲止。
例子:根據房屋的面積和房屋數來預測房價
PS:這裏採用批處理梯度下降法,還有有種叫做隨機梯度下降法。
批處理梯度下降需要的運算成本高,因爲每一個的更新都要用到所有樣本的均方誤差,會導致計算量增大。
而隨機梯度下每次只是用一個樣本數據進行更新,(這個以後在說)
這裏只附上最基礎的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))
關於正規方程求
先上結論:
關於正規方程的證明: 其實需要用到矩陣的求導公式,對於上面提到過的代價函數 因爲假設函數得到的值和y都是列向量,所以上式就可以化爲:
然後通過矩陣求導去極小值即可證明,證明見:寫的不錯
帶矩陣求導公式
可能還有其他的證明方法吧。這裏不列舉