一元線性回歸是統計學中最基礎的回歸分析方法,用于建立兩個變量之間的線性關系模型。
1. 模型表達式
一元線性回歸的數學模型為:
:因變量(預測值)
:自變量(輸入變量)
:回歸系數(斜率),表示xx每增加1單位時
的變化量
:截距項,表示當x=0時
?的取值
2. 參數估計:最小二乘法
通過最小化預測值與實際值的**殘差平方和(RSS)**求解kk和bb:
目標函數:
參數計算公式:
- 斜率k:
- 截距b:
其中,和
分別表示x和y的樣本均值。
3、線性回歸模型的評價
(1) MAE(平均絕對誤差)
- 定義:所有樣本預測值與真實值之差的絕對值的平均值。
- 公式:
- 特點:
- 單位與因變量一致,便于直觀理解(如房價預測中的“萬元”)。
- 對異常值不敏感,適用于需避免大誤差懲罰的場景(如穩健預測)。
- 無法反映誤差方向,僅衡量平均偏差大小
(2) MSE(均方誤差)
- 定義:預測值與真實值之差的平方和的均值。
- 公式:
- 特點:
- 單位是原變量的平方(如“萬元2”),解釋性較差,但數學性質優良(連續可導)。
- 對異常值敏感,大誤差會被放大,適用于需強調大誤差的場景(如金融風險預測)。
(3) RMSE(均方根誤差)
- 定義:MSE的平方根,將誤差單位還原為原變量單位。
- 公式:
- 特點:
- 結合了MSE和MAE的優點:單位直觀且對大誤差敏感56。
- 常用于實際業務中(如房價預測誤差表示為“5萬美元”)
(4) R2(決定系數)
- 定義:模型解釋因變量方差的比例,衡量擬合優度。
- 公式:
?- 特點:
- 取值范圍[0,1]:越接近1,模型解釋力越強;0表示模型不優于均值預測。
- 無量綱性:不受數據量綱影響,適合跨數據集比較模型性能。
- 局限性:樣本量小時可能高估擬合效果,且不直接反映誤差大小。
4、代碼實現
(1)、手動實現線性回歸
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt###準備數據集#加載boston(波士頓房價)數據集
data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
target = raw_df.values[1::2, 2]x = data[:,5]
y = targetx = x[y<50]
y = y[y<50]#顯示
plt.scatter(x,y)
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, random_state = 0)plt.scatter(x_train, y_train)
plt.show()###一元線性回歸
def fit(x, y):a_up = np.sum((x-np.mean(x))*(y - np.mean(y)))a_bottom = np.sum((x-np.mean(x))**2)a = a_up / a_bottomb = np.mean(y) - a * np.mean(x)return a, b
a, b = fit(x_train, y_train)
print(a,b) #結果:(8.056822140369603, -28.49306872447786)#訓練回歸線
plt.scatter(x_train, y_train)
plt.plot(x_train, a*x_train+ b, c='r')
plt.show()#測試回歸線
plt.scatter(x_test, y_test)
plt.plot(x_test, a*x_test+ b, c='r')
plt.show()
(2)、sklearn 實現一元線性回歸
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt #準備數據集
data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
target = raw_df.values[1::2, 2]x=data[:,5]
y=target x=x[y<50]
y=y[y<50]#劃分數據集
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, random_state = 0)#實現回歸from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()lin_reg.fit(x_train.reshape(-1,1), y_train)y_predict = lin_reg.predict(x_test.reshape(-1,1))plt.scatter(x_test, y_test)
plt.plot(x_test, y_predict, c='r')
plt.show()
(3)、sklearn 實現多元線性回歸(注意多元不用歸一化)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt #準備數據集
data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
target = raw_df.values[1::2, 2]x=data
y=target x=x[y<50]
y=y[y<50]#劃分數據集
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, random_state = 0)#實現回歸from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()lin_reg.fit(x_train, y_train)lin_reg.score(x_test, y_test) #結果:0.7455942658788952
5、模型評價
import numpy as np
import pandas as pd
from sklearn import datasets
import matplotlib.pyplot as plt###數據準備data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep=r"\s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
target = raw_df.values[1::2, 2]x=data[:, -1].reshape(-1, 1)
y=target.reshape(-1, 1) 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, random_state = 0)###實現一元線性回歸from sklearn.linear_model import LinearRegression
linearReg = LinearRegression()
#適配數據
model = linearReg.fit(x_train, y_train)
#得到預測函數
y_predict = model.predict(x_test)
#顯示
plt.scatter(x_test, y_test, s = 10)
plt.plot(x_test, y_predict, c = 'r')
plt.show()### MSEy_real = y_test
mse = np.sum((y_real - y_predict) ** 2) / len(y_test)
print(mse )#公式計算 39.81715050474416
from sklearn.metrics import mean_squared_error
mean_squared_error(y_real, y_predict)# sklearn計算 39.81715050474416### RMSE
rmse = np.sqrt(mse)
print(rmse )#公式計算 6.310083240714354
mean_squared_error(y_real, y_predict)# sklearn計算 6.310083240714354### MAE
mae = np.sum(np.abs(y_real - y_predict)) / len(y_test)
print(mae ) #公式計算 4.4883446998468415
from sklearn.metrics import mean_absolute_error
mean_absolute_error(y_real, y_predict) # sklearn計算 4.4883446998468415###R方
r2 = 1 - (np.sum((y_real - y_predict) ** 2)) / (np.sum((y_real - np.mean(y_real)) ** 2))
print(r2) #公式計算 0.5218049526125568 等效:1 - mse / np.var(y_real)
from sklearn.metrics import r2_score
r2_score(y_real, y_predict)# sklearn計算 0.5218049526125568