程序所用文件:https://files.cnblogs.com/files/henuliulei/%E5%9B%9E%E5%BD%92%E5%88%86%E7%B1%BB%E6%95%B0%E6%8D%AE.zip
標准方程法
標准方程法是求取參數的另一種方法,不需要像梯度下降法一樣進行迭代,可以直接進行結果求取
那么參數W如何求,下面是具體的推導過程
因此參數W可以根據最后一個式子直接求取,但是我們知道,矩陣如果線性相關,那么就無法取逆,如下圖
因此,對比梯度下降法和標准方程法我們可以得到下面的圖
下面的demo是標准方程法實現擬合
import numpy as np from matplotlib import pyplot as plt from numpy import genfromtxt #載入數據 data = genfromtxt('data.csv',delimiter=',') x_data = data[:,0,np.newaxis]#一維變為二維 y_data = data[:,1,np.newaxis] plt.scatter(x_data,y_data) plt.show() print(np.mat(x_data).shape) print(np.mat(y_data).shape) #給樣本添加偏置項 X_data = np.concatenate((np.ones((100,1)),x_data),axis=1) print(X_data.shape) #標准方程法求解回歸參數 def weights(xArr, yArr): xMat = np.mat(xArr)#array變為mat,方便進行矩陣運算 yMat = np.mat(yArr) xTx = xMat.T * xMat if np.linalg.det(xTx) == 0.0: #一、np.linalg.det():矩陣求行列式二、np.linalg.inv():矩陣求逆三、np.linalg.norm():求范數 print("該矩陣不可逆") return ws = xTx.I * xMat.T * yMat return ws ws = weights(X_data,y_data) print(ws[1].shape) #畫圖 x_test = np.array([[20], [80]]) print(x_test.shape) y_test = ws[0] + x_test * ws[1] plt.plot(x_data, y_data, 'b.') plt.plot(x_test, y_test, 'r') plt.show()
捎帶一下兩個小的知識點
數據歸一化
由於單位的原因,不同單位之間數據產別太大,影響數據分析,所以我們一般會對某些數據進行歸一化,即把數據歸一化到某個范圍之內。
交叉驗證
當樣本數據比較小的時候,為了避免驗證集“浪費”太多的訓練數據,采用樣本交叉驗證的方法,並把平均值作為結果
過擬合,欠擬合,正確擬合
過擬合會導致訓練集擬合效果好,測試集效果差,欠擬合都差。為防止過擬合
正則化就是在原來的損失函數基礎上加入一項,來減少高次項的值,使得曲線平滑
嶺回歸
為解決標准方程法中存在的矩陣不可逆問題,引入了嶺回歸
1 import numpy as np 2 from matplotlib import pyplot as plt 3 from sklearn import linear_model 4 #讀取數據 5 data = np.genfromtxt("longley.csv", delimiter=',') 6 print(data) 7 #切分數據 8 x_data = data[1:,2:] 9 y_data = data[1:,1] 10 #創建模型 11 #生成0.001到1的五十個嶺系數值 12 alphas_to_test = np.linspace(0.001, 1)#從0.001到1共五十個數據,默認在start和end之間有50個數據,這五十個數據是假設的嶺系數 13 model = linear_model.RidgeCV(alphas= alphas_to_test, store_cv_values= True)#store_cv_values表示存儲每個嶺系數和樣本對應下的損失值 14 model.fit(x_data, y_data) 15 print(model.alpha_)#最小損失函數對應的嶺系數 16 print(model.cv_values_.shape)#16*50的矩陣 17 #繪圖 18 #嶺系數和loss值得關系 19 plt.plot(alphas_to_test, model.cv_values_.mean(axis = 0))# 求在每個系數下對應的平均損失函數,axis=1表示橫軸,方向從左到右;0表示縱軸,方向從上到下 20 plt.plot(model.alpha_, min(model.cv_values_.mean(axis = 0)),'ro')#最優點 21 plt.show() 22 model.predict(x_data[2,np.newaxis])#對一個樣本進行預測
嶺系數和損失函數對應的關系圖
簡單說一下arange,range,linspace的區別,arange和range都是在start和end之間以step作為等差數列對應的數組,只不過arange的step
可以是小數,而range必須為整數,而且arange屬於numpy,linspace則是在start和end之間取num個數 np.linspace(start,end,num)
LASSO算法
由於嶺回歸計算得到的系數很難為0,而Lasso算法可以使一些指標為0
從上圖可以看出,LASSo在入系數某個取值下某些特征的系數就歸為0了
交點處變為最優取值處
1 import numpy as np 2 from matplotlib import pyplot as plt 3 from sklearn import linear_model 4 #讀取數據 5 data = np.genfromtxt("longley.csv", delimiter=',') 6 print(data) 7 #切分數據 8 x_data = data[1:,2:] 9 y_data = data[1:,1] 10 #創建模型 11 model = linear_model.LassoCV() 12 model.fit(x_data,y_data) 13 #lasso系數 14 print(model.alpha_) 15 #相關系數,發現某些系數為零,說明這些系數權重比較小,可以忽視 16 print(model.coef_)#[0.10206856 0.00409161 0.00354815 0. 0. 0. ] 17 #驗證 18 model.predict(x_data[-2,np.newaxis])
彈性網
對lasso和嶺系數方法綜合起來
1 import numpy as np 2 from matplotlib import pyplot as plt 3 from sklearn import linear_model 4 #讀取數據 5 data = np.genfromtxt("longley.csv", delimiter=',') 6 print(data) 7 #切分數據 8 x_data = data[1:,2:] 9 y_data = data[1:,1] 10 #創建模型 11 model = linear_model.ElasticNetCV() 12 model.fit(x_data,y_data) 13 #lasso系數 14 print(model.alpha_) 15 #相關系數,發現某些系數為零,說明這些系數權重比較小,可以忽視 16 print(model.coef_)#[0.10206856 0.00409161 0.00354815 0. 0. 0. ] 17 #驗證 18 print(model.predict(x_data[-2,np.newaxis]))