如何为分类问题执行弹性网络? 逻辑回归和弹性网之间有什么区别?代码中的区别是什么?这对于示例来说意味着什么?

问题描述

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

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

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

解决方法

有趣的问题。

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

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

我将关注上面的第三个要点。

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

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

逻辑回归和弹性网之间有什么区别?

首先,让我们了解逻辑回归与弹性网络的不同之处This TowardsDataScience article 写得相当好,详细介绍了一点,如果您不熟悉,您应该查看它。总之,

逻辑回归不会因其权重选择而惩罚模型,而弹性网络包括绝对值和用 l1_ratio 系数正则化的平方惩罚策略。

代码中的区别是什么?

您可以查看 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: https://stackoverflow.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 没有提供。