线性回归模型算法原理及Python实现
文章內容主要來自Aurelien Geron《Hands-on Machine Learning withi Scikit-Learn&TensorFlow》
目錄
線性回歸方程
參數求解方法一:標準方程
手動求解線性回歸方程
使用sklearn計算線性回歸方程
參數求解方法二:梯度下降
學習率
梯度下降陷阱
梯度下降特征縮放問題
批量梯度下降(batch gradient descent)
隨機梯度下降方法(Stochastic Gradient Descent,SGD)
Python手動實現隨機梯度下降
使用sk-learn 實現隨機梯度下降
小批量梯度下降(mini batch)
線性回歸求解方法比較
線性回歸方程
線性回歸模型的一般表達式:
轉換為向量表達形式為:
訓練線性回歸模型,主要是得到一組向量,使得均方誤差MSE(成本函數)最小
參數求解方法一:標準方程
MSE為凸函數,有唯一最優解(最小值),為了求解,可以令MSE對求偏導數為0,得到解:
手動求解線性回歸方程
現在我們來使用標準方程計算:
import numpy as npX = 2 * np.random.rand(100, 1) # 生存100 X 1維向量(均勻分布隨機數) y = 4 + 3 * X + np.random.randn(100, 1) # 生存100 X 1維向量(正態分布隨機數)# 使用np.linalg中對inv()求逆矩陣,使用dot()方法計算矩陣對內積 X_b = np.c_[np.ones((100, 1)), X] # add x0 = 1 to each instance # X_b為X加上一個常數項 theta_best = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y)>>>theta_best array([[4.21509616],[2.77011339]])我們期待的是theta_0=4, theta_1=3,得到 theta_0=3.865,theta_1=3.139, 非常接近,噪音的存在使得其不可能還原為原函數可以 使用theta進行預測X_new = np.array([[0], [2]]) # X取0,2進行預測y X_new_b = np.c_[np.ones((2, 1)), X_new] # add x0 = 1 to each instance y_predict = X_new_b.dot(theta_best) y_predict array([[4.21509616],[9.75532293]])繪制模型的預測結果:
plt.plot(X_new, y_predict, "r-") plt.plot(X, y, "b.") plt.axis([0, 2, 0, 15]) plt.show()使用sklearn計算線性回歸方程
>>>from sklearn.linear_model import LinearRegression >>>lin_reg = LinearRegression() >>>lin_reg.fit(X, y) >>>lin_reg.intercept_, lin_reg.coef_ # 線性回歸方程參數 (array([4.21509616]), array([[2.77011339]]))>>>lin_reg.predict(X_new) array([[4.21509616],[9.75532293]])標準方程求解的問題
標準方程求解需要求解逆矩陣,但并不是所有的矩陣都有逆矩陣,比如奇異矩陣,矩陣不可逆,其原因主要有兩個方面:
1. 部分特征線性相關,這種情況下,可以考慮刪除部分冗余特征
2. 特征數量大于樣本數量(這種情況不一定會導致矩陣不可逆,但肯能會導致不可逆)
對于矩陣不可逆的情況,可以用“偽逆矩陣” 替代“逆矩陣”,通常可以得到解的結果。
參數求解方法二:梯度下降
梯度下降是一種非常通用的優化算法,能夠為大范圍的問題找到最優解。梯度下降的中心思想就是迭代地調整參數從而使得成本函數最小化。
具體的來說,首先使用一個隨機的值(這稱為隨機初始化),然后逐步改進,每次踏出一小步,每一步都嘗試降低一點成本函數,直到算法收斂出一個最小值
學習率
梯度下降的一個重要參數是每一步的步長,取決于學習率。如果學習率太低,算法需要經過大量的迭代才能收斂,這將耗費很長的時間,如果學習率太高,可能會越過山谷到達山的另一邊,甚至可能比之前的起點還要高,會導致算法發散。
梯度下降陷阱
并不是所有的成本函數都是一個凸函數(形狀看起來像個碗),可能是不規則形狀如圖,這樣隨機梯度下降方法存在兩個主要挑戰:
1. 如果隨機初始化算法從左側起步,容易收斂到局部最小值而非全局最小值;
2. 如果算法從右側起步,那么需要經過很長都時間才能越過整片高原,如果停下來太早,將達不到全局最小。
但線性回歸模型但MSE是凸函數,也就是說不存在局部最小,只有全局最小,這對使用梯度下降求解線性回歸方程非常有保障。
梯度下降特征縮放問題
如果不同特征對尺寸差別巨大,可能會造成收斂對時間大大增加。比如右邊訓練集特征1比特征2小得多,梯度下降先是沿著全局最小對方向垂直前進,接下來是一段近乎平坦的長長的山谷,這段算法收斂需要大量時間。所以,在運用梯度下降時,需要保證所有特征值比例都差不多(可使用scikit-learn的StandardScaler)
批量梯度下降(batch gradient descent)
每一步計算梯度下降都使用完整的訓練集X進行計算,這導致在訓練集樣本很大時變得很慢。
要實現梯度下降,需要計算模型關于參數成本函數的梯度,成本函數的偏導數:
也可以寫出梯度向量的方式:
則每一個梯度的步長為:
其中η為學習率。
eta = 0.1 n_iterations = 1000 m = 100 theta = np.random.randn(2,1)for iteration in range(n_iterations):gradients = 2/m * X_b.T.dot(X_b.dot(theta) - y) # 成本函數的梯度公式theta = theta - eta * gradients # theta與學習率關系公式>>>theta array([[4.21509616],[2.77011339]])可以看出,比較容易求出來theta值。
不同學習率η,梯度下降前10步的線性回歸函數(theta值)
說明:左圖學習率低,需要較長時間;中圖學習率合適,很快算法就收斂;由于學習率太大,算法發散,直接跳過來數據區域,并且離實際解越來越遠。
隨機梯度下降方法(Stochastic Gradient Descent,SGD)
當訓練的數據集非常大時,為了克服批量梯度下降耗時非常長的缺點(因為需要使用全量數據進行訓練),而采用每一步在訓練中隨機選擇一個實例,并且僅基于該實例來計算梯度。這樣計算速度快多了,另一方面,由于實例選擇的隨機性,他比批量下降要不規則得多。成本函數不再是緩慢下降直到抵達最小值,而是不斷上上下下,不斷接近最小值,但是即時達到了最小值,依舊會持續反彈,永遠不會停止。因此,算法停下來參數值肯定是足夠好但,但不是最優。
當成本函數不規則時,隨機梯度但好處是可以逃離局部最優,但缺點永遠定位不出最小值。要解決這個問題,有一個辦法是逐步降低學習率,開始時,步長比較大(有助于快速進展和逃離局部最小),然后越來越小,讓算法盡量靠近全局最小,這個過程也叫模擬退火,因為它類似于冶金時金屬融化后慢慢冷卻但退火過程。
下面這段代碼使用一個簡單的學習計劃實現隨機梯度下降:
Python手動實現隨機梯度下降
# 手動隨機梯度下降 m = len(X_b) n_epochs = 50 t0, t1 = 5, 50 # learning schedule hyperparametersdef learning_schedule(t):return t0 / (t + t1)theta = np.random.randn(2,1) # random initializationfor epoch in range(n_epochs):for i in range(m):#隨機選出一個實例進行梯度計算random_index = np.random.randint(m)xi = X_b[random_index:random_index+1] yi = y[random_index:random_index+1]gradients = 2 * xi.T.dot(xi.dot(theta) - yi)eta = learning_schedule(epoch * m + i)theta = theta - eta * gradients >>>theta array([[4.21076011],[2.74856079]])進行50輪迭代就可以得到不錯的結果,而批量梯度下降要1000次。
使用sk-learn 實現隨機梯度下降
from sklearn.linear_model import SGDRegressor sgd_reg = SGDRegressor(max_iter=50, tol=-np.infty, penalty=None, eta0=0.1, random_state=42) sgd_reg.fit(X, y.ravel())>>>sgd_reg.intercept_, sgd_reg.coef_ (array([4.16782089]), array([2.72603052]))得到跟標準方程近似的解決方案
小批量梯度下降(mini batch)
介于批量梯度下降和隨機梯度下降中間的方法,即每一步梯度的計算,既不是基于整個訓練集,也不是基于單個實例,而是基于一小批隨機的實例集。所以它速度比批量梯度快,且比隨機梯度穩定,但也容易先入局部最優問題。
線性回歸求解方法比較
m為樣本數,n為特征數
| 標準方程 | 梯度下降 | |
| 需要設置參數如學習率 | 不需要 | 需要 |
| 需要很多次迭代 | 不需要 | 需要 |
| 特征數的影響 | n<1000時,一般采用標準方程 | n>10000時,一般采用梯度下降 |
| 樣本數量的影響 | 影響不大 | 影響大,可以采用隨機梯度和小批量梯度加快求解速度 |
總結
以上是生活随笔為你收集整理的线性回归模型算法原理及Python实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 花鸟市场卖的观赏鱼超会赚钱,但背后真相很
- 下一篇: 涨涨涨疯了!特斯拉美国再次上调Model