如何为分类问题执行弹性网络?
Posted
技术标签:
【中文标题】如何为分类问题执行弹性网络?【英文标题】:How to perform elastic-net for a classification problem? 【发布时间】:2021-06-21 13:33:37 【问题描述】:我是一个菜鸟,我之前使用正则化方法解决了线性回归问题。这一切都很简单,但我现在想在分类问题上使用弹性网络。
我运行了一个基线逻辑回归模型,预测分数不错(准确度和 f1 分数约为 80%)。我知道我的一些输入特征是高度相关的,我怀疑我正在引入多重共线性,因此我想运行一个弹性网络来查看对系数的影响并与基线进行比较。
我做了一些谷歌搜索,我知道我需要使用 SGDClassifier 函数来进行正则化物流回归模型。这是执行此分析的最佳方法吗?谁能指出我的交叉验证基本示例的方向?
【问题讨论】:
【参考方案1】:有趣的问题。
您的问题真的应该分解成多个其他问题,例如:
如何判断我的数据是否共线? 如何处理机器学习问题中的共线数据? 如何将逻辑回归转换为 elasticnet 进行分类?我将专注于上面的第三个项目符号。
此外,没有示例数据,甚至没有minimum, complete, reproducible
代码示例供我们参考,所以我将在下面做一些假设。
如何使用逻辑回归进行分类?
逻辑回归和elasticnet有什么区别?
首先,让我们了解逻辑回归与弹性网络有何不同。 This TowardsDataScience article 写得还算不错,细节也有一点,不熟悉的可以看一下。总之,
Logistic 回归不会因模型的权重选择而惩罚模型,而 elasticnet 包括绝对值和平方惩罚策略,这些策略用
l1_ratio
系数正则化。
这种差异在代码中是什么样的?
您可以查看source code for Logistic Regression here,但简而言之,794-796
行显示当惩罚类型为 elasticnet 时 alpha
和 beta
值会发生变化:
这个例子意味着什么?
以下是使用sklearn's Logistic Regression
在代码中实现此功能的示例。一些注意事项:
l1_ratios
等参数。这些值完全是任意的。
产生如下所示的输出:
Logistic Regression: 0.972027972027972 || Elasticnet: 0.9090909090909091
Logistic Regression
precision recall f1-score support
0 0.96 0.96 0.96 53
1 0.98 0.98 0.98 90
accuracy 0.97 143
macro avg 0.97 0.97 0.97 143
weighted avg 0.97 0.97 0.97 143
Elastic Net
precision recall f1-score support
0 0.93 0.81 0.87 53
1 0.90 0.97 0.93 90
accuracy 0.91 143
macro avg 0.92 0.89 0.90 143
weighted avg 0.91 0.91 0.91 143
代码如下:
# Load libraries
# Load a toy dataset
from sklearn.datasets import load_breast_cancer
# Load the LogisticRegression classifier
# Note, use CV for cross-validation as requested in the question
from sklearn.linear_model import LogisticRegressionCV
# Load some other sklearn functions
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
# Import other libraries
import pandas as pd, numpy as np
# Load the breast cancer dataset
X, y = load_breast_cancer(return_X_y=True, as_frame=True)
# Create your training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=2)
# Basic LogisticRegression algorithm
logistic_regression_classifier = LogisticRegressionCV(cv=3)
# SAGA should be considered more advanced and used over SAG. For more information, see: https://***.com/questions/38640109/logistic-regression-python-solvers-defintions
# Note, you should probably tune this, these values are arbitrary
elastic_net_classifier = LogisticRegressionCV(cv=3, penalty='elasticnet', l1_ratios=[0.1, 0.5, 0.9], solver='saga')
# Train the models
logistic_regression_classifier.fit(X_train, y_train)
elastic_net_classifier.fit(X_train, y_train)
# Test the models
print("Logistic Regression: || Elasticnet: ".format(logistic_regression_classifier.score(X_test, y_test), elastic_net_classifier.score(X_test, y_test)))
# Print out some more metrics
print("Logistic Regression")
print(classification_report(y_test, logistic_regression_classifier.predict(X_test)))
print("Elastic Net")
print(classification_report(y_test, elastic_net_classifier.predict(X_test)))
您还可以使用另一种方法,类似于RidgeClassifierCV
的功能,但我们需要围绕它编写一些包装器,因为sklearn
没有提供。
【讨论】:
以上是关于如何为分类问题执行弹性网络?的主要内容,如果未能解决你的问题,请参考以下文章
如何为多标签分类器/一对休息分类器腌制 sklearn 管道?