Python機(jī)器學(xué)習(xí)之隨機(jī)梯度下降法的實(shí)現(xiàn)
隨機(jī)梯度下降法
為什么使用隨機(jī)梯度下降法?
如果當(dāng)我們數(shù)據(jù)量和樣本量非常大時(shí),每一項(xiàng)都要參與到梯度下降,那么它的計(jì)算量時(shí)非常大的,所以我們可以采用隨機(jī)梯度下降法。
隨機(jī)梯度下降法中的學(xué)習(xí)率必須是隨著循環(huán)的次數(shù)增加而遞減的。如果eta取一樣的話有可能在非常接近我們的最優(yōu)值時(shí)會(huì)跳過,所以隨著迭代次數(shù)的增加,學(xué)習(xí)率eta要隨之減小,我們可以用模擬退火的思想實(shí)現(xiàn)(如下圖所示),t0和t1是一個(gè)常數(shù),定值,其通常是根據(jù)經(jīng)驗(yàn)取得一些值。
隨機(jī)梯度下降法的實(shí)現(xiàn)
隨機(jī)梯度下降法的公式如下圖所示,其中挑出一個(gè)樣本出來計(jì)算。
先創(chuàng)建x,y,以下取10000個(gè)樣本
import numpy as np m = 10000 x = np.random.random(size=m) y = x*3 + 4 + np.random.normal(size=m)
寫入函數(shù)
def dj_sgd(theta, x_i, y_i): # 傳入一個(gè)樣本,獲取對(duì)應(yīng)的梯度 return x_i.T.dot(x_i.dot(theta)-y_i)*2 # MSE def sgd(X_b, y, initial_theta, n_iters): # 求出整個(gè)theta的函數(shù) def learning_rate(i_iter): t0 = 5 t1 = 50 return t0/(i_iter+t1) theta = initial_theta i_iter = 1 while i_iter <= n_iters: index = np.random.randint(0, len(X_b)) x_i = X_b[index] y_i = y[index] gradient = dj_sgd(theta, x_i, y_i) # 求導(dǎo)數(shù) theta = theta - gradient*learning_rate(i_iter) # 求步長(zhǎng) i_iter += 1 return theta
調(diào)用函數(shù),求出截距和系數(shù)
以上隨機(jī)梯度的缺點(diǎn)是不能照顧到每一點(diǎn),因此需要進(jìn)行改進(jìn)。
以下對(duì)其中的函數(shù)進(jìn)行修改。
def dj_sgd(theta, x_i, y_i): # 傳入一個(gè)樣本,獲取對(duì)應(yīng)的梯度 return x_i.T.dot(x_i.dot(theta)-y_i)*2 # MSE def sgd(X_b, y, initial_theta, n_iters): # 求出整個(gè)theta的函數(shù) def learning_rate(i_iter): t0 = 5 t1 = 50 return t0/(i_iter+t1) theta = initial_theta m = len(X_b) for cur_iter in range(n_iters): # 每一次循環(huán)都把樣本打亂,n_iters的代表整個(gè)樣本看幾輪 random_indexs = np.random.permutation(m) X_random = X_b[random_indexs] y_random = y[random_indexs] for i in range(m): theta = theta - learning_rate(cur_iter*m+i) * (dj_sgd(theta, X_random[i], y_random[i])) return theta
與前邊運(yùn)算結(jié)果進(jìn)行對(duì)比,其耗時(shí)更長(zhǎng)。
到此這篇關(guān)于Python機(jī)器學(xué)習(xí)之隨機(jī)梯度下降法的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Python隨機(jī)梯度下降法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python3 json數(shù)據(jù)格式的轉(zhuǎn)換(dumps/loads的使用、dict to str/str to dict、j
JSON (JavaScript Object Notation) 是一種輕量級(jí)的數(shù)據(jù)交換格式。它基于ECMAScript的一個(gè)子集。這篇文章主要介紹了python3 json數(shù)據(jù)格式的轉(zhuǎn)換(dumps/loads的使用、dict to str/str to dict、json字符串/字典的相互轉(zhuǎn)換) ,需要的朋友可以參考下2019-04-04Python Process多進(jìn)程實(shí)現(xiàn)過程
這篇文章主要介紹了Python Process多進(jìn)程實(shí)現(xiàn)過程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10Python讀取多列數(shù)據(jù)以及用matplotlib制作圖表方法實(shí)例
這篇文章主要給大家介紹了關(guān)于Python讀取多列數(shù)據(jù)以及用matplotlib制作圖表的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09Python實(shí)現(xiàn)小數(shù)轉(zhuǎn)化為百分?jǐn)?shù)的格式化輸出方法示例
這篇文章主要介紹了Python實(shí)現(xiàn)小數(shù)轉(zhuǎn)化為百分?jǐn)?shù)的格式化輸出方法,結(jié)合具體實(shí)例形式分析了Python實(shí)現(xiàn)小數(shù)轉(zhuǎn)換為百分?jǐn)?shù)輸出的相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2017-09-09