线性回归是统计学中最基础且广泛使用的预测模型之一。它通过找到最佳拟合直线(或超平面)来描述因变量(目标变量)与自变量(预测因子)之间的关系。本文将探讨线性回归的核心理论,常见问题,如何避免这些错误,并提供一个实践案例及代码示例。
核心理论知识
- 模型假设:线性回归假设因变量与自变量之间存在线性关系,即
y = β0 + β1x1 + β2x2 + ... + βnxn + ε
,其中y
是因变量,x
是自变量,β
是权重系数,ε
是随机误差项。 - 最小二乘法:线性回归的目标是找到一组权重,使所有数据点到直线的垂直距离(残差)的平方和最小,也就是最小化损失函数(均方误差)。
- 系数估计:使用梯度下降法或正规方程(当自变量个数较少时)来求解最小化问题,得到最佳的权重
β
。
在掌握线性回归的基础之后,我们可以探索一些高阶使用技巧,以提高模型的准确性和泛化能力。
1. 多项式特征
线性回归的一个限制是它只能捕捉线性关系。在许多现实世界的问题中,因变量和自变量的关系可能是非线性的。通过创建自变量的多项式特征,我们可以将非线性关系转化为线性形式。例如,使用PolynomialFeatures
类可以轻松实现这一点:
from sklearn.preprocessing import PolynomialFeatures
poly_features = PolynomialFeatures(degree=2)
X_poly = poly_features.fit_transform(X_train)
# 使用多项式特征重新训练模型
model_poly = LinearRegression()
model_poly.fit(X_poly, y_train)
# 预测并评估
y_pred_poly = model_poly.predict(poly_features.transform(X_test))
mse_poly = mean_squared_error(y_test, y_pred_poly)
print(f"Mean Squared Error with Polynomials: {
mse_poly}")
2. 正则化
正则化是一种防止过拟合的技术,通过在损失函数中添加一个惩罚项来限制模型的复杂度。L1正则化(Lasso)和L2正则化(Ridge)是两种常见的方法。在Scikit-Learn中,可以使用Lasso
或Ridge
类实现:
from sklearn.linear_model import Lasso, Ridge
# 使用Lasso正则化
lasso_model = Lasso(alpha=0.1)
lasso_model.fit(X_train, y_train)
y_pred_lasso = lasso_model.predict(X_test)
mse_lasso = mean_squared_error(y_test, y_pred_lasso)
print(f"Mean Squared Error with Lasso: {
mse_lasso}")
# 使用Ridge正则化
ridge_model = Ridge(alpha=0.1)
ridge_model.fit(X_train, y_train)
y_pred_ridge = ridge_model.predict(X_test)
mse_ridge = mean_squared_error(y_test, y_pred_ridge)
print(f"Mean Squared Error with Ridge: {
mse_ridge}")
3. 特征选择
在具有大量特征的数据集中,特征选择可以帮助减少模型复杂度,提高模型的解释性。可以使用SelectKBest
类结合一个统计测试(如f_regression
)来选择最相关的特征:
from sklearn.feature_selection import SelectKBest, f_regression
# 选择最重要的k个特征
selector = SelectKBest(score_func=f_regression, k=2)
X_train_selected = selector.fit_transform(X_train, y_train)
X_test_selected = selector.transform(X_test)
# 使用选定的特征训练和评估模型
model_kbest = LinearRegression()
model_kbest.fit(X_train_selected, y_train)
y_pred_kbest = model_kbest.predict(X_test_selected)
mse_kbest = mean_squared_error(y_test, y_pred_kbest)
print(f"Mean Squared Error with KBest Features: {
mse_kbest}")
4. 超参数调优
使用网格搜索或随机搜索来找到最优的模型参数。GridSearchCV
和RandomizedSearchCV
可以帮助自动化这个过程:
from sklearn.model_selection import GridSearchCV, RandomizedSearchCV
# 对Ridge模型进行参数调优
ridge_params = {
'alpha': [0.1, 0.5, 1.0, 5.0, 10.0]}
ridge_search = GridSearchCV(Ridge(), ridge_params, scoring='neg_mean_squared_error', cv=5)
ridge_search.fit(X_train, y_train)
best_ridge = ridge_search.best_estimator_
y_pred_tuned = best_ridge.predict(X_test)
mse_tuned = mean_squared_error(y_test, y_pred_tuned)
print(f"Mean Squared Error with Tuned Ridge: {
mse_tuned}")
5. 分组特征
在某些情况下,数据可能存在分组结构,例如时间序列数据或按地理位置划分的数据。在这种情况下,可以使用分组线性回归,如GroupKFold
交叉验证,以更好地处理组内相关性:
from sklearn.model_selection import GroupKFold
# 假设我们有group_id变量表示数据的分组
groups = ... # 填充实际的分组ID
# 使用GroupKFold进行交叉验证
gkf = GroupKFold(n_splits=5)
mse_list = []
for train_idx, test_idx in gkf.split(X, y, groups=groups):
X_train, X_test = X[train_idx], X[test_idx]
y_train, y_test = y[train_idx], y[test_idx]
model