【问题标题】:Why is my Spark SVM always predicting the same label?为什么我的 Spark SVM 总是预测相同的标签?
【发布时间】:2016-01-30 04:21:51
【问题描述】:

我无法让我的 SVM 预测我期望的 0 和 1。似乎在我训练它并给它更多数据之后,它总是想预测一个 1 或一个 0,但它会预测全 1 或全 0,并且永远不会混合两者。我想知道你们中是否有人能告诉我我做错了什么。

我搜索过“svm 总是预测相同的值”和类似的问题,对于我们这些刚接触机器学习的人来说,这似乎很常见。恐怕我不明白我遇到的答案。

所以我从这个开始,它或多或少有效:

from pyspark.mllib.regression import LabeledPoint
cooked_rdd = sc.parallelize([LabeledPoint(0, [0]), LabeledPoint(1, [1])])
from pyspark.mllib.classification import SVMWithSGD
model = SVMWithSGD.train(cooked_rdd)

我说“或多或少”是因为

model.predict([0])
Out[47]: 0

是我所期望的,而且...

model.predict([1])
Out[48]: 1

也是我所期望的,但是...

model.predict([0.000001])
Out[49]: 1

绝对不是我所期望的。我认为无论是什么原因造成的都是我问题的根源。

在这里,我开始处理我的数据...

def cook_data():
  x = random()
  y = random()
  dice = 0.25 + (random() * 0.5)
  if x**2 + y**2 > dice:
    category = 0
  else:
    category = 1
  return LabeledPoint(category, [x, y])

cooked_data = []
for i in range(0,5000):
  cooked_data.append(cook_data())

...我得到了一个美丽的点云。当我绘制它们时,我得到一个带有一点混乱区域的分区,但是任何幼儿园的孩子都可以画一条线来分隔它们。那么为什么当我尝试画一条线来分隔它们时......

cooked_rdd = sc.parallelize(cooked_data)
training, testing = cooked_rdd.randomSplit([0.9, 0.1], seed = 1)
model = SVMWithSGD.train(training)
prediction_and_label = testing.map(lambda p : (model.predict(p.features), p.label))

...我只能将它们归为一组,而不是两组? (下面是一个列表,显示了 SVM 预测的元组,以及答案应该是什么。)

prediction_and_label.collect()
Out[54]: 
[(0, 1.0),
 (0, 0.0),
 (0, 0.0),
 (0, 1.0),
 (0, 0.0),
 (0, 0.0),
 (0, 1.0),
 (0, 0.0),
 (0, 1.0),
 (0, 1.0),
...

等等。它只会猜测 0,当它应该开始猜测 1 时应该有一个非常明显的划分。谁能告诉我我做错了什么?感谢您的帮助。

编辑:我不认为这是规模的问题,正如其他一些有类似问题的帖子所建议的那样。我已经尝试将所有内容乘以 100,但我仍然遇到同样的问题。我也尝试尝试计算我的“骰子”变量,但我所能做的就是将 SVM 的猜测从全 0 更改为全 1。

【问题讨论】:

    标签: python apache-spark svm pyspark apache-spark-mllib


    【解决方案1】:

    我知道为什么它总是预测全 1 或全 0。我需要添加这一行:

    model.setThreshold(0.5)
    

    这样就解决了。使用后才发现

    model.clearThreshold()
    

    clearThreshold,然后是预测测试数据,告诉我计算机预测的结果是浮点数,而不仅仅是我最终要寻找的二进制 0 或 1。我可以看到 SVM 正在做出我认为违反直觉的舍入决定。通过使用 setThreshold,我现在可以获得更好的结果。

    【讨论】:

      【解决方案2】:

      SVM 通常是一个非常依赖调优的模型,如果您选择的参数不佳,您可能会得到这种退化的行为。我建议从更直接的分类模型类型开始,例如逻辑回归或决策树/随机森林,并首先使其工作以确保您拥有正确的周围代码。

      设置完成后,如果您仍想更深入地使用 SVM,可以使用交叉验证的网格搜索来为模型和数据集找到更好的参数。关于如何做到这一点的详细信息不仅仅是一个 Stack Overflow 答案,但网上有很多关于它的好读物。

      【讨论】:

      • 实际上,我正在寻找有关 SparkMLlib 上 SVM 的交叉验证和模型选择的良好参考,尤其是 SVMWithSGD。找不到很多,有指针吗?
      猜你喜欢
      • 2020-01-17
      • 2020-01-09
      • 2016-10-18
      • 1970-01-01
      • 2016-02-18
      • 2018-09-24
      • 2019-09-09
      • 1970-01-01
      • 2021-10-06
      相关资源
      最近更新 更多