无法训练 pySpark SVM,标记点问题
Unable to train pySpark SVM, labeled point issue
我正在尝试将 spark Dataframe 转换为标记点。
Dataframe 被命名为 DF,看起来像:
+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+-----+
|step1|step2|step3|step4|step5|step6|step7|step8|step9|step10|class|
+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+-----+
| 14| 14| 0| 14| 14| 4| 11| 10| 0| 7| 1|
| 11| 10| 14| 0| 14| 18| 18| 14| 7| 7| 1|
| 14| 14| 14| 14| 14| 14| 7| 0| 7| 0| 1|
| 14| 14| 14| 14| 7| 7| 14| 14| 0| 11| 1|
| 14| 14| 14| 14| 14| 14| 14| 7| 14| 7| 1|
| 14| 14| 14| 14| 14| 14| 14| 0| 7| 7| 1|
| 14| 14| 14| 14| 14| 14| 14| 7| 14| 7| 1|
| 17| 14| 0| 7| 0| 0| 14| 7| 0| 7| 1|
| 14| 14| 14| 7| 7| 14| 7| 14| 14| 7| 1|
| 14| 14| 14| 14| 14| 14| 14| 7| 7| 7| 1|
| 7| 14| 14| 14| 14| 0| 14| 7| 0| 14| 1|
| 14| 14| 14| 14| 14| 0| 14| 7| 7| 7| 1|
根据文档,我想做的是:
(training, test) = DF.randomSplit([0.8,0.2])
print training
def parsePoint(line):
values = [float(x) for x in line.split(' ')]
return LabeledPoint(values[0], values[:1])
trainLabeled = training.rdd.map(parsePoint)
model = SVMWithSGD.train(trainLabeled, iterations=100)
但我收到错误消息:
Py4JJavaError: An error occurred while calling z:org.apache.spark.api.python.PythonRDD.runJob.
Spark 版本 2.0.1
没有看到你的数据我无法确定,但 SVMWithSGD
的一个常见问题来自标签。
您需要使用 LabeledPoint
(就像您所做的那样)并确保第一个参数为 0.0 或 1.0。错误可能来自 x[-1]
是另一个值(不是 0 也不是 1)。
你能查一下吗?
希望对您有所帮助,
pltrdy
编辑(查看数据后):
下摆。让我们回到基础:SVM(大致)"learns how to split data in two classes"(这不是很正式,但让我们暂时接受)。也就是说,您的数据集必须是:X
形状的矩阵 n x D
(n
行数,D
特征数),以及 y
包含数据标签的矩阵 n x 1
。标签是二进制的,通常表示为 {0, 1}
(或 {-1, 1}
,这对数学更方便)。
这是相当 "math" 的方法。通常你有一个 data
矩阵,你通过 "extracting" 一列作为标签在 X
和 y
之间拆分。 (此列中的所有值必须是 0、1)。
这就是说,长话短说:SVM 将根据 two 类.
对您的数据进行分类
标签(=类,其值要么是0,要么是1)可以看成是两个类别,用来拆分你的数据。所以你必须有一个只有 0 或 1 的列。
例如 如果我构建我的电影数据集,我可以设置列 "do i like it?" 和 label=1
如果我喜欢这部电影,label=0
如果我不喜欢,那么训练我的 SVM 来预测我应该喜欢哪部电影
我在您的数据中没有看到哪一列是 标签。如果你有超过 2 类,SVM 不适合你,你将不得不看一下多元分类(这超出了这里的范围,告诉我它是否是你想要的)。
我猜你的 objective 不是很清楚。例如,人们不会使用 ID 列训练分类,这几乎没有意义。如果我错了,请解释您对数据的期望。 (您还可以解释列指的是什么)。
pltrdy
我正在尝试将 spark Dataframe 转换为标记点。 Dataframe 被命名为 DF,看起来像:
+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+-----+
|step1|step2|step3|step4|step5|step6|step7|step8|step9|step10|class|
+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+-----+
| 14| 14| 0| 14| 14| 4| 11| 10| 0| 7| 1|
| 11| 10| 14| 0| 14| 18| 18| 14| 7| 7| 1|
| 14| 14| 14| 14| 14| 14| 7| 0| 7| 0| 1|
| 14| 14| 14| 14| 7| 7| 14| 14| 0| 11| 1|
| 14| 14| 14| 14| 14| 14| 14| 7| 14| 7| 1|
| 14| 14| 14| 14| 14| 14| 14| 0| 7| 7| 1|
| 14| 14| 14| 14| 14| 14| 14| 7| 14| 7| 1|
| 17| 14| 0| 7| 0| 0| 14| 7| 0| 7| 1|
| 14| 14| 14| 7| 7| 14| 7| 14| 14| 7| 1|
| 14| 14| 14| 14| 14| 14| 14| 7| 7| 7| 1|
| 7| 14| 14| 14| 14| 0| 14| 7| 0| 14| 1|
| 14| 14| 14| 14| 14| 0| 14| 7| 7| 7| 1|
根据文档,我想做的是:
(training, test) = DF.randomSplit([0.8,0.2])
print training
def parsePoint(line):
values = [float(x) for x in line.split(' ')]
return LabeledPoint(values[0], values[:1])
trainLabeled = training.rdd.map(parsePoint)
model = SVMWithSGD.train(trainLabeled, iterations=100)
但我收到错误消息:
Py4JJavaError: An error occurred while calling z:org.apache.spark.api.python.PythonRDD.runJob.
Spark 版本 2.0.1
没有看到你的数据我无法确定,但 SVMWithSGD
的一个常见问题来自标签。
您需要使用 LabeledPoint
(就像您所做的那样)并确保第一个参数为 0.0 或 1.0。错误可能来自 x[-1]
是另一个值(不是 0 也不是 1)。
你能查一下吗?
希望对您有所帮助, pltrdy
编辑(查看数据后):
下摆。让我们回到基础:SVM(大致)"learns how to split data in two classes"(这不是很正式,但让我们暂时接受)。也就是说,您的数据集必须是:X
形状的矩阵 n x D
(n
行数,D
特征数),以及 y
包含数据标签的矩阵 n x 1
。标签是二进制的,通常表示为 {0, 1}
(或 {-1, 1}
,这对数学更方便)。
这是相当 "math" 的方法。通常你有一个 data
矩阵,你通过 "extracting" 一列作为标签在 X
和 y
之间拆分。 (此列中的所有值必须是 0、1)。
这就是说,长话短说:SVM 将根据 two 类.
对您的数据进行分类标签(=类,其值要么是0,要么是1)可以看成是两个类别,用来拆分你的数据。所以你必须有一个只有 0 或 1 的列。
例如 如果我构建我的电影数据集,我可以设置列 "do i like it?" 和 label=1
如果我喜欢这部电影,label=0
如果我不喜欢,那么训练我的 SVM 来预测我应该喜欢哪部电影
我在您的数据中没有看到哪一列是 标签。如果你有超过 2 类,SVM 不适合你,你将不得不看一下多元分类(这超出了这里的范围,告诉我它是否是你想要的)。
我猜你的 objective 不是很清楚。例如,人们不会使用 ID 列训练分类,这几乎没有意义。如果我错了,请解释您对数据的期望。 (您还可以解释列指的是什么)。
pltrdy