Pyspark Py4j IllegalArgumentException с помощью spark.createDataFrame и pyspark.ml.clustering - PullRequest
0 голосов
/ 27 марта 2020

Позвольте мне сначала раскрыть полный фон моей проблемы, у меня будет упрощенный MWE, который воссоздает ту же проблему внизу. Не стесняйтесь пропустить меня, рассуждая о моей настройке и go прямо к последнему разделу.

Актеры в моей оригинальной задаче:

  1. Искренний кадр данных data чтение из Amazon S3 со столбцом scaled_features, который в конечном итоге является результатом операции VectorAssembler, за которой следует MinMaxScaler.
  2. столбец искрового фрейма данных pca_features, полученный из приведенного выше столбец df после PCA примерно так:
mat = RowMatrix(data.select('scaled_features').rdd.map(list))
pc = mat.computePrincipalComponents(2)
projected = mat.multiply(pc).rows.map(lambda x: (x, )).toDF().withColumnRenamed('_1', 'pca_features')
Два экземпляра BisectingKMeans соответствуют обоим экземплярам функций в вышеупомянутых фреймах данных, например:
kmeans_scaled = BisectingKMeans(featuresCol='scaled_features').setK(4).setSeed(1)
model1 = kmeans_scaled.fit(data)

kmeans_pca = BisectingKMeans(featuresCol='pca_features').setK(4).setSeed(1)
model2 = kmeans_pca.fit(projected)

Проблема:

В то время как BisectingKMeans подходит к scaled_features из моего первого df без проблем, при попытке подгонки к проецируемым функциям он выдает ошибку со следующим

Py4JJavaError: An error occurred while calling o1413.fit.
: java.lang.IllegalArgumentException: requirement failed: Column features must be of type equal to one of the following types:
[struct<type:tinyint,size:int,indices:array<int>,values:array<double>>, array<double>, array<float>]
but was actually of type struct<type:tinyint,size:int,indices:array<int>,values:array<double>>.

Как вы можете видеть, Py4J жалуется, что я ' m передача данных в определенном структурном типе, который оказывается первым типом, указанным в списке разрешенных типов.

Дополнительная информация об отладке:

My Spark работает под управлением версии 2.4.0

Проверка выходов dtypes: data.dtypes: [('scaled_features', 'vector')] и projected.dtypes: [('pca_features', 'vector')]. Схема одинакова для обоих фреймов данных, печатая только один для справки:

root
 |-- scaled_features: vector (nullable = true)

Воссоздание ошибки (MWE):

Оказывается, это ту же ошибку можно воссоздать, создав простой фрейм данных из некоторых Векторов (столбцы в моих исходных dfs также имеют VectorType):

from pyspark.sql import Row
from pyspark.mllib.linalg import DenseVector
from pyspark.ml.clustering import BisectingKMeans

test_data = spark.createDataFrame([Row(test_features=DenseVector([43.0, 0.0, 200.0, 1.0, 1.0, 1.0, 0.0, 3.0])),
    Row(test_features=DenseVector([44.0, 0.0, 250.0, 1.0, 1.0, 1.0, 0.0, 1.0])),
    Row(test_features=DenseVector([23.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0])),
    Row(test_features=DenseVector([25.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 2.0])),
    Row(test_features=DenseVector([19.0, 0.0, 200.0, 1.0, 0.0, 1.0, 0.0, 1.0]))])

kmeans_test = BisectingKMeans(featuresCol='test_features').setK(4).setSeed(1)
model3 = kmeans_test.fit(test_data)

Последняя строка приводит к той же ошибке, с которой я столкнулся в мои первоначальные настройки.

Может кто-нибудь объяснить эту ошибку и предложить способ ее исправления?

1 Ответ

0 голосов
/ 02 апреля 2020

После еще нескольких дней исследования я указал на (довольно смущающую) причину проблемы:

В Pyspark есть две библиотеки машинного обучения: pyspark.ml и pyspark.mllib, и оказалось, что они не go хорошо вместе. Замена from pyspark.mllib.linalg import DenseVector на from pyspark.ml.linalg import DenseVector устраняет все проблемы.

...