逻辑回归中的L1惩罚与稀疏性

在机器学习中,逻辑回归是一种广泛使用的分类算法。为了提高模型的泛化能力,通常会在模型中加入正则化项。L1惩罚和L2惩罚是两种常见的正则化方法,它们可以控制模型的复杂度,防止过拟合。此外,还有一种结合了L1和L2惩罚的Elastic-Net方法。本文将探讨在不同正则化参数C值下,这三种方法对模型稀疏性的影响。

稀疏性是指模型中系数为零的比例。在L1惩罚下,随着C值的减小,模型的稀疏性增加,这意味着更多的特征系数会被压缩为零。这有助于特征选择,因为只有少数重要的特征会保留在模型中。相反,L2惩罚对模型的稀疏性影响较小,它倾向于让所有特征的系数都接近于零,但不会完全为零。Elastic-Net惩罚的稀疏性介于L1和L2之间,它结合了两者的特点。

为了验证这些理论,使用了一个8x8的数字图像数据集,将数字0-4和5-9分为两个类别。通过调整C值,观察了不同惩罚方法对模型系数的影响。结果显示,当C值较大时,模型的自由度较高,稀疏性较低;而当C值较小时,模型的稀疏性增加。具体来说,当C=1.00时,三种惩罚方法的稀疏性均为4.69%,模型的准确率均为0.90。当C=0.10时,L1惩罚的稀疏性增加到29.69%,而L2惩罚的稀疏性仍然保持在4.69%。当C=0.01时,L1惩罚的稀疏性进一步增加到84.38%,而L2惩罚的稀疏性仍然很低。

这些结果表明,L1惩罚在控制模型稀疏性方面非常有效,尤其是在C值较小的情况下。这使得L1惩罚成为特征选择的理想选择。然而,L2惩罚在保持模型稳定性方面可能更有优势,因为它不会让太多的特征系数变为零。Elastic-Net惩罚则提供了一个折中的方案,它可以根据l1_ratio参数调整L1和L2惩罚的权重,以适应不同的应用场景。

为了进一步分析这些模型,使用了Python的matplotlib库来可视化模型的系数。通过比较不同C值下的系数图,可以直观地看到模型稀疏性的变化。这些图像显示了每个特征对模型的贡献程度,系数较大的特征在图像中更为明显。通过这种方式,可以更好地理解模型的工作原理,并根据需要调整正则化参数。

代码示例

import matplotlib.pyplot as plt import numpy as np from sklearn import datasets from sklearn.linear_model import LogisticRegression from sklearn.preprocessing import StandardScaler # 加载数据集 X, y = datasets.load_digits(return_X_y=True) X = StandardScaler().fit_transform(X) # 二分类问题:小数字(0-4)与大数字(5-9) y = (y > 4).astype(int) # 设置Elastic-Net正则化的L1权重 l1_ratio = 0.5 # 创建子图 fig, axes = plt.subplots(3, 3) # 设置正则化参数 for i, (C, axes_row) in enumerate(zip((1, 0.1, 0.01), axes)): # 增加容忍度以缩短训练时间 clf_l1_LR = LogisticRegression(C=C, penalty="l1", tol=0.01, solver="saga") clf_l2_LR = LogisticRegression(C=C, penalty="l2", tol=0.01, solver="saga") clf_en_LR = LogisticRegression(C=C, penalty="elasticnet", solver="saga", l1_ratio=l1_ratio, tol=0.01) clf_l1_LR.fit(X, y) clf_l2_LR.fit(X, y) clf_en_LR.fit(X, y) coef_l1_LR = clf_l1_LR.coef_.ravel() coef_l2_LR = clf_l2_LR.coef_.ravel() coef_en_LR = clf_en_LR.coef_.ravel() # 计算稀疏性 sparsity_l1_LR = np.mean(coef_l1_LR == 0) * 100 sparsity_l2_LR = np.mean(coef_l2_LR == 0) * 100 sparsity_en_LR = np.mean(coef_en_LR == 0) * 100 print(f"C={C:.2f}") print(f"Sparsity with L1 penalty: {sparsity_l1_LR:.2f}%") print(f"Sparsity with Elastic-Net penalty: {sparsity_en_LR:.2f}%") print(f"Sparsity with L2 penalty: {sparsity_l2_LR:.2f}%") print(f"Score with L1 penalty: {clf_l1_LR.score(X, y):.2f}") print(f"Score with Elastic-Net penalty: {clf_en_LR.score(X, y):.2f}") print(f"Score with L2 penalty: {clf_l2_LR.score(X, y):.2f}") if i == 0: axes_row[0].set_title("L1 penalty") axes_row[1].set_title(f"Elastic-Net\nl1_ratio={l1_ratio}") axes_row[2].set_title("L2 penalty") for ax, coefs in zip(axes_row, [coef_l1_LR, coef_en_LR, coef_l2_LR]): ax.imshow(np.abs(coefs.reshape(8, 8)), interpolation="nearest", cmap="binary", vmax=1, vmin=0) ax.set_xticks(()) ax.set_yticks(()) axes_row[0].set_ylabel(f"C={C}") plt.show()
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485