5

Biorąc pod uwagę mój obiekt pyspark Row:nie można przekonwertować typu <class 'pyspark.ml.linalg.SparseVector'> do wektora

>>> row 
Row(clicked=0, features=SparseVector(7, {0: 1.0, 3: 1.0, 6: 0.752})) 
>>> row.clicked 
0 
>>> row.features 
SparseVector(7, {0: 1.0, 3: 1.0, 6: 0.752}) 
>>> type(row.features) 
<class 'pyspark.ml.linalg.SparseVector'> 

Jednak row.features nie przechodzą isinstance (row.features, Vector) testu .

>>> isinstance(SparseVector(7, {0: 1.0, 3: 1.0, 6: 0.752}), Vector) 
True 
>>> isinstance(row.features, Vector) 
False 
>>> isinstance(deepcopy(row.features), Vector) 
False 

Ten dziwny błąd wpędził mnie w ogromne kłopoty. Bez podania "isinstance (row.features, Vector)," nie jestem w stanie wygenerować LabeledPoint za pomocą funkcji mapy. Będę naprawdę wdzięczny, jeśli ktoś może rozwiązać ten problem.

Odpowiedz

6

Jest mało prawdopodobne, aby wystąpił błąd. Nie dostarczyłeś code required to reproduce the issue, ale najprawdopodobniej używasz Spark 2.0 z transformatorami ML i porównujesz złe jednostki.

Zilustrujmy to przykładem. Proste dane

from pyspark.ml.feature import OneHotEncoder 

row = OneHotEncoder(inputCol="x", outputCol="features").transform(
    sc.parallelize([(1.0,)]).toDF(["x"]) 
).first() 

Teraz pozwala importu różne klasy Vector:

from pyspark.ml.linalg import Vector as MLVector, Vectors as MLVectors 
from pyspark.mllib.linalg import Vector as MLLibVector, Vectors as MLLibVectors 
from pyspark.mllib.regression import LabeledPoint 

i zrobić testy:

isinstance(row.features, MLLibVector) 
False 
isinstance(row.features, MLVector) 
True 

Jak widać, co mamy jest pyspark.ml.linalg.Vector nie pyspark.mllib.linalg.Vector który nie jest zgodny ze starym API:

LabeledPoint(0.0, row.features) 
TypeError         Traceback (most recent call last) 
... 
TypeError: Cannot convert type <class 'pyspark.ml.linalg.SparseVector'> into Vector 

Można przekształcić obiekt ml do MLLib jednym:

from pyspark.ml import linalg as ml_linalg 

def as_mllib(v): 
    if isinstance(v, ml_linalg.SparseVector): 
     return MLLibVectors.sparse(v.size, v.indices, v.values) 
    elif isinstance(v, ml_linalg.DenseVector): 
     return MLLibVectors.dense(v.toArray()) 
    else: 
     raise TypeError("Unsupported type: {0}".format(type(v))) 

LabeledPoint(0, as_mllib(row.features)) 
LabeledPoint(0.0, (1,[],[])) 

lub po prostu:

LabeledPoint(0, MLLibVectors.fromML(row.features)) 
LabeledPoint(0.0, (1,[],[])) 

, ale ogólnie rzecz biorąc powinieneś unikać sytuacji, gdy jest to konieczne.

+0

dzięki. Zostało rozwiązane! Jestem niezmiernie wdzięczny! –

4

Jeśli chcesz tylko przekonwertować SparseVectors z pyspark.ml na pyspark.mllib SparseVectors, możesz użyć MLUtils. Powiedz df to Twoja ramka danych, a kolumna z SparseVectors nosi nazwę "funkcje". Następnie dodaje się kilka linii pozwalają osiągnąć ten cel:

from pyspark.mllib.utils import MLUtils 
df = MLUtils.convertVectorColumnsFromML(df, "features") 

Problem ten wystąpił do mnie, ponieważ podczas korzystania CountVectorizer z pyspark.ml.feature nie mogłem stworzyć LabeledPoints, ze względu na niezgodność z SparseVector od pyspark.ml

Zastanawiam się, dlaczego ich najnowsza dokumentacja nie używa "nowej" klasy SparseVector. Ponieważ algorytmy klasyfikacji wymagają LabeledPoints, nie ma to dla mnie żadnego sensu ...

UPDATE: że źle że biblioteka ml przeznaczony jest do DataFrame-a mllib obiektów biblioteki dla BRD-obiektów. DataFrame-Datastructure jest zalecana od Spark> 2,0, ponieważ SparkSession jest bardziej kompatybilny niż SparkContext (ale przechowuje obiekt SparkContext) i dostarcza DataFrame zamiast RDD. Znalazłem ten post, który dał mi efekt "aha": mllib and ml. Dzięki Alberto Bonsanto :).

Aby użyć f.e. NaiveBayes z mllib, musiałem przekształcić moje DataFrame w obiekty LabeledPoint dla NaiveBayes z mllib.

Ale łatwiej jest użyć NaiveBayes z ml, ponieważ nie potrzebujesz LabeledPoints, ale możesz po prostu określić col i cechę swojej ramki danych.

PS: Miałem problemy z tym problemów przez kilka godzin, więc czułem, że muszę pisać tutaj :)

Powiązane problemy