引言
假如現存在一個房屋價格和一些數據的關系,真實關系是:真實房子價格 = 0.02×中心區域的距離 + 0.04×城市一氧化氮濃度 + (-0.12×自住房平均房價) + 0.254×城鎮犯罪率
那么現在呢,我們隨意指定一個關系(猜測)隨機指定關系:預測房子價格 = 0.25×中心區域的距離 + 0.14×城市一氧化氮濃度 + 0.42×自住房平均房價 + 0.34×城鎮犯罪率
這樣會發現真實結果與我們預測的結果存在一定的誤差,如下圖

那么存在誤差就需要將誤差衡量出來,並盡可能減小這個誤差,就有了損失函數
正文
損失函數
定義:
- yi為第i個訓練樣本的真實值
- h(xi)為第i個訓練樣本特征值組合預測函數
- 又稱最小二乘法

優化方法:
- 正規方程
- 梯度下降法
正規方程
定義:X為特征值矩陣,y為目標值矩陣,xT為x的轉置矩陣。

優點:直接求到最好的結果
缺點:當特征過多過復雜時,求解速度太慢並且得不到結果,時間復雜度高

代碼api:
- sklearn.linear_model.LinearRegression(fit_intercept=True)
- 通過正規方程優化
- 參數
- fit_intercept:是否計算偏置(y=ax+b 此時b就是偏置)
- 屬性
- LinearRegression.coef_:回歸系數(y=ax+b 此時a就是回歸系數)
- LinearRegression.intercept_:偏置
梯度下降
定義:梯度下降法的基本思想可以類比為一個下山的過程。假設這樣一個場景:一個人被困在山上,需要從山上下來(i.e. 找到山的最低點,也就是山谷)。但此時山上的濃霧很大,導致可視度很低。因此,下山的路徑就無法確定,他必須利用自己周圍的信息去找到下山的路徑。這個時候,他就可以利用梯度下降算法來幫助自己下山。具體來說就是,以他當前的所處的位置為基准,尋找這個位置最陡峭的地方,然后朝着山的高度下降的地方走,(同理,如果我們的目標是上山,也就是爬到山頂,那么此時應該是朝着最陡峭的方向往上走)。然后每走一段距離,都反復采用同一個方法,最后就能成功的抵達山谷。

梯度下降的基本過程就和下山的場景很類似。首先,我們有一個可微分的函數。這個函數就代表着一座山。我們的目標就是找到這個函數的最小值,也就是山底。根據之前的場景假設,最快的下山的方式就是找到當前位置最陡峭的方向,然后沿着此方向向下走,對應到函數中,就是找到給定點的梯度 ,然后朝着梯度相反的方向,就能讓函數值下降的最快!因為梯度的方向就是函數值變化最快的方向。 所以,我們重復利用這個方法,反復求取梯度,最后就能到達局部的最小值,這就類似於我們下山的過程。而求取梯度就確定了最陡峭的方向,也就是場景中測量方向的手段。
梯度下降公式:

-
1)α是什么含義?
α在梯度下降算法中被稱作為學習率或者步長,意味着我們可以通過α來控制每一步走的距離,以保證不要步子跨的太大扯着蛋,哈哈,其實就是不要走太快,錯過了最低點。同時也要保證不要走的太慢,導致太陽下山了,還沒有走到山下。所以α的選擇在梯度下降法中往往是很重要的!α不能太大也不能太小,太小的話,可能導致遲遲走不到最低點,太大的話,會導致錯過最低點!

-
2)為什么梯度要乘以一個負號?
梯度前加一個負號,就意味着朝着梯度相反的方向前進!我們在前文提到,梯度的方向實際就是函數在此點上升最快的方向!而我們需要朝着下降最快的方向走,自然就是負的梯度的方向,所以此處需要加上負號
所以有了梯度下降這樣一個優化算法,回歸就有了"自動學習"的能力。優化動態圖演示

代碼api:
- sklearn.linear_model.SGDRegressor(loss="squared_loss", fit_intercept=True, learning_rate ='invscaling', eta0=0.01)
- SGDRegressor類實現了隨機梯度下降學習,它支持不同的loss函數和正則化懲罰項來擬合線性回歸模型。
- 參數:
- loss:損失類型
- loss=”squared_loss”: 普通最小二乘法
- fit_intercept:是否計算偏置
- learning_rate : string, optional
- 學習率填充
- 'constant': eta = eta0
- 'optimal': eta = 1.0 / (alpha * (t + t0)) [default]
- 'invscaling': eta = eta0 / pow(t, power_t) power_t=0.25:存在父類當中
- 對於一個常數值的學習率來說,可以使用learning_rate=’constant’ ,並使用eta0來指定學習率。
- loss:損失類型
- 屬性:
- SGDRegressor.coef_:回歸系數
- SGDRegressor.intercept_:偏置
梯度下降和正規方程的對比
| 梯度下降 | 正規方程 |
|---|---|
| 需要選擇學習率 | 不需要 |
| 需要迭代求解 | 一次運算得出 |
| 特征數量較大可以使用 | 需要計算方程,時間復雜度高O(n3) |
算法選擇依據:
- 小規模數據:
- 正規方程:LinearRegression(不能解決擬合問題)
- 嶺回歸
- 大規模數據:
- 梯度下降法:SGDRegressor
案例:波士頓房價預測
通過正規方程和梯度下降分別實現房價的預測
數據介紹


代碼
#-*- codeing = utf-8 -*-
#@Time : 2021/1/16 19:41
#@Author : 楊曉
#@File : price_predict.py
#@Software: PyCharm
'''
# 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():
# 1、獲取數據
boston = load_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)
# 5、模型評估
print("模型中的偏置為:\n",estimator.intercept_)
print("模型中的系數為:\n",estimator.coef_)
y_pre = estimator.predict(x_test)
print("預測值為:\n",y_pre)
# 5.2 評價
# 均方誤差
error = mean_squared_error(y_test,y_pre)
print("模型均方差為:\n",error)
## 梯度下降
def linear_model2():
# 1、獲取數據
boston = load_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=100)
estimator.fit(x_train,y_train)
# 5、模型評估
print("模型中的偏置為:\n",estimator.intercept_)
print("模型中的系數為:\n",estimator.coef_)
y_pre = estimator.predict(x_test)
print("預測值為:\n",y_pre)
# 5.2 評價
# 均方誤差
error = mean_squared_error(y_test,y_pre)
print("模型均方差為:\n",error)
#linear_model1()
linear_model2()
運行結果:
正規方程

梯度下降

