使用SGDClassifier的partial_fit可以提供波动的准确性

时间:2017-05-16 14:56:18

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

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

由于尺寸较大,我决定在我的partial_fit上使用SGDClassifier,但我在每个时代得到的计算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时,我从未见过这种行为。

1 个答案:

答案 0 :(得分:0)

通常,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]中描述为:

“自适应”:eta = eta0,只要训练持续减少即可。每次n_iter_no_change个连续的纪元未能将训练损失减少一倍,或者如果Early_stopping为True,则未能增加鉴定分数一次,则当前学习率除以5。

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