【问题标题】:scikit-learn and mllib difference in predictions pythonscikit-learn 和 mllib 在预测 python 中的差异
【发布时间】:2017-05-06 08:03:03
【问题描述】:

我对使用 Spark 2.0.0 进行二进制分类训练的 SVM 模型有疑问。 我使用 scikit-learn 和 MLlib 遵循相同的逻辑,使用完全相同的数据集。 对于 scikit 学习,我有以下代码:

svc_model = SVC()
svc_model.fit(X_train, y_train)

print "supposed to be 1"
print svc_model.predict([15 ,15,0,15,15,4,12,8,0,7])
print svc_model.predict([15.0,15.0,15.0,7.0,7.0,15.0,15.0,0.0,12.0,15.0])
print svc_model.predict([15.0,15.0,7.0,0.0,7.0,0.0,15.0,15.0,15.0,15.0])
print svc_model.predict([7.0,0.0,15.0,15.0,15.0,15.0,7.0,7.0,15.0,15.0])

print "supposed to be 0"
print svc_model.predict([18.0, 15.0, 7.0, 7.0, 15.0, 0.0, 15.0, 15.0, 15.0, 15.0])
print svc_model.predict([ 11.0,13.0,7.0,10.0,7.0,13.0,7.0,19.0,7.0,7.0])
print svc_model.predict([ 15.0, 15.0, 18.0, 7.0, 15.0, 15.0, 15.0, 18.0, 7.0, 15.0])
print svc_model.predict([ 15.0, 15.0, 8.0, 0.0, 0.0, 8.0, 15.0, 15.0, 15.0, 7.0])

然后它返回:

supposed to be 1
[0]
[1]
[1]
[1]
supposed to be 0
[0]
[0]
[0]
[0]

火花正在做:

model_svm = SVMWithSGD.train(trainingData, iterations=100)

print "supposed to be 1"
print model_svm.predict(Vectors.dense(15.0,15.0,0.0,15.0,15.0,4.0,12.0,8.0,0.0,7.0))
print model_svm.predict(Vectors.dense(15.0,15.0,15.0,7.0,7.0,15.0,15.0,0.0,12.0,15.0))
print model_svm.predict(Vectors.dense(15.0,15.0,7.0,0.0,7.0,0.0,15.0,15.0,15.0,15.0))
print model_svm.predict(Vectors.dense(7.0,0.0,15.0,15.0,15.0,15.0,7.0,7.0,15.0,15.0))

print "supposed to be 0"
print model_svm.predict(Vectors.dense(18.0, 15.0, 7.0, 7.0, 15.0, 0.0, 15.0, 15.0, 15.0, 15.0))
print model_svm.predict(Vectors.dense(11.0,13.0,7.0,10.0,7.0,13.0,7.0,19.0,7.0,7.0))
print model_svm.predict(Vectors.dense(15.0, 15.0, 18.0, 7.0, 15.0, 15.0, 15.0, 18.0, 7.0, 15.0))
print model_svm.predict(Vectors.dense(15.0, 15.0, 8.0, 0.0, 0.0, 8.0, 15.0, 15.0, 15.0, 7.0))

返回:

supposed to be 1
1
1
1
1
supposed to be 0
1
1
1
1

试图保持我的正负类平衡我的测试数据包含 3521 条记录和我的训练数据 8356 条记录。对于评估,在 scikit-learn 模型上应用的交叉验证给出了 98% 的准确率,对于 spark,ROC 下的面积为 0.5,PR 下的面积为 0.74, 0.47 训练误差。

我也尝试清除阈值并将其设置回 0.5,但这并没有返回任何更好的结果。有时,当我更改训练测试拆分时,我可能会得到,即除了一个正确的预测之外的所有零或除了一个正确的零预测之外的所有零。 有谁知道如何解决这个问题?

正如我所说,我已多次检查我的数据集在两种情况下完全相同。

【问题讨论】:

    标签: python apache-spark scikit-learn apache-spark-mllib prediction


    【解决方案1】:

    Your call to clearThreshold, is causing the classifier to return the raw prediction scores:

    clearThreshold() 注意实验 清除阈值,以便 predict 输出原始预测分数。它仅用于二进制分类。

    1.4.0 版中的新功能。

    如果您只需要预测类,请删除此函数调用。

    【讨论】:

    • 我更新了我的帖子。感谢您的澄清。
    【解决方案2】:

    您使用了不同的分类器,因此得到了不同的结果。 Sklearn的SVC是一个带有RBF内核的SVM; SVMWithSGD 是一个带有使用 SGD 训练的线性内核的 SVM。它们完全不同。

    如果你想匹配结果那么我认为要走的路是使用sklearn.linear_model.SGDClassifier(loss='hinge')并尝试匹配其他参数(正则化,是否适合截距等),因为默认值不一样。

    【讨论】:

    • 但我想匹配“好”的结果。改变skicit learn 方法只会破坏整个分类。是否有可以执行相同方式的 mllib 库?
    • @Kratos 我不熟悉 mllib;似乎有一个将内核 SVM 添加到 mllib (issues.apache.org/jira/browse/SPARK-4638) 的请求请求,但它已经过时并且维护人员关闭了它。我想问题之一是带有 RBF 内核的 SVM 不能很好地随着训练示例的数量而扩展(sklearn 文档说复杂性不仅仅是二次的)。如果您需要一个可扩展的非线性分类器,我认为最好尝试随机森林(+其他相关方法,如梯度提升)或神经网络。
    猜你喜欢
    • 2015-03-11
    • 2016-04-01
    • 2020-02-01
    • 2016-04-03
    • 2021-05-25
    • 1970-01-01
    • 2015-12-19
    • 2018-01-09
    • 2018-08-12
    相关资源
    最近更新 更多