《机器学习实战》-线性回归
目錄
- 線性回歸
- 用線性回歸找到最佳擬合直線
- 程序8-1 標準回歸函數和數據導入函數
- 程序8-2 基于程序8-1繪圖
- 圖片8-1 ex0的數據集和它的最佳擬合直線
- 局部加權線性回歸
- 圖片8-2 參數k與權重的關系
- 程序8-3 局部加權線性回歸函數
- 圖片8-3 局部加權線性回歸結果
- 示例:預測鮑魚的年齡
- 縮減系數來“理解”數據
- 嶺回歸
- 前向逐步回歸
- 權衡偏差與方差
- 示例:預測樂高玩具套裝的價格
- 收集數據:使用 Google 購物的 API
- 訓練算法:建立模型
- 本章小結
- 線性回歸和局部加權線性回歸
線性回歸
本章內容
- 線性回歸
- 局部加權線性回歸
- 嶺回歸和逐步線性回歸
- 預測鮑魚年齡和樂高玩具價格
前面的章節給大家介紹了監督學習的分類部分,接下來幾章將會帶領同學們翱翔浩瀚的回歸海洋,注意此回歸不是 Logistic 回歸(Logistic 回歸之所以取名為這是因為歷史遺留問題)。具體是什么,那就開始讓我們來揭秘吧!
注意: 分類的目標變量是標稱型數據;回歸的目標變量是連續性數據。
用線性回歸找到最佳擬合直線
- 線性回歸的優缺點:
? 優點:結果易于理解,計算上不復雜
? 缺點:對非線性的數據擬合不好
? 適用數據類型:數值型和標稱型數據 - 回歸的目的:預測數值型的目標值
- 預測汽車功率大小的計算公式:
功率 = 0.0015 * 耗油量 + 0.99 * 百米加速時長 (純屬虛構,請勿模仿) - 回歸方程:上述計算公式即回歸方程
- 回歸系數:上述計算公式中的0.0015和0.99
- 預測值:給定所有待輸入的特征值乘以對應的回歸系數的總和
- 非線性回歸:輸出為輸入的乘積,例:功率 = 0.0015 * 耗油量 * 百米加速時長
- 回歸的一般方法:
- 收集數據:采用任意方法收集數據
- 準備數據:回歸需要數值型數據,標稱型數據將被轉成數值型數據
- 分析數據:可視化數據,采用縮減法求得新回歸系數后繪圖再與上一張圖比較
- 訓練算法:找到合適的回歸系數
- 測試算法:使用 R^2^或者預測值和數據的擬合度,來分析模型的效果
- 使用算法:使用回歸預測連續性數據的類別標簽
- 矩陣x:輸入的所有數據
- 向量 w:與數據對應的回歸系數
- 預測結果 Y~1~:\(Y_1={X^T}_1w\)
- 平方誤差:\(\sum_{i=1}^m(y_i-{x^T}_iw)^2\)
- 矩陣表示平方誤差:\((y-Xw)^T(y-Xw)\)
- 平方誤差對 w 求導:\(X^T(Y-Xw)\)
- 平方誤差對 w 求導等于零得:\(\hat{w}=(X^TX)-1X^Ty\)
- w 上方的標記含義:當前可以估計出 w 的最優解,即 w 的一個最佳估計
- 上述公式包含\((X^TX)^{-1}\),即該方程中的 X 必須存在逆矩陣
注意:不要糾結于公式,這不會影響你學習機器學習
程序8-1 標準回歸函數和數據導入函數
# coding: 'utf-8' import os import numpy as np import matplotlib.pyplot as plt from path_settings import machine_learning_PATHdata_set_path = os.path.join(machine_learning_PATH, '第八章/data-set') ex0_path = os.path.join(data_set_path, 'ex0.txt') ex1_path = os.path.join(data_set_path, 'ex1.txt') abalone_path = os.path.join(data_set_path, 'abalone.txt')def load_data_set(filename):# 文本第一行值全為0的解釋:簡單說是因為兩個矩陣相乘一個矩陣的行和另一個矩陣的列得相等,具體可查資料num_feat = len(open(filename).readline().split('\t')) - 1data_mat = []label_mat = []fr = open(filename)for line in fr.readlines():line_arr = []cur_line = line.strip().split('\t')for i in range(num_feat):line_arr.append(float(cur_line[i]))data_mat.append(line_arr)label_mat.append(float(cur_line[-1]))return data_mat, label_matdef stand_regres(x_arr, y_arr):x_mat = np.mat(x_arr)y_mat = np.mat(y_arr)x_tx = x_mat.T * x_mat# 判斷矩陣是否為奇異矩陣,即矩陣是否有逆矩陣if np.linalg.det(x_tx) == 0:print("奇異矩陣沒有逆矩陣")returnws = x_tx.I * (x_mat.T * y_mat.T)# 求解未知矩陣# ws = np.linalg.solve(x_tx,x_mat.T*y_mat.T)return x_mat, y_mat, wsdef test_stand_regres():x_arr, y_arr = load_data_set(ex0_path)_, _, ws = stand_regres(x_arr, y_arr)print(ws)if __name__ == '__main__':test_stand_regres()程序8-2 基于程序8-1繪圖
def plot_stand_regres(x_mat, y_mat, ws):fig = plt.figure()ax = fig.add_subplot(111)ax.scatter(x_mat[:, 1].flatten().A[0], y_mat.T[:, 0].flatten().A[0])x_copy = x_mat.copy()x_copy.sort(0)y_hat = x_copy * wsax.plot(x_copy[:, 1], y_hat)plt.show()def test_plot_stand_regres():x_arr, y_arr = load_data_set(ex0_path)x_mat, y_mat, ws = stand_regres(x_arr, y_arr)plot_stand_regres(x_mat, y_mat, ws)# 判斷擬合效果print(np.corrcoef((x_mat * ws).T, y_mat))'''[[1. 0.98647356][0.98647356 1. ]]'''if __name__ == '__main__':# test_stand_regres()test_plot_stand_regres()圖片8-1 ex0的數據集和它的最佳擬合直線
局部加權線性回歸
- 局部加權線性回歸:給待預測點附近的每個點賦予一定的權重
局部加權線性回歸求回歸系數公式:\(\hat{w}=(X^TWX)^{-1}X^TWy\)
- W:給每個數據點賦予權重的矩陣
- LWLR使用“核”(類似于支持向量機中的核)來對附近的點賦予更高的權重。
最常用的核——高斯核:\(w(i,i)=exp\left({\frac{|x^{(i)}-x|}{-2k^2}}\right)\)
點 x 與 x(i)越近,w(i,i)將會越大,參數 k 決定了對附近的點賦予多大的權重。
圖片8-2 參數k與權重的關系
- 假定我們正預測的點是 x=0.5,最上面的是原始數據集,第二個圖顯示了當 k=0.5 時,大部分數據都用于訓練回歸模型;最下面的圖顯示當 k=0.01 時,僅有很少的局部點被用于訓練回歸模型。
程序8-3 局部加權線性回歸函數
def lwlr(test_point, x_arr, y_arr, k=1):"""給樣本點增加權重,參數 k 控制衰減的速度"""x_mat = np.mat(x_arr)y_mat = np.mat(y_arr)m = np.shape(x_mat)[0]# 創建對角權重矩陣。該矩陣對角線元素全為1,其余元素全為0weights = np.mat(np.eye(m))for j in range(m):diff_mat = test_point - x_mat[j, :]weights[j, j] = np.exp(diff_mat * diff_mat.T / (-2 * k ** 2))x_tx = x_mat.T * (weights * x_mat)if np.linalg.det(x_tx) == 0:print("奇異矩陣沒有逆矩陣")returnws = x_tx.I * (x_mat.T * (weights * y_mat.T))return test_point * wsdef lwlr_test(test_arr, x_arr, y_arr, k=1):"""使數據集中每個點調用 lwlr 方法"""m = np.shape(test_arr)[0]y_hat = np.zeros(m)for i in range(m):y_hat[i] = lwlr(test_arr[i], x_arr, y_arr, k)return y_hatdef test_lwlr_test():x_arr, y_arr = load_data_set(ex0_path)y_hat = lwlr_test(x_arr, x_arr, y_arr, 0.003)print(y_hat)def plot_lwlr(x_sort, y_hat, str_ind, x_mat, y_mat):fig = plt.figure()ax = fig.add_subplot(111)ax.plot(x_sort[:, 1], y_hat[str_ind])ax.scatter(x_mat[:, 1].flatten().A[0], y_mat.T[:, 0].flatten().A[0], s=2, c='red')plt.show()def test_plot_lwlr():x_arr, y_arr = load_data_set(ex0_path)x_mat = np.mat(x_arr)y_mat = np.mat(y_arr)y_hat = lwlr_test(x_arr, x_arr, y_arr, 0.01)str_ind = x_mat[:, 1].argsort(0)x_sort = x_mat[str_ind][:, 0, :]plot_lwlr(x_sort, y_hat, str_ind, x_mat, y_mat)if __name__ == '__main__':# test_stand_regres()# test_plot_stand_regres()# test_lwlr_test()test_plot_lwlr()圖片8-3 局部加權線性回歸結果
示例:預測鮑魚的年齡
縮減系數來“理解”數據
嶺回歸
前向逐步回歸
權衡偏差與方差
示例:預測樂高玩具套裝的價格
收集數據:使用 Google 購物的 API
訓練算法:建立模型
本章小結
線性回歸和局部加權線性回歸
? 由于看完《機器學習實戰》第八章中的局部加權線性回歸后,敲完代碼之后只是知道它是這樣的,但不是很清楚內在的原因。書中并沒有對其做過多解釋,百度也找不到一篇很好的文章來解釋 線性回歸和局部加權線性回歸 兩者之間的區別。索性寫一寫自己對 線性回歸和局部加權線性回歸 的看法與感悟。也許還是不那么準確,但一定是清晰易懂的。
? 其中的平方誤差是我們的在 x=x~i~ 上預測值與實際值的差值平方,而我們需要做的任務就是找到一個最合適的 w 使得該差值平方最小。
? 再來說說我們的局部加權線性回歸(LWLR),它只是在線性回歸的基礎上加了一個權重,而LWLR通常使用“核”(類似于自持向量機中的核)來對附近的點賦予更高的權重。因此它的公式變成:
\(\sum_{i=1}^mW_i(y_i-x^T_iw)^2\)
? 注意:W~i~ 是賦予 x~i~ 權重的矩陣,也可以是向量。
? 一般我們的 W~i~ 最常用的核是高斯核:\(w(i,i)=exp\left({\frac{|x^{(i)}-x|}{-2k^2}}\right)\)
? 注意:高斯核中的 x 為新預測樣本的特征數據即新的 x,它同 w 也是一個向量,參數 k 控制了權值變化的速率。
? 以上介紹了局部加權線性回歸的理論,現在通過圖像我們再來形象化的解釋局部加權線性回歸。首先看看不同 k 下的參數 k 與權重的關系:
- 基于上圖我們能發現兩個規律:
- 假定我們正預測的點是 x=0.5,一定要記住 x 的對應值不再是一個數值,它的對應值變成了向量,所以這是 x=0.5后的新圖像,牢記它變成了一個向量,最上面的是原始數據集;第二個圖顯示了當 k=0.5 時,大部分數據都用于訓練回歸模型;最下面的圖顯示當 k=0.01 時,僅有很少的局部點被用于訓練回歸模型。
- 如果\(|x^{(i)}-x|\approx0\),則\(w_{(i)}\approx1\);如果\(|x^{(i)}-x|\approx\infty\),則\(w^{(i)}\approx0\)
? 重點來了,我剛開始不明白的就是這里,上面 兩個注意+圖片解釋 其實已經揭曉了答案
? 離 x 很近的樣本,權值接近1;而離 x 很遠的樣本,此時權值接近于0,這樣就在 x 局部構成線性回歸,x 構成的線性回歸依賴的事 x 周邊的點,而不類似于線性回歸依賴訓練集中的所有數據。
? 上圖紅線是某個點 x 基于訓練集中所有數據使用線性回歸做的結果,黑色直線使用 LWLR 做的結果,由于在每個數據都會重復局部加權的過程,并且不斷地每個點的回歸系數也在不斷的改變,因此它會很好的擬合數據集,進而消除了線性回歸擬合不好的缺點。(有點類似極限或者求導或者微積分的思想,總之就是把一個大的物體切割成一大部分,然后對于每一部分進行計算)。
? 說到了LWLR的優點,不得不說說它的缺點,上一段講到了訓練集中的每個數據都會重復局部加權的過程,因此他的計算量是龐大的,并且他的回歸系數是基于周圍的數據計算出來的,因此下次需要預測某個數據的分類時,需要再一次輸入所有的數據。即線性回歸算法是參數學習算法,一旦擬合出合適的回歸系數,對于之后的預測,不需要再使用原始訓練數據集;局部加權線性回歸算法是非參數學習算法,每次進行預測都需要全部的訓練數據,無法算出固定的回歸系數。
? 最后看一看 線性回歸和不同 k 值的局部加權線性回歸 對相同數據集的結果。
? 上圖第一張圖使用的是 k=1 的LWLR(類似于線性回歸),第二張圖使用的是 k=0.01 的LWLR,第三張圖使用的 k=0.003 的 LWLR。第一張圖明顯欠擬合,第二張圖很合適,第三張圖過擬合。
轉載于:https://www.cnblogs.com/nickchen121/p/10912341.html
總結
以上是生活随笔為你收集整理的《机器学习实战》-线性回归的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [BZOJ2738]矩阵乘法
- 下一篇: Scrapy运行中常见网络相关错误