线性回归:原理与实现
线性回归:原理与实现
什么是线性回归
线性回归(Linear Regression)是最基础也是最经典的回归算法。它假设特征与目标变量之间存在线性关系,通过找到最佳拟合直线来预测连续值输出。
简单来说,线性回归就是要找到一条直线,使得所有数据点到这条直线的"距离"总和最小。
数学原理
单变量线性回归
假设特征 $x$ 和目标 $y$ 之间存在线性关系:
$$y = wx + b$$
其中:
- $w$ 是权重(斜率)
- $b$ 是偏置(截距)
多变量线性回归
对于多个特征,模型变为:
$$y = w_1x_1 + w_2x_2 + ... + w_nx_n + b$$
最小二乘法(OLS)
最小二乘法的目标是最小化预测值与实际值之间的均方误差(MSE):
$$MSE = \frac{1}{n}\sum_{i=1}^{n}(y_i - \hat{y}_i)^2$$
通过对损失函数求导并令其为零,可以得到最优参数的解析解。
代码示例:房价预测实战
import numpy as np
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.preprocessing import StandardScaler, PolynomialFeatures
from sklearn.pipeline import Pipeline
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
import warnings
warnings.filterwarnings('ignore')
# 生成模拟房价数据
np.random.seed(42)
n_samples = 500
area = np.random.uniform(50, 200, n_samples) # 面积
rooms = np.random.randint(1, 6, n_samples) # 房间数
age = np.random.uniform(0, 30, n_samples) # 房龄
# 房价 = 面积*3 + 房间数*10 - 房龄*2 + 噪声
price = area * 3 + rooms * 10 - age * 2 + np.random.normal(0, 20, n_samples)
X = np.column_stack([area, rooms, age])
y = price
print(f"数据集大小: {X.shape}")
print(f"特征: 面积, 房间数, 房龄")
print(f"目标: 房价")
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# --- 基础线性回归 ---
lr = LinearRegression()
lr.fit(X_train, y_train)
y_pred = lr.predict(X_test)
print("\n=== 线性回归 ===")
print(f"R² 分数: {r2_score(y_test, y_pred):.4f}")
print(f"MSE: {mean_squared_error(y_test, y_pred):.4f}")
print(f"MAE: {mean_absolute_error(y_test, y_pred):.4f}")
print(f"学到的权重: {lr.coef_}")
print(f"学到的偏置: {lr.intercept_:.4f}")
# --- 岭回归(L2正则化) ---
ridge = Ridge(alpha=1.0)
ridge.fit(X_train, y_train)
print(f"\n=== 岭回归 ===")
print(f"R² 分数: {ridge.score(X_test, y_test):.4f}")
print(f"权重: {ridge.coef_}")
# --- Lasso回归(L1正则化) ---
lasso = Lasso(alpha=1.0)
lasso.fit(X_train, y_train)
print(f"\n=== Lasso回归 ===")
print(f"R² 分数: {lasso.score(X_test, y_test):.4f}")
print(f"权重: {lasso.coef_}")
# --- 多项式回归 ---
poly_pipeline = Pipeline([
('poly', PolynomialFeatures(degree=2, include_bias=False)),
('scaler', StandardScaler()),
('lr', LinearRegression())
])
poly_pipeline.fit(X_train, y_train)
y_pred_poly = poly_pipeline.predict(X_test)
print(f"\n=== 多项式回归(2阶) ===")
print(f"R² 分数: {r2_score(y_test, y_pred_poly):.4f}")
# 交叉验证
cv_scores = cross_val_score(lr, X, y, cv=5, scoring='r2')
print(f"\n5折交叉验证 R²: {cv_scores.mean():.4f} ± {cv_scores.std():.4f}")
模型评估指标
| 指标 | 含义 | 越好 |
|---|---|---|
| R² | 解释方差比例 | 越接近1越好 |
| MSE | 均方误差 | 越小越好 |
| MAE | 平均绝对误差 | 越小越好 |
| RMSE | 均方根误差 | 越小越好 |
正则化
为防止过拟合,可以使用正则化技术:
- Ridge回归(L2):权重趋向于小值,但不会为零
- Lasso回归(L1):可以将某些权重压缩为零,实现特征选择
总结
线性回归是理解更复杂模型的基础。虽然它假设线性关系,但通过特征工程和多项式扩展,可以处理非线性问题。掌握线性回归的原理和实现,对后续学习其他回归算法大有裨益。