初始線性回歸 - 正規方程 - 梯度下降法 - 嶺回歸

一、初始線性回歸:

1、線性回歸的定義:
線性回歸(Linear regression)是利用回歸方程(函數)一個或多個自變量(特征值)和因變量(目標值)之間關系進行建模的一種分析方式。
2、通用公式
h(w) = w1x1 + w2x2 +w3x3 ... + b = (wτ)x + b

通用公式.png

其中:w,x可以理解為矩陣:

image.png

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、運行結果:

運行結果:.png

二、導數-求導:

1、常見函數的導數:

常見函數的導數:.png

2、導數的四則運算:

導數的四則運算.png

3、矩陣(向量)求導:

矩陣(向量)求導.png

三、線性回歸的損失和優化:

1、損失函數公式:

損失函數公式.png

其中:
(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、運行結果:

image.png

3、梯度下降(Gradient Descent):

3.1、基本思想:
梯度下降法可以類比為一個下山的過程
假設這樣一個場景:一個人被困在山上,需要從山上下來(i.e.找到山的最低點,也就是山谷。但此時山上的濃霧很大,導致可視度很低)。因此,下山的路徑就無法確定,以他當前的位置為基準尋找這個位置最陡峭的地方,然后朝著山的高度下降的地方走,然后沒走一段距離,都反復采用同一個方法,最后就能成功的抵達山谷。

梯度下降法基本思想.png

梯度下降的基本過程就和下山的場景很類似:
首先,我們有一個可微分的函數,這個函數就代表著一座山
我們的目標就是找到這個函數的最小值也就是山底

根據之前的場景假設,最快的下山方式就是找到當前位置最陡峭的方向,然后沿著此方向向下走,對應到函數中,就是找到給定點的梯度,然后朝著梯度相反的方向,就能讓函數值下降的最快!因為梯度的方向就是函數值變化最快的方向。所以,我們重復利用這個方法,反復求取梯度,最后就能到達局部最小值,這就類似于我們下山的過程。而求取梯度就確定了最陡峭的方向,也就是場景中測量方向的手段。

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

如圖,經過四次的運算,也就是走了四部,基本就抵達了函數的最低點山底了:

梯度下降過程.png

(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)

我們發現,已經基本靠近函數的最小值點:

多變量函數的梯度下降.png

3.4、梯度下降公式:

梯度下降公式.png

(1)α 在梯度下降算法中被稱作 學習率或者步長,控制每一步走的距離,控制步長很重要,不能太小,也不能太大。

(2)α后面的部分決定了梯度下降的方向

(3)特點:

  • 初始點不同,獲得的最小值也不同,因此梯度下降求得的只是局部最小值;
  • 越接近最小值時,下降速度越慢;

(4)梯度下降法沒辦法保證走到最小值,可能只是極小值:

梯度下降法可能走到的值.png

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、運行結果:

梯度下降法運行結果.png

四、線性回歸的改進 - 嶺回歸(Tikhonov regularization):

1、嶺回歸是線性回歸的正則化版本,即在原來的線性回歸的cost function懲罰函數中添加正則項(regularization term):

正則項.png

以達到在你和數據的同時,使模型權重盡可能小的目的,嶺回歸代價函數:

嶺回歸代價函數.png

即:


嶺回歸代價函數.png

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、正則化程度的變化對結果的影響:

正則化程度的變化對結果的影響.png
  • 正則化力度越大,權重系數會越小
  • 正則化力度越小,權重系數會越大

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、嶺回歸代碼運行結果:

嶺回歸代碼運行結果.png

6、可以釋放之前注釋的代碼,并注釋掉多余部分,進行多種方法運行結果的簡單對比。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,250評論 6 530
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 97,923評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,041評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,475評論 1 308
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,253評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,801評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,882評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,023評論 0 285
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,530評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,494評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,639評論 1 366
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,177評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,890評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,289評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,552評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,242評論 3 389
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,626評論 2 370

推薦閱讀更多精彩內容