如何对分类问题执行弹性网?

How to perform elastic-net for a classification problem?

我是菜鸟,之前曾使用正则化方法解决过线性回归问题。这一切都非常简单,但我现在想在分类问题上使用弹性网。

我有 运行 基线逻辑回归模型,预测分数不错(准确性和 f1 分数约为 80%)。我知道我的一些输入特征是高度相关的,我怀疑我引入了多重共线性,因此我想 运行 一个弹性网络来查看对系数的影响并与基线进行比较。

我进行了一些谷歌搜索,我知道我需要对正则化逻辑回归模型使用 SGDClassifier 函数。这是执行此分析的最佳方法吗?谁能指出我使用交叉验证的基本示例的方向?

有趣的问题。

你的问题 真的 应该分解成多个其他问题,例如:

  • 如何判断我的数据是否共线?
  • 如何处理机器学习问题中的共线数据?
  • 如何将逻辑回归转换为 elasticnet 进行分类?

我将重点关注上面的第三个项目符号。

此外,没有示例数据,甚至没有 minimum, complete, reproducible 代码示例供我们使用,因此我将在下面做一些假设。

如何使用逻辑回归进行分类?

逻辑回归和 elasticnet 有什么区别?

首先,让我们了解一下逻辑回归与弹性网络有何不同。 This TowardsDataScience article 写的还不错,比较详细,不熟的可以看看。简而言之,

Logistic Regression does not penalize the model for its weight choices, while elasticnet includes absolute value, and squared penalization tactics which are regularized with an l1_ratio coefficient.

代码中的区别是什么?

您可以查看 source code for Logistic Regression here,但简而言之,第 794-796 行显示当惩罚类型为 elasticnet 时 alphabeta 值发生变化:

这个例子是什么意思?

下面是使用 sklearn's Logistic Regression 在代码中实现此功能的示例。一些注意事项:

  • 我正在按要求使用交叉验证,并将其设置为 3 折
  • 我对这种性能持保留态度——有很多特征工程需要完成,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: 
# 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 没有提供。