【问题标题】:partial_fit with SGDClassifier gives fluctuating accuracy带有 SGDClassifier 的 partial_fit 给出了波动的精度
【发布时间】:2017-10-15 17:45:30
【问题描述】:

我的数据在一个稀疏矩阵中。在开始大计算之前,我现在首先处理大约 500k 行的子集。数据是二元计数加上熵和字符串长度,完整的数据集包含数以百万计的行乘以 1400 列。该模型旨在帮助表征这些字符串,因此我使用SGDClassifier 进行逻辑回归。

由于我决定在我的SGDClassifier 上使用partial_fit,但我在每个时期得到的计算出的area-under-curve 值似乎波动很大。

这是我的代码:

from sklearn.linear_model import SGDClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score
model = SGDClassifier(loss='log', alpha=1e-10, n_iter=50, n_jobs=-1, shuffle=True)
for f in file_list:
    data = dill.load(open(f))
    X_train, X_test, y_train, y_test = train_test_split(data, labels, test_size=0.2)
    X_train, X_holdout, y_train, y_holdout = train_test_split(data, labels, test_size=0.05)
    for ep in range(max_epoch):
        model.partial_fit(X_train, y_train, classes=np.unique(y_train))

        # Calculate Area under ROC curve to see if things improve
        probs = model.predict_proba(X_holdout)
        auc   = roc_auc_score(y_holdout, [x[1] for x in probs])

        if auc > best_auc: best_auc = auc
        print('Epoch: %d - auc: %.2f (best %.2f)' %(ep, auc, best_auc))

发生的情况是 auc 迅速上升到 ~0.9,但随后波动很大。有时它甚至会下降到 ~0.5-0.6,然后再回升。我认为更合乎逻辑的auc 应该随着每个时期继续增加,只有很小的下降可能,直到它找到一个平衡值,更多的训练几乎不会改善任何东西。

我做错了什么,或者这可能是partial_fit 的“正常”行为?当我在较小的数据集上使用 fit 时,我从未见过这种行为。

【问题讨论】:

  • 上面发布的代码对我来说似乎是错误的。您将相同的数据和标签拆分两次(使用 train_test_split),这将再次为 X_train 分配新数据,但不是 y_train 将包含来自第一次拆分的值。你确定这是你想要做的吗?
  • 输入错误,我正在另一台计算机上编写代码,而不是代码所在的计算机。
  • 好的。为什么在roc_auc_score 中使用[x[1] for x in probs] 表示y_pred?您可以在其中使用probs
  • 因为 probs 每个类都有两列,当我尝试简单地输入 probe 时,我得到一个 ValueError: bad input shape ...
  • 嘿@Tobias 你解决了这个问题吗?我面临着类似的问题

标签: python scikit-learn partial logistic-regression auc


【解决方案1】:

通常,partial_fit 在准确度上倾向于reductionfluctuation。在某种程度上,可以通过改组和提供整个数据集的一小部分来稍微缓解这种情况。但是,对于更大的数据,在线训练似乎只会降低准确性,使用 SGDClassifier/SVM 分类器。

我尝试使用它并发现使用低学习率有时可以帮助我们。粗略的类比是,在大数据上重复训练相同的模型时,会导致模型忘记它从以前的数据中学到的东西。因此,使用微小的学习率会减慢学习和遗忘的速度!

我们可以使用adaptive 提供的sklearn 学习率功能,而不是手动提供速率。注意模型初始化部分,

model = SGDClassifier(loss="hinge", penalty="l2", alpha=0.0001, max_iter=3000, tol=None, shuffle=True, verbose=0, learning_rate='adaptive', eta0=0.01, early_stopping=False)

这在 [scikit docs] 中被描述为:

‘adaptive’:eta = eta0,只要训练不断减少。如果 early_stopping 为 True,则每次 n_iter_no_change 连续 epoch 未能将训练损失减少 tol 或未能将验证分数增加 tol 时,当前学习率除以 5。

随着学习率的变化,我得到了非常好的结果(从最初的数据集第四部分从 98% 下降到 28%)到 100% 的模型准确率。

【讨论】:

    猜你喜欢
    • 2017-04-02
    • 2016-08-11
    • 2020-12-18
    • 2016-06-10
    • 1970-01-01
    • 2021-06-19
    • 2018-03-21
    • 2018-05-27
    • 2020-06-02
    相关资源
    最近更新 更多