Позвольте мне сначала раскрыть полный фон моей проблемы, у меня будет упрощенный MWE, который воссоздает ту же проблему внизу. Не стесняйтесь пропустить меня, рассуждая о моей настройке и go прямо к последнему разделу.
Актеры в моей оригинальной задаче:
- Искренний кадр данных
data
чтение из Amazon S3 со столбцом scaled_features
, который в конечном итоге является результатом операции VectorAssembler
, за которой следует MinMaxScaler
. - столбец искрового фрейма данных
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)
Последняя строка приводит к той же ошибке, с которой я столкнулся в мои первоначальные настройки.
Может кто-нибудь объяснить эту ошибку и предложить способ ее исправления?