在简单的一维数据集上,LogisticRegressionCV选择了可怕的超参数,所得分数没有意义

问题描述 投票:1回答:1

我正在尝试使用LogisticRegressionCV将Logistic回归模型拟合到简单的1D数据集。非常奇怪的是,当给出选择时,似乎选择了一个很小的C值,这迫使我的模型选择了一个很小的theta,从而导致了一个无用的模型。

我尝试查看模型提供的scores_,但它们没有任何意义。例如,当我告诉它使用5个C值选择进行三重交叉验证时,它会给我:

{1: array([
    [0.47058824, 0.47058824, 0.47058824, 0.47058824, 0.47058824],
    [1.        , 1.        , 1.        , 1.        , 1.        ],
    [0.63636364, 0.63636364, 0.63636364, 0.63636364, 0.63636364]])}

数据集不是线性可分离的,但是无论我给它尝试了哪个C值,它都声称获得了100%的精度。

下面的示例代码:

import numpy as np
from sklearn.linear_model import LogisticRegressionCV
from sklearn.linear_model import LogisticRegression

def gen_y(x):
    p1 = np.clip(x + 0.5, 0, 1)
    v = np.random.uniform(0, 1)
    if v < p1:
        return 1
    return 0

np.random.seed(6)
x_data = np.sort(np.random.normal(0, 0.3, 100))
y_data = np.array([gen_y(x) for x in x_data])

regularized_logistic_regression_model = LogisticRegressionCV(
    Cs = np.array([10**-8, 10**-4, 1, 10**4, 10**8]), fit_intercept = False, cv = 3)

regularized_logistic_regression_model.fit(x_data.reshape(-1, 1), y_data)

print(regularized_logistic_regression_model.C_) # yields 10^-8
print(regularized_logistic_regression_model.coef_) # yields incredibly tiny value
print(regularized_logistic_regression_model.scores_) # yields nonsensical scores
machine-learning scikit-learn logistic-regression cross-validation regularized
1个回答
0
投票

两个基本错误:

  • 无拦截
  • 排序后的数据,没有改组

另外:相当小的数据集。

截距大大提高了逻辑回归的表达能力,尤其是在只有一个特征的问题中,例如此处。其default settingTrue是有原因的-除非您确切地知道自己在做什么,否则最好不要与它们混合使用。像这样在简单的单变量情况下省略截距很容易理解:它迫使回归线穿过原点(0,0)-huge约束。

在这种人工数据集的情况下,混洗尤其重要,因为在某些情况下,这些值会被排序(如此处所述)。原因是,虽然ML模型可以很好地进行插值,但是它们是extremely bad at extrapolating(预测值超出其训练范围);并使用排序的数据,您的每个验证CV折叠都会尝试使用相应训练折叠之外的数据进行预测(毫无疑问,它做得不好)。

因此,只需对数据进行混排,并使用这些数据和`fit_intercept = True,我们得到:

from sklearn.utils import shuffle

x_s, y_s = shuffle(x_data, y_data, random_state=0)

regularized_logistic_regression_model = LogisticRegressionCV(
    Cs = np.array([10**-8, 10**-4, 1, 10**4, 10**8]), fit_intercept = True, cv = 3)

regularized_logistic_regression_model.fit(x_s.reshape(-1, 1), y_s)

print(regularized_logistic_regression_model.C_) 
print(regularized_logistic_regression_model.coef_) 
print(regularized_logistic_regression_model.scores_)

结果:

[10000.]
[[4.57770177]]
{1: array([[0.61764706, 0.61764706, 0.70588235, 0.67647059, 0.67647059],
       [0.60606061, 0.60606061, 0.78787879, 0.84848485, 0.84848485],
       [0.60606061, 0.60606061, 0.57575758, 0.72727273, 0.72727273]])}

比您所报告的要明智得多。

添加更多数据(300个样本,而不是100个样本,得到)

[1.]
[[3.57243675]]
{1: array([[0.52, 0.52, 0.72, 0.72, 0.72],
       [0.52, 0.52, 0.68, 0.67, 0.67],
       [0.51, 0.51, 0.67, 0.66, 0.66]])}

最后一点:尽管通常强烈建议进行混洗,但在这里(根据定义,是人工随机数据),如果您将初始数据保持原样(即不对它们进行排序),则可以避免使用它:

x_data = np.random.normal(0, 0.3, 100) # no sorting

我将保留对此的验证作为练习。

© www.soinside.com 2019 - 2024. All rights reserved.