J'ai lu quelque part que les vecteurs / matrices locales de MLLIB sont actuellement enroulement de la mise en œuvre de la brise, mais les méthodes convertissant Mllib en vecteurs / matrices de brise sont privées vers ORG.APACHE.SPARK.MLLIB. La suggestion de contourner ce problème consiste à écrire votre code dans org.apache.park.mllib.something package. P>
Y a-t-il une meilleure façon de faire cela? Pouvez-vous citer des exemples pertinents? P>
Merci et respections, p>
6 Réponses :
Si je comprends bien, les étincelles ne veulent pas exposer aux API tiers (y compris Breeze) afin qu'il soit plus facile de changer si elles décident de s'éloigner d'eux. P>
Vous pouvez toujours mettre une simple classe de conversion implicite dans cet emballage et écrire le reste de votre code dans votre propre package. Pas beaucoup mieux que de simplement mettre tout ce que là-bas, mais cela en fait un peu plus évident pourquoi vous le faites. P>
Mettre le code dans le package Mllib.Linalg n'est pas une solution viable pour les clients du cadre MLLIB
Je suis d'accord C'est idiot, mais il suffit de mettre un petit cours (comme le soin de @Lev), et c'est la meilleure solution de contournement qui n'implique pas la création inutile de tableaux supplémentaires, comme votre solution ci-dessous.
(Bien sûr, je pense qu'ils devraient simplement exposer la brise comme «expérimental» s'ils veulent se réserver le droit de le changer, mais c'est hors de mes mains.)
Mais l'ajout au mllib / linalg est une solution "hors limites" pour un client général (qui ne doit pas modifier ce paquet): il s'agit d'un non-démarreur. Je préfère non plus ma solution en termes de commodité: mais au moins c'est "légal". Si vous avez une idée d'une solution généralement la solution admissible i> meilleure, je suis tout à fait pour cela.
Tout ce qui est une meilleure solution nécessite de la politique, j'ai peur.
J'ai fait la même solution que @DLWh suggéré. Voici le code qui le fait:
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) } }
Ce code est placé à l'intérieur de l'emballage Spark Mllib.Linalg. Ce n'est pas une solution générale viable pour les clients du framework de MLLIB: ils ne doivent pas toucher les classes et les paquets-cadres.
C'est dans le paquet Spark.Mllib.linalg, mais l'étincelle ne devrait pas être recompilée pour cela. Créez uniquement un nouvel assemblage qui enveloppe l'assemblage d'étincelles existant et ajoutez cette classe là-bas. C'est un peu hacky, mais c'est le meilleur que j'ai trouvé.
Des trucs comme ceci est un peu dangereux. Par exemple, si vous prenez une tranche de votre vecteur Breeze et essayez de l'envelopper avec debreeze code>, cela échouera.
Voici le meilleur que j'ai jusqu'à présent. Note à @DLWh: Veuillez fournir toute amélioration que vous pourriez avoir à cela.
La solution que je pourrais proposer - qui ne met pas de code à l'intérieur du paquet de Mllib .Linalg em> strong> - est de convertir chaque vecteur en une nouvelle brise densevector. p>
Cela semble être une bonne solution, au moins travaillé pour mon but, mais lorsque nous faisons v1.toarray code> nous collectons tous les éléments de
v1 code>, qui pourrait potentiellement causer des problèmes. Quand par exemple, 'v1` est énorme et ne peut pas tenir dans la RAM!
Cette solution évite de mettre le code dans les paquets d'étincelles et évite de convertir les vecteurs clairsemés aux vecteurs denses:
Ceci est une méthode que je mobilise pour convertir un MLIB DENCEMATRIX en une matrice Breeze, peut-être qu'elle aide !!
import breeze.linalg._ import org.apache.spark.mllib.linalg.Matrix def toBreez(X:org.apache.spark.mllib.linalg.Matrix):breeze.linalg.DenseMatrix[Double] = { var i=0; var j=0; val m = breeze.linalg.DenseMatrix.zeros[Double](X.numRows,X.numCols) for(i <- 0 to X.numRows-1){ for(j <- 0 to X.numCols-1){ m(i,j)=X.apply(i, j) } } m }
Ma solution est une sorte d'hybride de celles de @barclar et @Lev, ci-dessus. Vous n'avez pas besoin em> pour mettre votre code dans le puis vous pouvez importer ces implicites dans votre code avec: p> org.apache.spark.mllib.linalg code> si vous ne utilisez pas les conversions implicites Spark-ML. Vous pouvez définir vos propres conversions implicites dans votre propre package, comme: