- 迴歸
迴歸是監督學習的一個重要問題,輸入變量X和輸出變量Y均爲連續變量。迴歸問題按照X和Y之間關係的類型,分爲線性模型和非線性模型;按照輸入變量的個數,分爲一元迴歸和多元迴歸。 線性迴歸
根據數據的預處理,選定模型的假設空間,即包含所有可能的條件概率分佈或決策模型,線性迴歸的假設空間就是所有這些線性函數構成的函數集合。初始數據經過處理後,可通過直觀的圖形輸出的定性方法分析選擇假設空間。import pandas as pd import matplotlib.pyplot as plt path = 'adverdataRaw.csv' data = pd.read_csv(path) x = data[['TV', 'Radio', 'Newspaper']] y = data['Sales'] plt.plot(data['TV'], y, 'r.', label='TV') plt.plot(data['Radio'], y, 'go', label='Radio') plt.plot(data['Newspaper'], y, 'b^', label='Newspaper') plt.legend(loc='lower right') plt.grid() plt.title('adverdataShow') plt.savefig('adverdataShow.png') # 在show之前,否則保存的是一張空白圖片 plt.show()
監督學習從訓練數據集合中學習模型,對測試數據進行預測。把初始數據進行切割分成訓練數據和測試數據時,訓練數據和測試數據應當儘可能互斥,即測試數據儘量不要在訓練數據中出現,未在訓練數據中使用。from sklearn.model_selection import train_test_split x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)
線性迴歸模型求解
基於均方誤差最小化來進行模型求解的方法稱爲“最小二乘法”,它對應了常用的歐幾里得距離或簡稱“歐氏距離”。在線性迴歸中,最小二乘法是試圖找到一條直線,使所有樣本到直線上的歐氏距離之和最小。- 對於一元線性迴歸,模型爲:
f(xi)=wxi+b(式1)
根據均方差最小化,有
(x∗,b∗)=argmin(w,b)∑i=1m(f(xi)−yi)2
=argmin(w,b)∑i=1m(yi−wxi−b)2(式2) - 對於多元線性迴歸,模型爲:
f(xi)=wTxi+b(式3)
類似的,可以用最小二乘法來對w和b進行估計,把w和b吸收入向量形式
ŵ =(w;b)
相應的,把數據集爲一個m*(d+1)大小的矩陣 X,其中每行對應一個示例,該行前d個元素對應於示例的d個屬性值,最後一個元素恆置爲1,即
X=⎛⎝⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜x11x21⋮xm1x12x22⋮xm2⋯⋯⋱⋯x1dx2d⋮xmd11⋮1⎞⎠⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟=⎛⎝⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜xT1xT2⋮xTm11⋮1⎞⎠⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟
再把標記也寫成向量形式
y=(y1;y2;⋯;ym)
則類似(式2),有
ŵ ∗=argminŵ (y−Xŵ )T(y−Xŵ )(式4)
令
Eŵ =(y−Xŵ )T(y−Xŵ )
對ŵ 求導得到
(∂Eŵ )(∂ŵ )=2XT(Xŵ −y)(式5)
令上式爲零得到ŵ 最優解的閉式解。
當XTX 爲滿秩矩陣或正定矩陣時,令(式5)爲零可得
ŵ ∗=(XTX)−1XTy(式6)
其中(XTX)−1 是(XTX) 的逆矩陣。令x̂ i=(xi;1) ,則最終的多元線性迴歸模型爲
f(ŵ i)=x̂ Ti(XTX)−1XTy(式7)
Python的sklearn庫已經封裝好了線性迴歸模型,只需要調用即可
from sklearn.linear_model import LinearRegression model = linearRegression.fit(x_train, y_train) # print(model) y_hat = linearRegression.predict(np.array(x_test)) mse = np.average((y_hat - np.array(y_test)) ** 2) # mean squared error rmse = np.sqrt(mse) # root mean squared error t = np.arange(len(x_test)) plt.plot(t, y_test, 'r-', linewidth=2, label='Test') plt.plot(t, y_hat, 'g-', linewidth=2, label='Predict') plt.legend(loc='upper right') plt.grid() plt.title('Test-Preict') plt.savefig('adverdataTP.png') plt.show() print(linearRegression.coef_) # 估計係數 print(linearRegression.intercept_) # 常數項 print('mse=%f, rmse=%f' % (mse, rmse))
定量分析如下(各項係數、常數項、方差&標準差)[ 0.04695205 0.17658644 0.00185115] 2.93721573469 mse=1.928925, rmse=1.388857
- 正則化
式7中多元線性迴歸模型是在XTX 爲滿秩陣或正定陣時求得,然而,現實任務中XTX 往往不是滿秩陣。例如在許多任務中我們會遇到大量的變量,其數目甚至超過樣例數,導致X 的列數多於行數,XTX 顯然不是滿秩陣。此時可解出多個ŵ i ,它們都能使均方誤差最小化,選擇哪一個解作爲輸出將由算法的歸納偏好決定,常見的做法是引入正則化。
正則化符合奧卡姆剃刀原理。奧卡姆剃刀原理應用於模型選擇時變爲一下想法:在所有可能選擇的模型中,能夠很好地解釋已知數據並且十分簡單纔是最好的模型。
令Θ=(XTX)−1XTy ,則根據(式7)得到模型爲
ŷ (Θ)=ΘX̂ (式8)
令Θ=(XTX+λI)−1XTy ,XTX 半正定:對於任意的非零向量μ
μXTXμ=(Xμ)TXμ(式9)
令ν=Xμ ,可得νTν≥0
所以,對於任意的實數λ>0,XTX+λI 正定,從而可逆,保證公式Θ=(XTX+λI)−1XTy 有意義。
正則化項可以取不同的形式。在迴歸問題中,損失函數是平方損失,正則化可以是參數向量的L2 範數:
L(w)=1N∑i=1N(f(xi;w)−y2i)+λ2∥w∥2(式10)
式10中,∥w∥ 表示參數向量w 的L2 範數
正則化也可以是參數向量的L1 範數:
L(w)=1N∑i=1N(f(xi;w)−y2i)+∥w∥1(式11)
式11中,∥w∥1 表示參數向量w 的L1 範數
在sklearn庫中,LassoCV類封裝了L1正則,RidgeCV類封裝了L2正則,λ 先設置ndarray,然後讓系統篩選出最佳的那個
from sklearn.linear_model import LassoCV, RidgeCV x_train, x_test, y_train, y_test = train_test_split(data_x, data_y, random_state=1) # 數據切割 alpha = np.logspace(-4, 1, 100) lasso_model = LassoCV(alphas=alpha, cv=5) #L1 正則化,且爲5折交叉驗證 lasso_model.fit(x_train, y_train) lasso_yhat = lasso_model.predict(np.array(x_test)) ridge_model = RidgeCV(alphas=alpha, cv=5) #L2 正則化,且爲5折交叉驗證 ridge_model.fit(x_train, y_train) ridge_yhat = ridge_model.predict(np.array(x_test)) t = np.arange(len(x_test)) # 圖形(定性)分析 plt.plot(t, y_test, linewidth=2, label='Test') plt.plot(t, lasso_yhat, linewidth=2, label='Predict') plt.legend(loc='upper right') plt.title('LassoCV') plt.savefig('LassoCV.png') plt.show() plt.plot(t, y_test, linewidth=2, label='Test') plt.plot(t, ridge_yhat, linewidth=2, label='Predict') plt.legend(loc='upper right') plt.title('RidgeCV') plt.savefig('RidgeCV.png') plt.show() # 定量分析 lasso_mse = np.average((lasso_yhat - np.array(y_test)) ** 2) # 方差 lasso_rmse = np.sqrt(lasso_mse) # 標準差 ridge_mse = np.average((ridge_yhat - np.array(y_test)) ** 2) ridge_rmse = np.sqrt(ridge_mse) print('lasso model各項係數:', lasso_model.coef_, '常數項:', lasso_model.intercept_) # 估計係數 print('lasso_mse:%f, lasso_rmse:%f' % (lasso_mse, lasso_rmse)) print('lasso model alpha:', lasso_model.alpha_) print('ridge model各項係數:', ridge_model.coef_, '常數項:', ridge_model.intercept_) print('ridge model alpha:', ridge_model.alpha_) print('ridge_mse:%f, ridge_rmse:%f' % (ridge_mse, ridge_rmse))
定性分析(圖片)
定量分析,根據下面參數,可知Ridge比Lasso好點lasso model各項係數: [ 0.04660234 0.18117916] 常數項: 2.92724792885 lasso_mse:1.926281, lasso_rmse:1.387905 lasso model alpha: 0.0001 ridge model各項係數: [ 0.04660234 0.18117959] 常數項: 2.92723733246 ridge model alpha: 0.0001 ridge_mse:1.926276, ridge_rmse:1.387903
- 參考書籍
[1] 李航.統計學習方法
[2] 周志華.機器學習
- 數據參考
Advertising.csv
- 對於一元線性迴歸,模型爲:
線性迴歸
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.