Nat*_*iel 1 python svm apache-spark pyspark apache-spark-mllib
我无法让我的 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)
Run Code Online (Sandbox Code Playgroud)
我说“或多或少”是因为
model.predict([0])
Out[47]: 0
Run Code Online (Sandbox Code Playgroud)
是我所期望的,而且......
model.predict([1])
Out[48]: 1
Run Code Online (Sandbox Code Playgroud)
也是我所期望的,但是......
model.predict([0.000001])
Out[49]: 1
Run Code Online (Sandbox Code Playgroud)
绝对不是我所期望的。我认为无论是什么原因造成的都是我问题的根源。
在这里,我首先处理我的数据......
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())
Run Code Online (Sandbox Code Playgroud)
......我得到了一团美丽的点云。当我绘制它们时,我会得到一个带有一点混乱区域的分区,但是任何幼儿园的孩子都可以画一条线来将它们分开。那么为什么当我尝试画一条线将它们分开时...
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))
Run Code Online (Sandbox Code Playgroud)
……只能归为一组,不能归为两组?(下面的列表显示了 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),
...
Run Code Online (Sandbox Code Playgroud)
等等。它只猜测 0,当应该有一个非常明显的划分时它应该开始猜测 1。谁能告诉我我做错了什么?谢谢你的帮助。
编辑:我不认为这是规模问题,正如其他一些有类似问题的帖子所建议的那样。我试过把所有东西都乘以 100,但我仍然遇到同样的问题。我也尝试玩弄我如何计算“骰子”变量,但我所能做的就是将 SVM 的猜测从全 0 更改为全 1。
我想出了为什么它总是预测全 1 或全 0。我需要添加这一行:
model.setThreshold(0.5)
Run Code Online (Sandbox Code Playgroud)
那修复它。使用后我想通了
model.clearThreshold()
Run Code Online (Sandbox Code Playgroud)
clearThreshold,然后是预测测试数据,告诉我计算机预测的是浮点数,而不仅仅是我最终要寻找的二进制 0 或 1。我可以看到 SVM 正在做出我认为违反直觉的舍入决定。通过使用 setThreshold,我现在可以获得更好的结果。