Ridge回归模型
最近做项目用到岭回归模型,特地来记录一下整个岭回归模型的原理和代码。
以后会将用到的机器学习模型算法都记录下来。
1、Ridge 回归原理
多元线性回归计算回归系数的时候回归系数的计算如下:
学过线性代数的都知道,以上式子β存在的前提是X’X可逆。
但是可能会出现自变量个数多于样本数,或者多重共线性使得X’X行列式为0。此时β不存在。
为了避免β不存在的情况,觉得加上一个L2正则项。Ridge回归的代价函数如下:
其中λ为收缩惩罚项,用于控制模型大小。
那么找到合适的λ也十分的重要,接下来就是要讨论第二个内容,交叉验证。
2、交叉验证
这次用到的是 K折交叉验证(k-fold cross validation)
K折交叉验证将数据集分为训练集和测试集,将训练集分为 K 份,每次使用 kK份中的 1 份作为验证集,其他全部作为训练集。通过 K 次训练后,我们得到了 K 个不同的模型。K次记录的平均值作为结果
可以用K折交叉验证,获取最优的λ的值。
3、实现代码
交叉验证找λ+岭回归
# 构造10到10的5次方的等比数列,计算岭回归的最佳正则化系数α
alphas = np.logspace(alpha_low, alpha_high, points)
#5倍交叉验证,shuffle=True每次划分的结果都不一样(运行两次结果不同)
raidgecv = RidgeCV(alphas = alphas, normalize = True,score = 'neg_mean_squared_error', cv = 5)
raidgecv.fit(X_train, y_train)
# 返回最佳的lambda值
best_Lambda = raidgecv.alpha_
best_Lambda
#建立岭回归模型
ridge = Ridge(alpha = ridge_best_alpha, normalize=True)
ridge.fit(X_train, y_train)
#用模型进行预测
y_hat = ridge.predict(X_test)
也可以用自己的评价指标找合适的λ,我这里是根据R2
from sklearn.model_selection import KFold
import sklearn.linear_model as linear_model
def train_and_predict_ridge(alpha, X_train, y_train, X_test):
"""
训练岭模型和预测测试集。
"""
ridge = linear_model.Ridge(alpha)
ridge.fit(X_train, y_train) #训练岭回归模型
y_hat = ridge.predict(X_test) #用模型进行预测
return y_hat
def find_best_alpha(X, y, k_inner, alphas, to_print=False):
"""
在一个完全随机的CV循环中找到最好的α。
"""
kf = KFold(n_splits=k_inner, shuffle=True)
best_alpha = 0
best_r2 = 0
for idx, alpha in enumerate(alphas):
y_hat = np.zeros_like(y)
for train_idx, test_idx in kf.split(X):
X_train, X_test = X[train_idx], X[test_idx]
y_train, y_test = y[train_idx], y[test_idx]
X_train, X_test = scale_features(X_train, X_test)
y_hat[test_idx] = train_and_predict_ridge(alpha, X_train, y_train, X_test)
#得到岭回归模型预测的结果(选择一轮交叉验证中最好的结果)
r2 = metrics.r2_score(y, y_hat) #计算R2
if r2 > best_r2:
best_alpha = alpha
best_r2 = r2
if to_print:
print(best_alpha)
return best_alpha