Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何用LibSVM格式训练的Spark-MLlib模型进行预测_Scala_Apache Spark_Machine Learning_Apache Spark Mllib - Fatal编程技术网

Scala 如何用LibSVM格式训练的Spark-MLlib模型进行预测

Scala 如何用LibSVM格式训练的Spark-MLlib模型进行预测,scala,apache-spark,machine-learning,apache-spark-mllib,Scala,Apache Spark,Machine Learning,Apache Spark Mllib,我使用一个训练数据文件来训练我的模型,该文件采用LibSVM格式,如下所述。具体来说,我使用了这个部分 val data = MLUtils.loadLibSVMFile(sc, "data/mllib/sample_libsvm_data.txt") // Split data into training (60%) and test (40%). val splits = data.randomSplit(Array(0.6, 0.4), seed = 11L) val training

我使用一个训练数据文件来训练我的模型,该文件采用LibSVM格式,如下所述。具体来说,我使用了这个部分

val data = MLUtils.loadLibSVMFile(sc, "data/mllib/sample_libsvm_data.txt")

// Split data into training (60%) and test (40%).
val splits = data.randomSplit(Array(0.6, 0.4), seed = 11L)
val training = splits(0).cache()
val test = splits(1)

// Run training algorithm to build the model
val model = new LogisticRegressionWithLBFGS()
  .setNumClasses(10)
  .run(training)
但我的问题是,如何在预测时为这样训练的模型准备特征?我提出的解决方案是以libsvm格式保存一个中间文件(由于我只想预测,所以使用虚拟标签),然后使用
MLUtils.loadLibSVMFile
加载它,然后将结果应用到训练过的模型中进行预测。但是,这种策略效率很低,在我的系统中,这需要一个非常昂贵的
collect()
调用。是否有任何方法可以将我的数据以正确的
LabeledPoint
格式放置,而无需先将其放置在LibSVM格式中(这需要一个中间文件)?我希望我不必深入研究
MLUtils.loadLibSVMFile
的内部结构来找出libSVM格式的行如何转换为
LabeledPoint
对象


PS:看起来Spark的ML管道是一种更好的方法,但如果我能帮上忙的话,我不想放弃我迄今为止所做的所有工作,尝试这种策略。

当你完成了模型训练,只想用它来预测时,你不需要将数据设置为
标签点
格式。唯一需要的是一个向量(密集或稀疏,请参阅以了解更多信息)来进行预测

val prediction = model.predict(features)
当然,也可以转换为
标签点
,尽管不是必需的。一个小例子:

val rdd = sc.parallelize(Array(
    (1, List(1.0,4.0,8.0)),
    (2, List(3.0,3.0,8.0)),
    (3, List(5.0,5.0,9.0))))

val rdd2 = rdd.map{ case(k, vs) => 
  LabeledPoint(k.toDouble, Vectors.dense(vs.toArray))
}

可以在LibSVM格式和Spark向量之间进行转换。在LibSVM文件中,每一行的格式如下:

<label> <index1>:<value1> <index2>:<value2> ... <indexN>:<valueN>
示例中使用了
SparseVector
,因为LibSVM文件同时指定了索引和值

在LibSVM中,索引从1开始,而更常见的约定(包括创建
SparseVector
)是从0开始,因此,在从LibSVM格式转换时,有必要从索引中减去1


接下来,您可以轻松地自己创建向量来进行预测。

是的,但我的问题更多的是关于如何创建此向量。特征向量元素的顺序很重要。如果预测时的顺序与训练时的顺序不同,则预测将偏离很远。那么,您如何知道预测时特征向量元素的顺序与训练时从libsvm文件生成的
MLUtils.loadLibSVMFile
的顺序相同呢?@user1893354在回答您的问题时添加了额外的信息。是的,这回答了我的问题-但我希望Spark会有更多的是一个内置的解决方案。顺便说一句,我深入研究了代码,代码和libsvm索引从1开始,但读取时,spark会从每个索引中减去1,因此最终向量中的索引实际上应该是libsvm索引-1(您可能希望将其添加到您的答案中)。实际上,如果您能够创建libsvm文件,是什么阻止你自己创建向量并在预测中使用它们?你已经把你的特征放进了文件,所以它们应该已经准备好了…?@Shaido-是的,我知道如何把特征放进文件中-只是不知道如何从文件中读取它们并转换成最终传递给模型的向量。我可以深入研究
MLUtils.loadLibSVMFile
来解决这个问题,但我希望我不必这么做(但我最终做到了)
val prediction = model.predict(features)