1、什么是線性回歸?
回歸分析(Regression analysis)是一種統計分析方法,研究自變量和因變量之間的定量關系。回歸分析不僅包括建立數學模型並估計模型參數,檢驗數學模型的可信度,也包括利用建立的模型和估計的模型參數進行預測或控制。按照輸入輸出變量關系的類型,回歸分析可以分為線性回歸和非線性回歸。
線性回歸(Linear regression) 假設樣本數據集中的輸出變量(y)與輸入變量(X)存在線性關系,即輸出變量是輸入變量的線性組合。線性模型是最簡單的模型,也是非常重要和應用廣泛的模型。
如果模型只有一個輸入變量和一個輸出變量,稱為一元線性模型,可以用一條直線來描述輸出與輸入的關系,其表達式是一元一次方程:
y = w0 + w1*x1 + e
如果模型包括兩個或多個輸入變量,則稱為多元線性模型,可以用一個平面或超平面來描述輸出與輸入的關系,其表達式是多元一次方程:
Y = w0 + w1*x1 + w2*x2+...+ wm*xm + e
采用最小二乘法(Least square method)可以通過樣本數據來估計回歸模型的參數,使模型的輸出與樣本數據之間的誤差平方和最小。
回歸分析還要進一步分析究竟能不能采用線性回歸模型,或者說線性關系的假設是否合理、線性模型是否具有良好的穩定性?這就需要使用統計分析進行顯著性檢驗,檢驗輸入與輸出變量之間的線性關系是否顯著,用線性模型來描述它們之間的關系是否恰當。
歡迎關注 Youcans 原創系列,每周更新數模筆記
Python數模筆記-PuLP庫
Python數模筆記-StatsModels統計回歸
Python數模筆記-Sklearn
Python數模筆記-NetworkX
Python數模筆記-模擬退火算法
2、SKlearn 中的線性回歸方法(sklearn.linear_model)
以機器學習的角度來看,回歸是廣泛應用的預測建模方法,線性回歸是機器學習中重要的基礎算法。SKlearn 機器學習工具包提供了豐富的線性模型學習方法,最重要和應用最廣泛的無疑是普通最小二乘法(Ordinary least squares,OLS),此外多項式回歸(Polynomial regression)、邏輯回歸(Logistic Regression)和嶺回歸(Ridge regression)也較為常用,將在本文及后續文中介紹。其它方法相對比較特殊,以下根據官網介紹給出簡要說明,普通讀者可以略過。
- 普通最小二乘法(Ordinary least squares):
以模型預測值與樣本觀測值的殘差平方和最小作為優化目標。 - 嶺回歸(Ridge regression)
在普通最小二乘法的基礎上增加懲罰因子以減少共線性的影響,以帶懲罰項(L2正則化)的殘差平方和最小作為優化目標。在指標中同時考慮了較好的學習能力以及較小的慣性能量,以避免過擬合而導致模型泛化能力差。 - Lasso 回歸(Least absolute shrinkage and selection operator)
在普通最小二乘法的基礎上增加絕對值偏差作為懲罰項(L1正則化)以減少共線性的影響,在擬合廣義線性模型的同時進行變量篩選和復雜度調整,適用於稀疏系數模型。 - 多元 Lasso 回歸(Multi-task Lasso)
用於估計多元回歸稀疏系數的線性模型。注意不是指多線程或多任務,而是指對多個輸出變量篩選出相同的特征變量(也即回歸系數整列為 0,因此該列對應的輸入變量可以被刪除)。 - 彈性網絡回歸(Elastic-Net)
引入L1和L2范數正則化而構成帶有兩種懲罰項的模型,相當於嶺回歸和 Lasso 回歸的組合。 - Multi-task Elastic-Net
用於估計多元回歸稀疏系數線性模型的彈性網絡回歸方法。 - 最小角回歸算法(Least Angle Regression)
結合前向梯度算法和前向選擇算法,在保留前向梯度算法的精確性的同時簡化迭代過程。每次選擇都加入一個與相關度最高的自變量,最多 m步就可以完成求解。特別適合於特征維度遠高於樣本數的情況。 - LARS Lasso
使用最小角回歸算法求解 Lasso模型。 - 正交匹配追蹤法(Orthogonal Matching Pursuit)
用於具有非零系數變量數約束的近似線性模型。在分解的每一步進行正交化處理,選擇刪除與當前殘差最大相關的列,反復迭代達到所需的稀疏程度。 - 貝葉斯回歸(Bayesian Regression)
用貝葉斯推斷方法求解的線性回歸模型,具有貝葉斯統計模型的基本性質,可以求解權重系數的概率密度函數。可以被用於觀測數據較少但要求提供后驗分布的問題,例如對物理常數的精確估計;也可以用於變量篩選和降維。 - 邏輯回歸(Logistic Regression)
邏輯回歸是一種廣義線性模型,研究順序變量或屬性變量作為輸出的問題,實際是一種分類方法。通過線性模型加Sigmoid映射函數,將線性模型連續型輸出變換為離散值。常用於估計某種事物的可能性,如尋找危險因素、預測發病概率、判斷患病概率,是流行病學和醫學中最常用的分析方法。 - 廣義線性回歸(Generalized Linear Regression)
廣義線性回歸是線性回歸模型的推廣,實際上是非線性模型。通過單調可微的聯結函數,建立輸出變量與輸入變量的線性關系,將問題簡潔直接地轉化為線性模型來處理。 - 隨機梯度下降(Stochastic Gradient Descent)
梯度下降是一種基於搜索的最優化方法,用梯度下降法來求損失函數最小時的參數估計值,適用樣本數(和特征數)非常非常大的情況。隨機梯度下降法在計算下降方向時,隨機選一個數據進行計算,而不是掃描全部訓練數據集,加快了迭代速度。 - 感知機(Perceptron)
感知機是一種適合大規模學習的簡單分類算法。訓練速度比SGD稍快,並且產生的模型更稀疏。 - 被動攻擊算法(Passive Aggressive Algorithms)
被動攻擊算法是一類用於大規模學習的算法。 - 魯棒性回歸(Robustness regression)
魯棒性回歸的目的是在存在損壞數據的情況下擬合回歸模型,如存在異常值或錯誤的情況。 - 多項式回歸(Polynomial regression)
多項式回歸通過構造特征變量的多項式來擴展簡單的線性回歸模型。例如將特征變量組合成二階多項式,可以將拋物面擬合到數據中,從而具有更廣泛的靈活性和適應性。
3、SKlearn 中的最小二乘線性回歸方法
3.1 最小二乘線性回歸類(LinearRegression )
SKlearn 包中的 LinearRegression() 方法,不宜從字面理解為線性回歸方法, LinearRegression() 僅指基於普通最小二乘法(OLS)的線性回歸方法。
sklearn.linear_model.LinearRegression 類是 OLS 線性回歸算法的具體實現,官網介紹詳見:https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html#sklearn.linear_model.LinearRegression
sklearn.linear_model.LinearRegression()
class sklearn.linear_model.LinearRegression(*, fit_intercept=True, normalize=False, copy_X=True, n_jobs=None, positive=False)
LinearRegression() 類的參數不多,通常幾乎不需要設置。
- fit_intercept:bool, default=True 是否計算截距。默認值 True,計算截距。
- normalize:bool, default=False 是否進行數據標准化,該參數僅在 fit_intercept = True 時有效。
- n_jobs:int, default=None 計算時設置的任務數,為 n>1和大規模問題提供加速。默認值 任務數為 1。
LinearRegression() 類的主要屬性:
- coef_: 線性系數,即模型參數 w1... 的估計值
- intercept_: 截距,即模型參數 w0 的估計值
LinearRegression() 類的主要方法:
- fit(X,y[,sample_weight]) 用樣本集(X, y)訓練模型。sample_weight 為每個樣本設權重,默認None。
- get_params([deep]) 獲取模型參數。注意不是指模型回歸系數,而是指fit_intercept,normalize等參數。
- predict(X) 用訓練的模型預測數據集 X 的輸出。即可以對訓練樣本給出模型輸出結果,也可以對測試樣本給出預測結果。
- score(X,y[,sample_weight]) R2 判定系數,是常用的模型評價指標。
3.2 一元線性回歸
LinearRegression 使用例程:
# skl_LinearR_v1a.py
# Demo of linear regression by scikit-learn
# Copyright 2021 YouCans, XUPT
# Crated:2021-05-12
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score, mean_squared_error, mean_absolute_error, median_absolute_error
# 生成測試數據:
nSample = 100
x = np.linspace(0, 10, nSample) # 起點為 0,終點為 10,均分為 nSample個點
e = np.random.normal(size=len(x)) # 正態分布隨機數
y = 2.36 + 1.58 * x + e # y = b0 + b1*x1
# 按照模型要求進行數據轉換:輸入是 array類型的 n*m 矩陣,輸出是 array類型的 n*1 數組
x = x.reshape(-1, 1) # 輸入轉換為 n行 1列(多元回歸則為多列)的二維數組
y = y.reshape(-1, 1) # 輸出轉換為 n行1列的二維數組
# print(x.shape,y.shape)
# 一元線性回歸:最小二乘法(OLS)
modelRegL = LinearRegression() # 創建線性回歸模型
modelRegL.fit(x, y) # 模型訓練:數據擬合
yFit = modelRegL.predict(x) # 用回歸模型來預測輸出
# 輸出回歸結果 XUPT
print('回歸截距: w0={}'.format(modelRegL.intercept_)) # w0: 截距
print('回歸系數: w1={}'.format(modelRegL.coef_)) # w1,..wm: 回歸系數
# 回歸模型的評價指標 YouCans
print('R2 確定系數:{:.4f}'.format(modelRegL.score(x, y))) # R2 判定系數
print('均方誤差:{:.4f}'.format(mean_squared_error(y, yFit))) # MSE 均方誤差
print('平均絕對值誤差:{:.4f}'.format(mean_absolute_error(y, yFit))) # MAE 平均絕對誤差
print('中位絕對值誤差:{:.4f}'.format(median_absolute_error(y, yFit))) # 中值絕對誤差
# 繪圖:原始數據點,擬合曲線
fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(x, y, 'o', label="data") # 原始數據
ax.plot(x, yFit, 'r-', label="OLS") # 擬合數據
ax.legend(loc='best') # 顯示圖例
plt.title('Linear regression by SKlearn (Youcans)')
plt.show() # YouCans, XUPT
#=== 關注 Youcans,分享更多原創系列 https://www.cnblogs.com/youcans/ ===
程序說明:
- 線性回歸模型 LinearRegression() 類在模型訓練 modelRegL.fit(x, y) 時,要求輸入 x 和輸出 y 數據格式為 array類型的 n*m 矩陣。一元回歸模型 m=1,也要轉換為 n*1 的 array類型:
x = x.reshape(-1, 1) # 輸入轉換為 n行 1列(多元回歸則為多列)的二維數組
y = y.reshape(-1, 1) # 輸出轉換為 n行1列的二維數組
- LinearRegression() 類提供的模型評價指標只有 R2指標,但在 sklearn.metrics 包中提供了均方誤差、平均絕對值誤差和中位絕對值誤差,例程中給出了其使用方法。
程序運行結果:
回歸截距: w0=[2.45152704]
回歸系數: w1=[[1.57077698]]
R2 確定系數:0.9562
均方誤差:0.9620
平均絕對值誤差:0.7905
中位絕對值誤差:0.6732
3.2 多元線性回歸
用 LinearRegression() 解決多元線性回歸問題與一元線性回歸的步驟、參數和屬性都是相同的,只是要注意樣本數據的格式要求:輸入數據 X 是 array 類型的 n*m 二維數組,輸出數據 y 是 array類型的 n*1 數組(也可以用 n*k 表示多變量輸出)。
問題描述:
數據文件 toothpaste.csv 中收集了 30個月牙膏銷售量、價格、廣告費用及同期的市場均價。
(1)分析牙膏銷售量與價格、廣告投入之間的關系,建立數學模型;
(2)估計所建立數學模型的參數,進行統計分析;
(3)利用擬合模型,預測在不同價格和廣告費用下的牙膏銷售量。
需要說明的是,本文例程並不是問題最佳的求解方法和結果,只是使用該問題及數據示范讀取數據文件和數據處理的方法。
LinearRegression 使用例程:
# skl_LinearR_v1b.py
# Demo of linear regression by scikit-learn
# v1.0d: 線性回歸模型(SKlearn)求解
# Copyright 2021 YouCans, XUPT
# Crated:2021-05-12
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import stats
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, mean_absolute_error, median_absolute_error
# 主程序
# === 關注 Youcans,分享更多原創系列 https://www.cnblogs.com/youcans/ ===
def main(): # 主程序
# 讀取數據文件
readPath = "../data/toothpaste.csv" # 數據文件的地址和文件名
dfOpenFile = pd.read_csv(readPath, header=0, sep=",") # 間隔符為逗號,首行為標題行
dfData = dfOpenFile.dropna() # 刪除含有缺失值的數據
print(dfData.head())
# Model 1:Y = b0 + b1*X1 + b2*X2 + e
# 線性回歸:分析因變量 Y(sales) 與 自變量 x1(diffrence)、x2(advertise) 的關系
# 按照模型要求進行數據轉換:輸入是 array類型的 n*m 矩陣,輸出是 array類型的 n*1 數組
feature_cols = ['difference', 'advertise'] # 創建特征列表
X = dfData[feature_cols] # 使用列表選擇樣本數據的特征子集
y = dfData['sales'] # 選擇樣本數據的輸出變量
# print(type(X),type(y))
# print(X.shape, y.shape)
# 一元線性回歸:最小二乘法(OLS)
modelRegL = LinearRegression() # 創建線性回歸模型
modelRegL.fit(X, y) # 模型訓練:數據擬合
yFit = modelRegL.predict(X) # 用回歸模型來預測輸出
# 輸出回歸結果 # YouCans, XUPT
print("\nModel1: Y = b0 + b1*x1 + b2*x2")
print('回歸截距: w0={}'.format(modelRegL.intercept_)) # w0: 截距
print('回歸系數: w1={}'.format(modelRegL.coef_)) # w1,..wm: 回歸系數
# 回歸模型的評價指標
print('R2 確定系數:{:.4f}'.format(modelRegL.score(X, y))) # R2 判定系數
print('均方誤差:{:.4f}'.format(mean_squared_error(y, yFit))) # MSE 均方誤差
print('平均絕對值誤差:{:.4f}'.format(mean_absolute_error(y, yFit))) # MAE 平均絕對誤差
print('中位絕對值誤差:{:.4f}'.format(median_absolute_error(y, yFit))) # 中值絕對誤差
# Model 3:Y = b0 + b1*X1 + b2*X2 + b3*X2**2 + e
# 線性回歸:分析因變量 Y(sales) 與 自變量 x1、x2 及 x2平方的關系
x1 = dfData['difference'] # 價格差,x4 = x1 - x2
x2 = dfData['advertise'] # 廣告費
x5 = x2**2 # 廣告費的二次元
X = np.column_stack((x1,x2,x5)) # [x1,x2,x2**2]
# 多元線性回歸:最小二乘法(OLS)
modelRegM = LinearRegression() # 創建線性回歸模型
modelRegM.fit(X, y) # 模型訓練:數據擬合
yFit = modelRegM.predict(X) # 用回歸模型來預測輸出
# 輸出回歸結果 # YouCans, XUPT
print("\nModel3: Y = b0 + b1*x1 + b2*x2 + b3*x2**2")
print('回歸截距: w0={}'.format(modelRegM.intercept_)) # w0: 截距, YouCans
print('回歸系數: w1={}'.format(modelRegM.coef_)) # w1,..wm: 回歸系數, XUPT
# 回歸模型的評價指標
print('R2 確定系數:{:.4f}'.format(modelRegM.score(X, y))) # R2 判定系數
print('均方誤差:{:.4f}'.format(mean_squared_error(y, yFit))) # MSE 均方誤差
print('平均絕對值誤差:{:.4f}'.format(mean_absolute_error(y, yFit))) # MAE 平均絕對誤差
print('中位絕對值誤差:{:.4f}'.format(median_absolute_error(y, yFit))) # 中值絕對誤差
# 計算 F統計量 和 F檢驗的 P值
m = X.shape[1]
n = X.shape[0]
yMean = np.mean(y)
SST = sum((y-yMean)**2) # SST: 總平方和
SSR = sum((yFit-yMean)**2) # SSR: 回歸平方和
SSE = sum((y-yFit)**2) # SSE: 殘差平方和
Fstats = (SSR/m) / (SSE/(n-m-1)) # F 統計量
probFstats = stats.f.sf(Fstats, m, n-m-1) # F檢驗的 P值
print('F統計量:{:.4f}'.format(Fstats))
print('FF檢驗的P值:{:.4e}'.format(probFstats))
# 繪圖:原始數據點,擬合曲線
fig, ax = plt.subplots(figsize=(8, 6)) # YouCans, XUPT
ax.plot(range(len(y)), y, 'b-.', label='Sample') # 樣本數據
ax.plot(range(len(y)), yFit, 'r-', label='Fitting') # 擬合數據
ax.legend(loc='best') # 顯示圖例
plt.title('Regression analysis with sales of toothpaste by SKlearn')
plt.xlabel('period')
plt.ylabel('sales')
plt.show()
return
# === 關注 Youcans,分享更多原創系列 https://www.cnblogs.com/youcans/ ===
if __name__ == '__main__':
main()
程序運行結果:
Model1: Y = b0 + b1*x1 + b2*x2
回歸截距: w0=4.4074933246887875
回歸系數: w1=[1.58828573 0.56348229]
R2 確定系數:0.8860
均方誤差:0.0511
平均絕對值誤差:0.1676
中位絕對值誤差:0.1187
Model3: Y = b0 + b1*x1 + b2*x2 + b3*x2**2
回歸截距: w0=17.324368548878198
回歸系數: w1=[ 1.30698873 -3.69558671 0.34861167]
R2 確定系數:0.9054
均方誤差:0.0424
平均絕對值誤差:0.1733
中位絕對值誤差:0.1570
F統計量:82.9409
F檢驗的P值:1.9438e-13
程序說明:
- 用 LinearRegression() 類處理多元線性回歸問題,模型對訓練樣本數據的格式要求為:輸入數據 X 是 array 類型的 n*m 二維數組,輸出數據 y 是 array類型的 n*1 數組(也可以用 n*k 表示多變量輸出)。例程中給出了兩種數據轉換的方式:Model 1 從 Pandas 的 dataframe 數據轉換得到模型要求的 array 類型二維數組,這在 Pandas 讀取數據文件時非常方便;Model3 則用 Numpy 的 np.column_stack 數組拼接獲得 array 類型二維數組。
- 本例程的問題和數據《Python學習筆記-StatsModels 統計回歸(3)模型數據的准備》中相同,來自:姜啟源、謝金星《數學模型(第 3版)》,高等教育出版社。
- 為了便於與 StatsModels 統計回歸結果進行比較,例程所采用的模型也與該文一致:Model1 中使用特征變量 'difference', 'advertise' 建立線性回歸模型,Model3 中使用特征變量 'difference', 'advertise' 及 'advertise' 的二次項( x2**2)建立線性回歸模型。SKlearn 與 StatsModels 對這兩個模型的參數估計結果、預測結果和 R2確定系數都完全相同,表明用 SKlearn 與 StatsModels 工具包都可以實現線性回歸。
- StatsModels 工具包提供的模型檢驗的指標非常全面、詳細,對模型檢驗和統計分析非常重要。而 SKlearn 包所提供的統計檢驗指標很少,F檢驗、T 檢驗、相關系數的顯著性檢驗指標都沒有,根本原因在於 SKlearn 是機器學習庫而非統計工具箱,關注點是模型精度和預測性能,而不在於模型的顯著性。
- 為了解決缺少模型顯著性檢驗指標的問題,例程中增加了一段 計算 F統計量 和 F檢驗P值 的程序可供參考。
版權說明:
本文內容及例程為作者原創,並非轉載書籍或網絡內容。
YouCans 原創作品
Copyright 2021 YouCans, XUPT
Crated:2021-05-12
歡迎關注 Youcans 原創系列,每周更新數模筆記
Python數模筆記-PuLP庫(1)線性規划入門
Python數模筆記-PuLP庫(2)線性規划進階
Python數模筆記-PuLP庫(3)線性規划實例
Python數模筆記-Scipy庫(1)線性規划問題
Python數模筆記-StatsModels 統計回歸(1)簡介
Python數模筆記-StatsModels 統計回歸(2)線性回歸
Python數模筆記-StatsModels 統計回歸(3)模型數據的准備
Python數模筆記-StatsModels 統計回歸(4)可視化
Python數模筆記-Sklearn (1)介紹
Python數模筆記-Sklearn (2)聚類分析
Python數模筆記-Sklearn (3)主成分分析
Python數模筆記-Sklearn (4)線性回歸
Python數模筆記-Sklearn (5)支持向量機
Python數模筆記-NetworkX(1)圖的操作
Python數模筆記-NetworkX(2)最短路徑
Python數模筆記-NetworkX(3)條件最短路徑
Python數模筆記-模擬退火算法(1)多變量函數優化
Python數模筆記-模擬退火算法(2)約束條件的處理
Python數模筆記-模擬退火算法(3)整數規划問題
Python數模筆記-模擬退火算法(4)旅行商問題