【问题标题】:sklearn.linear_model.LogisticRegression returns different coefficients every time although random_state is setsklearn.linear_model.LogisticRegression 每次返回不同的系数,尽管设置了 random_state
【发布时间】:2014-06-26 07:10:42
【问题描述】:

我正在拟合逻辑回归模型并将随机状态设置为固定值。

每次“拟合”时,我都会得到不同的系数,例如:

classifier_instance.fit(train_examples_features, train_examples_labels)
LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
          intercept_scaling=1, penalty='l2', random_state=1, tol=0.0001)

>>> classifier_instance.raw_coef_
array([[ 0.071101940040772596  ,  0.05143724979709707323,  0.071101940040772596  , -0.04089477198935181912, -0.0407380696457252528 ,  0.03622160087086594843,  0.01055345545606742319,
         0.01071861708285645406, -0.36248634699444892693, -0.06159019047096317423,  0.02370064668025737009,  0.02370064668025737009, -0.03159781822495803805,  0.11221150783553821006,
         0.02728295348681779309,  0.071101940040772596  ,  0.071101940040772596  ,  0.                    ,  0.10882033432637286396,  0.64630314505709030026,  0.09617956519989406816,
         0.0604133873444507169 ,  0.                    ,  0.04111685986987245051,  0.                    ,  0.                    ,  0.18312324521915510078,  0.071101940040772596  ,
         0.071101940040772596  ,  0.                    , -0.59561802045324663268, -0.61490898457874587635,  1.07812569991461248975,  0.071101940040772596  ]])

classifier_instance.fit(train_examples_features, train_examples_labels)
LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
          intercept_scaling=1, penalty='l2', random_state=1, tol=0.0001)

>>> classifier_instance.raw_coef_
array([[ 0.07110193825129411394,  0.05143724970282205489,  0.07110193825129411394, -0.04089477178162870957, -0.04073806899140903354,  0.03622160048165772028,  0.010553455400928528  ,
         0.01071860364222424096, -0.36248635488413910588, -0.06159021545062405567,  0.02370064608376460866,  0.02370064608376460866, -0.03159783710841745225,  0.11221149816037970237,
         0.02728295411479400578,  0.07110193825129411394,  0.07110193825129411394,  0.                    ,  0.10882033461822394893,  0.64630314701686075729,  0.09617956493834901865,
         0.06041338563697066372,  0.                    ,  0.04111676713793514099,  0.                    ,  0.                    ,  0.18312324401049043243,  0.07110193825129411394,
         0.07110193825129411394,  0.                    , -0.59561803345113684127, -0.61490899867901249731,  1.07812569539027203191,  0.07110193825129411394]])

我使用的是 0.14 版,文档指定“底层 C 实现在拟合模型时使用随机数生成器来选择特征。因此,对于相同的输入数据,结果略有不同的情况并不少见。如果发生这种情况,请尝试使用较小的 tol 参数。”

我认为设置随机状态可以确保没有随机性,但显然情况并非如此。这是错误还是期望的行为?

【问题讨论】:

  • 我还注意到,有时这种行为在“运行”之间会发生变化,有一次我启动 python 重复调用以适应生成不同的系数,而在其他时候我重新启动 python 我没有。很奇怪。

标签: python scikit-learn logistic-regression


【解决方案1】:

我也对这个问题感到困惑,但最终发现除了传递random_state之外,还需要调用numpy.random.seed()来设置numpy内部RNG的状态。

这是用 sklearn 0.13.1 测试的。

【讨论】:

  • 这对我有用!我们知道它为什么起作用吗?也许逻辑回归中的 srand 函数使用全局 numpy 随机种子?
  • 这对我不起作用...我使用的是 sklearn 0.19.1。 @个人电脑。您使用的是哪个 sklearn 版本?
  • 我都设置了,但结果仍然不同。您必须将它们设置为相同的值还是不同的值?有什么技巧吗?
【解决方案2】:

这并不是真正需要的,但这是一个很难解决的已知问题。问题是LogisticRegression 模型是用Liblinear 训练的,这不允许以完全稳健的方式设置其随机种子。当您明确设置 random_state 时,会尽最大努力设置 Liblinear 的随机种子,但这可能会失败。

【讨论】:

  • 如果必须具有完全相同的系数,您可以编写一个函数get_logistic_regression_coef 拟合模型并返回系数,然后使用sklearn.externals.joblib.Memory 对其进行缓存。这样,它会将给定输入的结果保存到磁盘,如果输入没有改变,它会在第二次调用时重新加载。
  • 如果在每次运行中,小数点后 6 位之后的所有数字都会发生变化,那么无论出于何种意图和目的,它们都是没有意义的,不是吗?在那些说6个小数点之后将系数四舍五入怎么样?这样结果将是确定性的。
  • @jonathans 可能仍然存在随机的侥幸,导致更大的差异。我觉得你的建议相当于隐藏问题,而不是解决问题(例如,通过在 Liblinear 中安装不同的 RNG,这很棘手但可能)。
  • 我同意,在这一点上,我正在求助于我个人可以控制的东西,直接在 Liblinear 中修复这个问题不是我觉得我有资格做的事情之一。
  • 这是否也适用于“lbfgs”和“newton-cg”求解器?
猜你喜欢
  • 2022-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-26
  • 1970-01-01
  • 1970-01-01
  • 2016-12-20
  • 1970-01-01
相关资源
最近更新 更多