我感觉这是目前讲得最明白的线性回归的文章了
?Datawhale?
作者:尹曉丹,Datawhale優秀學習者
寄語:本文對線性回歸算法的原理及模型,學習策略、算法求解和sklearn參數做了詳細的講解。同時,用例子進行Python代碼實踐。
線性回歸是利用數理統計中的回歸分析,來確定兩種或兩種以上變量間相互依賴的定量關系的一種統計分析方法,是機器學習最基礎的算法之一。
學習框架
模型建立
線性回歸原理
進入一家房產網,可以看到房價、面積、廳室呈現以下數據:
將價格和面積、廳室數量的關系習得為:
使得, 這就是一個直觀的線性回歸的樣式。
線性回歸模型
1. 線性回歸的一般形式
有數據集,其中,其中表示變量的數量,表示每個變量的維度。
可以用以下函數來描述y和x之間的關系:
如何來確定的值,使得 盡可能接近的值呢?均方誤差是回歸中常用的性能度量,即:
我們可以選擇,試圖讓均方誤差最小化。
2.?極大似然估計(概率角度闡釋)
下面我們用極大似然估計,來解釋為什么要用均方誤差作為性能度量。可以把目標值和變量寫成如下等式:
表示我們未觀測到的變量的印象,即隨機噪音。我們假定是獨立同分布,服從高斯分布。(根據中心極限定理)
因此,
我們建立極大似然函數,即描述數據遵從當前樣本分布的概率分布函數。由于樣本的數據集獨立同分布,因此可以寫成:
選擇 ???? ,使得似然函數最大化,這就是極大似然估計的思想。為了方便計算,我們計算時通常對對數似然函數求最大值:
顯然,最大化即最小化:
這一結果即均方誤差,因此用這個值作為代價函數來優化模型在統計學的角度是合理的。學習策略
1. 損失函數(Loss Function)
度量單樣本預測的錯誤程度,損失函數值越小,模型就越好。常用的損失函數包括:0-1損失函數、平方損失函數、絕對損失函數、對數損失函數等。
2. 代價函數(Cost Function)
度量全部樣本集的平均誤差。常用的代價函數包括均方誤差、均方根誤差、平均絕對誤差等。
3. 目標函數(Object Function)
代價函數和正則化函數,最終要優化的函數。
4. 思考題
既然代價函數已經可以度量樣本集的平均誤差,為什么還要設定目標函數?
答:當模型復雜度增加時,有可能對訓練集可以模擬的很好,但是預測測試集的效果不好,出現過擬合現象,這就出現了所謂的“結構化風險”。結構風險最小化即為了防止過擬合而提出來的策略,定義模型復雜度為 ????(????) ,目標函數可表示為:
例如有以下6個房價和面積關系的數據點,可以看到,當設定:
時,可以完美擬合訓練集數據,但是,真實情況下房價和面積不可能是這樣的關系,出現了過擬合現象。當訓練集本身存在噪聲時,擬合曲線對未知影響因素的擬合往往不是最好的。
通常,隨著模型復雜度的增加,訓練誤差會減少;但測試誤差會先增加后減小。我們的最終目的時試測試誤差達到最小,這就是我們為什么需要選取適合的目標函數的原因。
算法求解
梯度下降法
設定初始參數,不斷迭代,使得最小化:
對其求導為:
即:
將所有的參數以向量形式表示,可得:
由于這個方法中,參數在每一個數據點上同時進行了移動,因此稱為批梯度下降法,對應的,我們可以每一次讓參數只針對一個數據點進行移動,即:這個算法稱為隨機梯度下降法,隨機梯度下降法的好處是,當數據點很多時,運行效率更高;
其缺點是,因為每次只針對一個樣本更新參數,未必找到最快路徑達到最優值,甚至有時候會出現參數在最小值附近徘徊而不是立即收斂。但當數據量很大的時候,隨機梯度下降法經常優于批梯度下降法。
當為凸函數時,梯度下降法相當于讓參數不斷向的最小值位置移動。
梯度下降法的缺陷:如果函數為非凸函數,有可能找到的并非全局最優值,而是局部最優值。
最小二乘法矩陣求解
令:
其中,
由于
且
對于向量來說,有
因此可以把損失函數寫作
為最小化,對求導可得:
中間兩項互為轉置,由于求得的值是個標量,矩陣與轉置相同,因此可以寫成
令偏導數等于零,由于最后一項和 ???? 無關,偏導數為0。因此,
利用矩陣求導性質,
和
令導數等于零,
牛頓法
可求得:
重復迭代,可以讓逼近取到的最小值。當我們對損失函數進行優化的時候,實際上是想要取到的最小值,因此迭代公式為:
當是向量值的時候,
的偏導數,是的海森矩陣,
問題:請用泰勒展開法推導牛頓法公式。
答:將泰勒公式展開到二階:
對上式求導,并令導數等于0,求得值
可以求得,
牛頓法的收斂速度非常快,但海森矩陣的計算較為復雜,尤其當參數的維度很多時,會耗費大量計算成本。我們可以用其他矩陣替代海森矩陣,用擬牛頓法進行估計。
牛頓法比梯度下降法收斂速度更快,紅色的牛頓法的迭代路徑,綠色的是梯度下降法的迭代路徑。
擬牛頓法
常用的擬牛頓法算法包括DFP,BFGS等。擬牛頓法的思路是用一個矩陣替代計算復雜的海森矩陣,因此要找到符合H性質的矩陣。
要求得海森矩陣符合的條件,同樣對泰勒公式求導
即迭代后的值,代入可得:
更一般的,
為第k個迭代值。即找到矩陣,使得它符合上式。
線性回歸的評估指標
均方誤差(MSE):
均方根誤差(RMSE):
平均絕對誤差(MAE):
但以上評價指標都無法消除量綱不一致而導致的誤差值差別大的問題,最常用的指標是,可以避免量綱不一致問題。
我們可以把理解為,回歸模型可以成功解釋的數據方差部分在數據固有方差中所占的比例,越接近1,表示可解釋力度越大,模型擬合的效果越好。
sklearn參數詳解
1. it_intercept
默認為True,是否計算該模型的截距。如果使用中心化的數據,可以考慮設置為False,不考慮截距。一般還是要考慮截距。
2. normalize
默認為false. 當fit_intercept設置為false的時候,這個參數會被自動忽略。如果為True,回歸器會標準化輸入參數:減去平均值,并且除以相應的二范數。當然啦,在這里還是建議將標準化的工作放在訓練模型之前。通過設置sklearn.preprocessing.StandardScaler來實現,而在此處設置為false。
3. copy_X
默認為True, 否則X會被改寫
4. n_jobs
int 默認為1. 當-1時默認使用全部CPUs ??(這個參數有待嘗試)
5.?可用屬性
**coef_????*訓練后的輸入端模型系數,如果label有兩個,即y值有兩列。那么是一個2D的array
6. intercept_: 截距
7. 可用的methods
fit(X,y,sample_weight=None):
X: array, 稀疏矩陣 [n_samples,n_features]
y: array [n_samples, n_targets]
sample_weight: 權重 array [n_samples] 在版本0.17后添加了sample_weight
get_params(deep=True):返回對regressor 的設置值
predict(X): 預測 基于 R^2值
score:評估
練習題
請用以下數據(可自行生成嘗試,或用其他已有數據集)
首先嘗試調用sklearn的線性回歸函數進行訓練;
用最小二乘法的矩陣求解法訓練數據;
用梯度下降法訓練數據;
比較各方法得出的結果是否一致。
1. sklearn的線性回歸
生成數據:
2.?最小二乘法
class LR_LS():def __init__(self):self.w = None def fit(self, X, y):# 最小二乘法矩陣求解#============================= show me your code =======================self.w = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(y)#============================= show me your code =======================def predict(self, X):# 用已經擬合的參數值預測新自變量#============================= show me your code =======================y_pred = X.dot(self.w)#============================= show me your code =======================return y_predif __name__ == "__main__":lr_ls = LR_LS()lr_ls.fit(x,y)print("估計的參數值:%s" %(lr_ls.w))x_test = np.array([4,5,7]).reshape(1,-1)print('真實值為:',x_test.dot(np.array([4.2,5.7,10.8])))print("預測值為:?%s"?%(lr_ls.predict(x_test)))3.?梯度下降法
class LR_GD():def __init__(self):self.w = None def fit(self,X,y,alpha=0.002,loss = 1e-10): # 設定步長為0.002,判斷是否收斂的條件為1e-10y = y.reshape(-1,1) #重塑y值的維度以便矩陣運算[m,d] = np.shape(X) #自變量的維度self.w = np.zeros((d)) #將參數的初始值定為0tol = 1e5#============================= show me your code =======================while tol > loss:h_f = X.dot(self.w).reshape(-1,1) theta = self.w + alpha*np.mean(X*(y - h_f),axis=0) #計算迭代的參數值tol = np.sum(np.abs(theta - self.w))self.w = theta#============================= show me your code =======================def predict(self, X):# 用已經擬合的參數值預測新自變量y_pred = X.dot(self.w)return y_pred if __name__ == "__main__":lr_gd = LR_GD()lr_gd.fit(x,y)print("估計的參數值為:%s" %(lr_gd.w))x_test = np.array([4,5,7]).reshape(1,-1)print('真實值為:',x_test.dot(np.array([4.2,5.7,10.8])))print("預測值為:%s"?%(lr_gd.predict(x_test)))4. 測試
在3維數據上測試sklearn線性回歸和最小二乘法的結果相同,梯度下降法略有誤差;又在100維數據上測試了一下最小二乘法的結果比sklearn線性回歸的結果更好一些。
往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習在線手冊深度學習在線手冊AI基礎下載(pdf更新到25集)本站qq群1003271085,加入微信群請回復“加群”獲取一折本站知識星球優惠券,復制鏈接直接打開:https://t.zsxq.com/yFQV7am喜歡文章,點個在看總結
以上是生活随笔為你收集整理的我感觉这是目前讲得最明白的线性回归的文章了的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【NLP】Doc2vec原理解析及代码实
- 下一篇: Python 2退出历史舞台 一句话证明