一元线性回归是统计学中最基础的回归分析方法,用于建立两个变量之间的线性关系模型。
1. 模型表达式
一元线性回归的数学模型为:
:因变量(预测值)
:自变量(输入变量)
:回归系数(斜率),表示xx每增加1单位时
的变化量
:截距项,表示当x=0时
的取值
2. 参数估计:最小二乘法
通过最小化预测值与实际值的**残差平方和(RSS)**求解kk和bb:
目标函数:
参数计算公式:
- 斜率k:
- 截距b:
其中,和
分别表示x和y的样本均值。
3、线性回归模型的评价
(1) MAE(平均绝对误差)
- 定义:所有样本预测值与真实值之差的绝对值的平均值。
- 公式:
- 特点:
- 单位与因变量一致,便于直观理解(如房价预测中的“万元”)。
- 对异常值不敏感,适用于需避免大误差惩罚的场景(如稳健预测)。
- 无法反映误差方向,仅衡量平均偏差大小
(2) MSE(均方误差)
- 定义:预测值与真实值之差的平方和的均值。
- 公式:
- 特点:
- 单位是原变量的平方(如“万元²”),解释性较差,但数学性质优良(连续可导)。
- 对异常值敏感,大误差会被放大,适用于需强调大误差的场景(如金融风险预测)。
(3) RMSE(均方根误差)
- 定义:MSE的平方根,将误差单位还原为原变量单位。
- 公式:
(4) R²(决定系数)
- 定义:模型解释因变量方差的比例,衡量拟合优度。
- 公式:
- 特点:
- 取值范围[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 = target
x = 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_bottom
b = 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()
### MSE
y_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