【机器学习基础】线性回归和梯度下降的初学者教程
作者 | Lily Chen?
編譯 | VK?
來源 | Towards Data Science
假設我們有一個虛擬的數據集,一對變量,一個母親和她女兒的身高:
考慮到另一位母親的身高為63,我們如何預測她女兒的身高?
方法是用線性回歸。
首先,找到最合適的直線。然后用這條直線做預測。
?線性回歸是尋找數據集的最佳擬合線。這條線可以用來做預測。
?「你如何找到最合適的?」
這就是使用梯度下降的原因。
?梯度下降是一種找到最佳擬合線的工具
?在深入研究梯度下降之前,讓我們先看看另一種計算最佳擬合線的方法。
「最佳擬合線的統計計算方法:」
直線可以用公式表示:y=mx+b。
回歸線斜率m的公式為:
m = r * (SD of y / SD of x)
轉換:x和y值之間的相關系數(r),乘以y值的標準差(SD of y)除以x值的標準偏差(SD of x)。
以上數據中母親身高的標準差約為4.07。女兒身高的標準偏差約為5.5。這兩組變量之間的相關系數約為0.89。
因此,最佳擬合線或回歸線為:
y?=?0.89*(5.5?/?4.07)x?+?b y?=?1.2x?+?b我們知道回歸線穿過了平均點,所以線上的一個點是(x值的平均值,y值的平均值),其中有(63.5,63.33)
63.33?=?1.2*63.5?+?b b?=?-12.87因此,使用相關系數和標準差計算的回歸線近似為:
y?=?1.2x?-?12.87使用統計學的回歸線為y=1.2x-12.87
現在,讓我們來研究梯度下降。
「計算最佳擬合線的梯度下降法:」
在梯度下降中,你從一條隨機線開始。然后一點一點地改變直線的參數(即斜率和y軸截距),以得到最佳擬合的直線。
你怎么知道你什么時候到達最合適的位置?
對于你嘗試的每一條直線——直線A、直線B、直線C等等——你都要計算誤差的平方和。如果直線B的值比直線A的誤差小,那么直線B更適合,等等。
誤差是你的實際值減去你的預測值。最佳擬合線使所有誤差平方和最小化。在線性回歸中,我們用相關系數計算出的最佳擬合線也恰好是最小平方誤差線。這就是回歸線被稱為最小二乘回歸線的原因。
?最佳擬合線是最小二乘回歸線
?在下面的圖像中,直線C比直線B更適合,直線B比直線A更適合。
這就是梯度下降的工作原理:
你從一條隨機線開始,比如說直線a,你計算這條線的誤差平方和。然后,調整斜率和y軸截距。重新計算新行的誤差平方和。繼續調整,直到達到局部最小值,其中平方誤差之和最小。
?梯度下降法是一種通過多次迭代最小化誤差平方和來逼近最小平方回歸線的算法。
?梯度下降算法
在機器學習術語中,誤差平方和稱為“成本”。這個成本公式是:
其中
因此,這個方程大致是“誤差平方和”,因為它計算的是預測值減去實際值平方的總和。
1/2m是“平均”數據點數量的平方誤差,這樣數據點的數量就不會影響函數。為什么除以2請看這個解釋(https://datascience.stackexchange.com/questions/52157/why-do-we-have-to-divide-by-2-in-the-ml-squared-error-cost-function)。
在梯度下降中,目標是使代價函數最小化。我們通過嘗試不同的斜率和截距值來實現這一點。但是應該嘗試哪些值以及如何改變這些值?
我們根據梯度下降公式改變它們的值,這個公式來自于對代價函數的偏導數。確切的數學公式可以在這個鏈接中找到:https://www.ritchieng.com/one-variable-linear-regression/
通過偏導數,得到:
這個公式計算每次迭代時θ的變化量。
α(α)被稱為學習率。學習率決定了每次迭代的步驟有多大。有一個好的學習率是非常重要的,因為如果它太大,你的算法不會達到最小值,如果它太小,你的算法會花很長時間才能達到。對于我的例子,我選擇alpha為0.001
總而言之,步驟如下:
估計θ
計算成本
調整θ
重復2和3,直到你達到收斂。
這是我使用梯度下降實現簡單線性回歸的方法。
斜率和截距都是0,0。
注:在機器學習中,我們使用θ來表示向量[y-截距,斜率]。θ=y軸截距。θ1=斜率。這就是為什么在下面的實現中將theta看作變量名。
#?x?=?[58,?62,?60,?64,?67,?70]?#?媽媽的身高 #?y?=?[60,?60,?58,?60,?70,?72]?#?女兒的身高class?LinearRegression:def?__init__(self,?x_set,?y_set):self.x_set?=?x_setself.y_set?=?y_setself.alpha?=?0.0001??#?alpha?是學習率def?get_theta(self,?theta):intercept,?slope?=?thetaintercept_gradient?=?0slope_gradient?=?0m?=?len(self.y_set)for?i?in?range(0,?len(self.y_set)):x_val?=?self.x_set[i]y_val?=?self.y_set[i]y_predicted?=?self.get_prediction(slope,?intercept,?x_val)intercept_gradient?+=?(y_predicted?-?y_val)slope_gradient?+=?(y_predicted?-?y_val)?*?x_valnew_intercept?=?intercept?-?self.alpha?*?intercept_gradientnew_slope?=?slope?-?self.alpha?*?(1/m)?*?slope_gradientreturn?[new_intercept,?new_slope]def?get_prediction(self,?slope,?intercept,?x_val):return?slope?*?x_val?+?interceptdef?calc_cost(self,?theta):intercept,?slope?=?thetasum?=?0for?i?in?range(0,?len(self.y_set)):x_val?=?self.x_set[i]y_val?=?self.y_set[i]y_predicted?=?self.get_prediction(slope,?intercept,?x_val)diff_sq?=?(y_predicted?-?y_val)?**?2sum?+=?diff_sqcost?=?sum?/?(2*len(self.y_set))return?costdef?iterate(self):num_iteration?=?0current_cost?=?Nonecurrent_theta?=?[0,?0]??#?初始化為0while?num_iteration?<?500:if?num_iteration?%?10?==?0:print('current?iteration:?',?num_iteration)print('current?cost:?',?current_cost)print('current?theta:?',?current_theta)new_cost?=?self.calc_cost(current_theta)current_cost?=?new_costnew_theta?=?self.get_theta(current_theta)current_theta?=?new_thetanum_iteration?+=?1print(f'After?{num_iteration},?total?cost?is?{current_cost}.?Theta?is?{current_theta}')使用這個算法和上面的母女身高數據集,經過500次迭代,我得到了3.4的成本。
500次迭代后的方程為y=0.998x+0.078。實際回歸線為y=1.2x-12.87,成本約為3.1。
用[0,0]作為[y-截距,斜率]的初始值,得到y=1.2x-12.87是不切實際的。為了在沒有大量迭代的情況下接近這個目標,你必須從一個更好的初始值開始。
例如,[-10,1]在不到10次迭代后,大約得到y=1.153x-10,成本為3.1。
在機器學習領域,調整學習率和初始估計等參數是比較常見的做法。
這就是線性回歸中梯度下降的要點。
?梯度下降法是一種通過多次迭代最小化誤差平方和來逼近最小平方回歸線的算法。
?到目前為止,我已經討論過簡單線性回歸,其中只有1個自變量(即一組x值)。理論上,梯度下降可以處理n個變量。
我已經重構了我以前的算法來處理下面的n個維度。
import?numpy?as?npclass?LinearRegression:def?__init__(self,?dataset):self.dataset?=?datasetself.alpha?=?0.0001??#?alpha?是學習率def?get_theta(self,?theta):num_params?=?len(self.dataset[0])new_gradients?=?[0]?*?num_paramsm?=?len(self.dataset)for?i?in?range(0,?len(self.dataset)):predicted?=?self.get_prediction(theta,?self.dataset[i])actual?=?self.dataset[i][-1]for?j?in?range(0,?num_params):x_j?=?1?if?j?==?0?else?self.dataset[i][j?-?1]new_gradients[j]?+=?(predicted?-?actual)?*?x_jnew_theta?=?[0]?*?num_paramsfor?j?in?range(0,?num_params):new_theta[j]?=?theta[j]?-?self.alpha?*?(1/m)?*?new_gradients[j]return?new_thetadef?get_prediction(self,?theta,?data_point):#?使用點乘#?y?=?mx?+?b?可以重寫為?[b?m]?dot?[1?x]#?[b?m]?是參數#?代入x的值values?=?[0]*len(data_point)for?i?in?range(0,?len(values)):values[i]?=?1?if?i?==?0?else?data_point[i-1]prediction?=?np.dot(theta,?values)return?predictiondef?calc_cost(self,?theta):sum?=?0for?i?in?range(0,?len(self.dataset)):predicted?=?self.get_prediction(theta,?self.dataset[i])actual?=?self.dataset[i][-1]diff_sq?=?(predicted?-?actual)?**?2sum?+=?diff_sqcost?=?sum?/?(2*len(self.dataset))return?costdef?iterate(self):num_iteration?=?0current_cost?=?Nonecurrent_theta?=?[0]?*?len(self.dataset[0])??#?initialize?to?0while?num_iteration?<?500:if?num_iteration?%?10?==?0:print('current?iteration:?',?num_iteration)print('current?cost:?',?current_cost)print('current?theta:?',?current_theta)new_cost?=?self.calc_cost(current_theta)current_cost?=?new_costnew_theta?=?self.get_theta(current_theta)current_theta?=?new_thetanum_iteration?+=?1print(f'After?{num_iteration},?total?cost?is?{current_cost}.?Theta?is?{current_theta}')一切都是一樣的,唯一的例外是不用mx+b(即斜率乘以變量x加y截距)來獲得預測值,而是進行矩陣乘法。參見上述的def get_prediction。
使用點積,你的算法可以接受n個變量來計算預測。
往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習及深度學習筆記等資料打印機器學習在線手冊深度學習筆記專輯《統計學習方法》的代碼復現專輯 AI基礎下載機器學習的數學基礎專輯 獲取本站知識星球優惠券,復制鏈接直接打開: https://t.zsxq.com/qFiUFMV 本站qq群704220115。加入微信群請掃碼:總結
以上是生活随笔為你收集整理的【机器学习基础】线性回归和梯度下降的初学者教程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Win7系统无法复制粘贴怎么解决
- 下一篇: 【数据分析】2020年创业公司到底过得怎