Python 为什么我的Spark SVM总是预测相同的标签?

Python 为什么我的Spark SVM总是预测相同的标签?,python,apache-spark,svm,pyspark,apache-spark-mllib,Python,Apache Spark,Svm,Pyspark,Apache Spark Mllib,我很难让我的SVM预测0和1的位置。似乎在我训练它并给它更多的数据之后,它总是想预测1或0,但它会预测所有1或所有0,而且永远不会两者混合。我想知道你们中是否有人能告诉我我做错了什么 我搜索过“svm总是预测相同的值”和类似的问题,对于我们这些机器学习新手来说,这似乎很常见。我恐怕我不明白我遇到的答案 所以我从这个开始,它或多或少起作用: from pyspark.mllib.regression import LabeledPoint cooked_rdd = sc.parallelize([

我很难让我的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([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预测的元组以及答案。)

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


编辑:我不认为这是一个规模问题,正如在其他一些类似问题的帖子中所建议的那样。我试着把所有的东西都乘以100,但我还是遇到了同样的问题。我也试着尝试如何计算“骰子”变量,但我所能做的就是将SVM的猜测从所有0更改为所有1。

SVM通常是一个非常依赖于调整的模型,如果参数选择不当,则可能会出现这种退化行为。我建议从一个更简单的分类模型类型开始,比如逻辑回归或决策树/随机森林,并首先让它起作用,以确保您正确使用了周围的代码


一旦设置好了,如果您仍然想更深入地使用支持向量机,您可以使用交叉验证的网格搜索为模型和数据集找到更好的参数。关于如何做到这一点的详细信息不仅仅是一个单堆栈溢出的答案,但是在网络上有很多关于它的好的阅读。

支持向量机通常是一个非常依赖于调整的模型,如果您的参数选择不当,您可能会出现这种退化行为。我建议从一个更简单的分类模型类型开始,比如逻辑回归或决策树/随机森林,并首先让它起作用,以确保您正确使用了周围的代码


一旦设置好了,如果您仍然想更深入地使用支持向量机,您可以使用交叉验证的网格搜索为模型和数据集找到更好的参数。关于如何做到这一点的详细信息不仅仅是一个单堆栈溢出的答案,但是在网络上有很多关于它的好文章。

我明白了为什么它总是预测所有1或所有0。我需要添加这一行:

model.setThreshold(0.5)
这就解决了问题。我用过之后就知道了

model.clearThreshold()

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

我明白了为什么它总是预测所有1或所有0。我需要添加这一行:

model.setThreshold(0.5)
这就解决了问题。我用过之后就知道了

model.clearThreshold()

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

实际上,我正在寻找有关SPARKMLIB上SVM的交叉验证和模型选择的良好参考,特别是SVMWithSGD。找不到太多,你有指针吗?事实上,我正在寻找关于SPARKMLIB上SVM的交叉验证和模型选择的好参考资料,特别是SVMWithSGD。找不到多少,你有指针吗?