一、初始線性回歸:
1、線性回歸的定義:
線性回歸(Linear regression)是利用回歸方程(函數)對一個或多個自變量(特征值)和因變量(目標值)之間關系進行建模的一種分析方式。
2、通用公式:
h(w) = w1x1 + w2x2 +w3x3 ... + b = (wτ)x + b
其中:w,x可以理解為矩陣:
3、線性回歸的分類: 線性關系、非線性關系。
4、線性回歸API:
sklearn.linear_model.LinearRegression()
- LinearRegression.coef_: 線性回歸系數。
5、代碼演示??:根據學生的平時成績、期末成績預測學生的最終成績。
# coding:utf-8
from sklearn.linear_model import LinearRegression
# 1.獲取數據
x = [[80, 86],
[82, 80],
[85, 78],
[90, 90],
[86, 82],
[82, 90],
[78, 80],
[92, 94]]
y = [84.2, 80.6, 80.1, 90, 83.2, 87.6, 79.4, 93.4]
# 2.模型訓練
# 2.1 實例化一個估計器
estimator = LinearRegression()
# 2.2 使用fit方法進行訓練
estimator.fit(x, y)
# 打印對應的系數:
print("線性回歸的系數是:\n", estimator.coef_)
# 打印的預測結果是:
print("輸出預測結果:\n", estimator.predict([[100, 80]]))
6、運行結果:
二、導數-求導:
1、常見函數的導數:
2、導數的四則運算:
3、矩陣(向量)求導:
三、線性回歸的損失和優化:
1、損失函數公式:
其中:
(1)yi為第i個訓練樣本的真實值。
(2)h(xi)為第i個訓練樣本特征值組合預測函數。
(3)又稱最小二乘法。
那么,如何減少這個損失,使我們預測的更加準確些?既然存在這個損失,我們一直說機器學習有自動學習的功能,在線性回歸這里是能夠體現的。這里可以通過一些優化方法去優化(其實是數學當中的求導功能)回歸的總損失!
2、正規方程:利用矩陣的逆,轉置進行一步求解,只適合樣本和特征比較少的情況。
2.1、代碼示范??:
# coding:utf-8
"""
# 1.獲取數據
# 2.數據基本處理
# 2.1 分割數據
# 3.特征工程-標準化
# 4.機器學習-模型訓練-線性回歸
# 5.模型評估
"""
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, SGDRegressor
from sklearn.metrics import mean_squared_error
def linear_model1():
"""
線性回歸:正規方程
:return:
"""
# 1.獲取數據
boston = load_boston()
print(boston)
# 2.數據基本處理
# 2.1 分割數據
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, test_size=0.2)
# 3.特征工程-標準化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4.機器學習-模型訓練-線性回歸
estimator = LinearRegression()
estimator.fit(x_train, y_train)
print("這個模型的偏置是:\n", estimator.intercept_)
print("這個模型的系數是:\n", estimator.coef_)
# 5.模型評估
# 5.1 預測值
y_pre = estimator.predict(x_test)
print("預測值是:\n", y_pre)
# 5.2 均方誤差
ret = mean_squared_error(y_test, y_pre)
print("均方誤差:\n", ret)
linear_model1()
2.2、運行結果:
3、梯度下降(Gradient Descent):
3.1、基本思想:
梯度下降法可以類比為一個下山的過程。
假設這樣一個場景:一個人被困在山上,需要從山上下來(i.e.找到山的最低點,也就是山谷。但此時山上的濃霧很大,導致可視度很低)。因此,下山的路徑就無法確定,以他當前的位置為基準尋找這個位置最陡峭的地方,然后朝著山的高度下降的地方走,然后沒走一段距離,都反復采用同一個方法,最后就能成功的抵達山谷。
梯度下降的基本過程就和下山的場景很類似:
首先,我們有一個可微分的函數,這個函數就代表著一座山。
我們的目標就是找到這個函數的最小值,也就是山底。
根據之前的場景假設,最快的下山方式就是找到當前位置最陡峭的方向,然后沿著此方向向下走,對應到函數中,就是找到給定點的梯度,然后朝著梯度相反的方向,就能讓函數值下降的最快!因為梯度的方向就是函數值變化最快的方向。所以,我們重復利用這個方法,反復求取梯度,最后就能到達局部最小值,這就類似于我們下山的過程。而求取梯度就確定了最陡峭的方向,也就是場景中測量方向的手段。
3.2、梯度的概念:
梯度是微積分中一個很重要的概念。
在單變量的函數中,梯度其實就是函數的微分,代表著函數在某個給定點的切線的斜率;
在多變量函數中,梯度是一個向量,向量有方向,梯度的方向就指出了函數在給定點的上升最快的方向;
這也就說明了為什么我們需要千方百計地求取梯度!我們需要到達山底,就需要在每一步觀測到此時最陡峭的地方,梯度就恰好告訴我們這個方向。梯度的方向是函數在給定點上升最快的方向,那么梯度的反方向就是函數在給定點下降最快的方向,這正是我們所需要的。所以我們只要沿著梯度的方向一直走,就能走到局部的最低點。
3.3、梯度下降舉例:
(1)單變量函數的梯度下降:
我們假設有一個單變量的函數:J(θ) = θ^2 (其中;θ^2指的是θ的平方 )
函數的微分:J`(θ) = 2θ。
初始化,起點為: θ^0 = 1
學習率: α = 0.4
我們開始進行梯度下降的迭代計算過程:
θ^0 = 1
θ^1 = θ^0 - α * J`(θ^0) = 1 - 0.4 * 2 = 0.2
θ^2 = θ^1 - α * J`(θ^1) = 0.04
θ^3 = θ^2 - α * J`(θ^2) = 0.008
θ^4 = θ^13- α * J`(θ^3) = 0.0016
如圖,經過四次的運算,也就是走了四部,基本就抵達了函數的最低點山底了:
(2)多變量函數的的梯度下降:
假設有一個目標函數:J(θ) = θ1^2 + θ2^2
現在要通過梯度下降法計算這個函數的最小值,我們通過觀察不難發現其實就是(0,0)點。但是接下來,我們從梯度下降算法開始一步步計算到這個最小值!我們假設:
初始的起點為:θ^0 = (1, 3)
初始的學習率為:α = 0.1
函數的梯度為:▽:J(θ) =<2θ1, 2θ2)>
進行多次迭代:
θ^0 = (1, 3)
θ^1 = θ^0 - α▽J(θ) = (1, 3) - 0.1(2, 6) = (0.8, 2.4)
θ^2 = θ^1 - α▽J(θ) = (0.8, 2.4) - 0.1(1.6, 4.8) = (0.64, 1.92)
θ^3 = θ^2 - α▽J(θ) = (0.512, 1.536)
θ^4 = θ^3 - α▽J(θ) = (0.4096, 1.2288000000000001)
.
.
.
θ^10 = (0.10737418240000003, 0.32212254720000005)
.
.
.
θ^50 = (1.1417981541647683e-05, 3.425394462494306e-05)
.
.
.
θ^100 = (1.6296287810675902e-10, 4.888886343202771e-10)
我們發現,已經基本靠近函數的最小值點:
3.4、梯度下降公式:
(1)α 在梯度下降算法中被稱作 學習率或者步長,控制每一步走的距離,控制步長很重要,不能太小,也不能太大。
(2)α后面的部分決定了梯度下降的方向。
(3)特點:
- 初始點不同,獲得的最小值也不同,因此梯度下降求得的只是局部最小值;
- 越接近最小值時,下降速度越慢;
(4)梯度下降法沒辦法保證走到最小值,可能只是極小值:
3.5、常見的梯度下降法:
(1)、全梯度下降算法(Full gradient descent):使用所有樣本,整個數據集。
(2)、隨機梯度下降算法(Stochastic gradient descent),
(3)、小批量梯度下降算法(Mini-batch gradient descent),
(4)、隨機平均梯度下降算法(Stochastic average gradient descent)。
它們都是為了正確地調節權重向量沒通過為每個權重計算一個梯度,從而更新權值,是目標函數盡可能最小化。其差別在于樣本的使用方式不同。
3.6、梯度下降法代碼示范??:
# coding:utf-8
"""
# 1.獲取數據
# 2.數據基本處理
# 2.1 分割數據
# 3.特征工程-標準化
# 4.機器學習-模型訓練-線性回歸
# 5.模型評估
"""
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, SGDRegressor
from sklearn.metrics import mean_squared_error
def linear_model1():
"""
線性回歸:正規方程
:return:
"""
# 1.獲取數據
boston = load_boston()
print(boston)
# 2.數據基本處理
# 2.1 分割數據
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, test_size=0.2)
# 3.特征工程-標準化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4.機器學習-模型訓練-線性回歸
estimator = LinearRegression()
estimator.fit(x_train, y_train)
print("這個模型的偏置是:\n", estimator.intercept_)
print("這個模型的系數是:\n", estimator.coef_)
# 5.模型評估
# 5.1 預測值
y_pre = estimator.predict(x_test)
print("預測值是:\n", y_pre)
# 5.2 均方誤差
ret = mean_squared_error(y_test, y_pre)
print("均方誤差:\n", ret)
def linear_model2():
"""
線性回歸:梯度下降法
:return:
"""
# 1.獲取數據
boston = load_boston()
print(boston)
# 2.數據基本處理
# 2.1 分割數據
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, test_size=0.2)
# 3.特征工程-標準化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4.機器學習-模型訓練-線性回歸
estimator = SGDRegressor(max_iter=1000)
estimator.fit(x_train, y_train)
print("這個模型的偏置是:\n", estimator.intercept_)
print("這個模型的系數是:\n", estimator.coef_)
# 5.模型評估
# 5.1 預測值
y_pre = estimator.predict(x_test)
print("預測值是:\n", y_pre)
# 5.2 均方誤差
ret = mean_squared_error(y_test, y_pre)
print("均方誤差:\n", ret)
# linear_model1()
linear_model2()
3.7、運行結果:
四、線性回歸的改進 - 嶺回歸(Tikhonov regularization):
1、嶺回歸是線性回歸的正則化版本,即在原來的線性回歸的cost function懲罰函數中添加正則項(regularization term):
以達到在你和數據的同時,使模型權重盡可能小的目的,嶺回歸代價函數:
即:
2、嶺回歸API: sklearn.linear_model.Ridge(alpha=1.0,fit_intercept=True, normalize=False)
- 具有l2正則化的線性回歸
- alpha:正則化力度,也叫 λ
λ取值: 0~1 1~10 - solver:會根據數據自動選擇優化方法
sag:如果數據集、特征都比較大,選擇該隨機梯度下降優化 - normalize:數據是否進行標準化
normalize=False:可以在fit之前調用preprocessing.StandardScaler標準化
數據
normalize=True:默認對數據標準化進行了封裝,會自動進行數據標準化 - Ridge.coef:回歸權重
- Ridge.intercept: 回歸偏置
注意:Ridge方法相當于SGDRegressor(penalty='l2', loss="squared_loss"),只不過SGDRegressor實現了一個普通的隨機梯度下降學習,推薦使用Ridge(實現了SAG) - sklearn.linear_model.RidgeCV(BaseRidgeCV, RegressorMixin)
(1) 具有l2正則化的線性回歸,可以進行交叉驗證
(2)coef:回歸系數
3、正則化程度的變化對結果的影響:
- 正則化力度越大,權重系數會越小
- 正則化力度越小,權重系數會越大
4、嶺回歸代碼演示??:
# coding:utf-8
"""
# 1.獲取數據
# 2.數據基本處理
# 2.1 分割數據
# 3.特征工程-標準化
# 4.機器學習-模型訓練-線性回歸
# 5.模型評估
"""
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, SGDRegressor, RidgeCV, Ridge
from sklearn.metrics import mean_squared_error
def linear_model1():
"""
線性回歸:正規方程
:return:
"""
# 1.獲取數據
boston = load_boston()
# print(boston)
# 2.數據基本處理
# 2.1 分割數據
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, test_size=0.2)
# 3.特征工程-標準化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4.機器學習-模型訓練-線性回歸
estimator = LinearRegression()
estimator.fit(x_train, y_train)
print("這個模型的偏置是:\n", estimator.intercept_)
print("這個模型的系數是:\n", estimator.coef_)
# 5.模型評估
# 5.1 預測值
y_pre = estimator.predict(x_test)
print("預測值是:\n", y_pre)
# 5.2 均方誤差
ret = mean_squared_error(y_test, y_pre)
print("均方誤差:\n", ret)
def linear_model2():
"""
線性回歸:梯度下降法
:return:
"""
# 1.獲取數據
boston = load_boston()
# print(boston)
# 2.數據基本處理
# 2.1 分割數據
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, test_size=0.2)
# 3.特征工程-標準化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4.機器學習-模型訓練-線性回歸
estimator = SGDRegressor(max_iter=1000)
estimator.fit(x_train, y_train)
print("這個模型的偏置是:\n", estimator.intercept_)
print("這個模型的系數是:\n", estimator.coef_)
# 5.模型評估
# 5.1 預測值
y_pre = estimator.predict(x_test)
print("預測值是:\n", y_pre)
# 5.2 均方誤差
ret = mean_squared_error(y_test, y_pre)
print("均方誤差:\n", ret)
def linear_model3():
"""
線性回歸:嶺回歸
:return:None
"""
# 1.獲取數據
boston = load_boston()
# print(boston)
# 2.數據基本處理
# 2.1 分割數據
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, test_size=0.2)
# 3.特征工程-標準化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4.機器學習-模型訓練-線性回歸
# estimator = Ridge(alpha=1.0)
estimator = RidgeCV(alphas=(0.001, 0.01, 0.1, 1, 10, 100))
estimator.fit(x_train, y_train)
print("嶺回歸這個模型的偏置是:\n", estimator.intercept_)
print("嶺回歸這個模型的系數是:\n", estimator.coef_)
# 5.模型評估
# 5.1 預測值
y_pre = estimator.predict(x_test)
print("嶺回歸預測值是:\n", y_pre)
# 5.2 均方誤差
ret = mean_squared_error(y_test, y_pre)
print("嶺回歸均方誤差:\n", ret)
if __name__ == '__main__':
linear_model1()
linear_model2()
linear_model3()
5、嶺回歸代碼運行結果:
6、可以釋放之前注釋的代碼,并注釋掉多余部分,進行多種方法運行結果的簡單對比。