2014-10-30 3 views
6

Ich habe irgendwo gelesen, dass lokale MLlib-Vektoren/Matrizen derzeit die Breeze-Implementierung umschließen, aber die Methoden, die MLlib in Breeze-Vektoren/Matrizen konvertieren, sind für den Bereich org.apache.spark.mllib privat. Der Vorschlag, dies zu umgehen, besteht darin, den Code in org.apache.spark.mllib.irgendetwas zu schreiben.MLlib zu Breeze-Vektoren/Matrizen sind für den Bereich org.apache.spark.mllib privat?

Gibt es einen besseren Weg, dies zu tun? Können Sie einige relevante Beispiele nennen?

Danke und Gruß,

Antwort

2

Wie ich es verstehe, wollen die Spark-Leute nicht Dritten APIs (einschließlich Breeze), so dass es leichter zu ändern, aussetzen, wenn sie sich entscheiden, von ihnen weg zu bewegen.

Sie könnten immer nur eine einfache implizite Konvertierungsklasse in dieses Paket schreiben und den Rest Ihres Codes in Ihr eigenes Paket schreiben. Nicht viel besser, als alles reinzustellen, aber es macht es ein bisschen deutlicher, warum Sie es tun.

+1

Code in das mllib.linalg Paket setzen ist keine praktikable Lösung für Kunden aus der mllib Rahmen – javadba

+1

I stimme zu, dass es doof ist, aber du musst nur eine kleine Klasse setzen (wie von @lev bezeugt), und es ist die beste Problemumgehung, die nicht die unnötige Erstellung von zusätzlichen Arrays beinhaltet, wie deine Lösung unten. – dlwh

+0

(Ich denke natürlich, sie sollten Breeze nur als "experimentell" aussetzen, wenn sie das Recht behalten wollen, es zu ändern, aber es liegt nicht in meiner Hand.) – dlwh

4

Ich habe die gleiche Lösung wie @ dlwh vorgeschlagen. Hier ist der Code, der es tut:

package org.apache.spark.mllib.linalg 

object VectorPub { 

    implicit class VectorPublications(val vector : Vector) extends AnyVal { 
    def toBreeze : breeze.linalg.Vector[scala.Double] = vector.toBreeze 

    } 

    implicit class BreezeVectorPublications(val breezeVector : breeze.linalg.Vector[Double]) extends AnyVal { 
    def fromBreeze : Vector = Vectors.fromBreeze(breezeVector) 
    } 
} 

feststellen, dass die implizite Klasse AnyVal erstreckt Zuweisung eines neuen Objekts zu verhindern, wenn diese Methoden aufrufen

+0

Dieser Code befindet sich im Paket spark mllib.linalg. Dies ist keine praktikable allgemeine Lösung für Clients des mllib-Frameworks: Sie sollten die Framework-Klassen und -Pakete nicht berühren. – javadba

+0

Es befindet sich im Paket spark.mllib.linalg, aber Spark sollte nicht neu kompiliert werden. Erstellen Sie nur eine neue Assembly, die die vorhandene Spark-Assembly umschließt, und fügen Sie diese Klasse dort hinzu. Es ist ein bisschen hacky, aber es ist das Beste, was ich gefunden habe. – lev

+0

Zeug wie das ist ein bisschen gefährlich. Wenn Sie zum Beispiel ein Stück Ihres Brise-Vektors nehmen und versuchen, es mit 'fromBreeze' zu ​​umbrechen, wird es fehlschlagen. – VF1

1

Hier ist das Beste, was ich bisher. Hinweis zu @dlwh: Bitte stellen Sie eventuell notwendige Verbesserungen bereit.

Die Lösung, die ich tun konnte, - , die keinen Programmcode gesetzt innerhalb des mllib .linalg Pakets - ist jeden Vektor auf einen neuen Breeze DenseVector zu konvertieren.

val v1 = Vectors.dense(1.0, 2.0, 3.0) 
val v2 = Vectors.dense(4.0, 5.0, 6.0) 
val bv1 = new DenseVector(v1.toArray) 
val bv2 = new DenseVector(v2.toArray) 
val vectout = Vectors.dense((bv1 + bv2).toArray) 
vectout: org.apache.spark.mllib.linalg.Vector = [5.0,7.0,9.0] 
+0

Dies scheint eine gute Lösung zu sein, zumindest funktionierte es für meinen Zweck, aber wenn wir 'v1.toArray' machen, sammeln wir alle Elemente von' v1', was möglicherweise Probleme verursachen könnte, wenn zum Beispiel 'v1' riesig ist und kann nicht in RAM passen! –

0

Diese Lösung vermeidet Code in Spark-Pakete setzen und vermeidet spärlich bis dicht Vektoren Umwandlung:

def toBreeze(vector: Vector) : breeze.linalg.Vector[scala.Double] = vector match { 
     case sv: SparseVector => new breeze.linalg.SparseVector[Double](sv.indices, sv.values, sv.size) 
     case dv: DenseVector => new breeze.linalg.DenseVector[Double](dv.values) 
    } 
Verwandte Themen