stackoverflow.com/q/49734374/8371915

очная информация: я делаю простую двоичную классификацию, используя RandomForestClassifier из pyspark.ml. Перед передачей данных для обучения мне удалось использовать VectorIndexer, чтобы решить, будут ли функции числовыми или категоричными, предоставив аргумент maxCategories.

Проблема: Даже если я использовал VectorIndexer с параметром maxCategories равным 30, я все равно получал ошибку во время обучения конвейера:

An error occurred while calling o15371.fit.
: java.lang.IllegalArgumentException: requirement failed: DecisionTree requires maxBins (= 32) to be at least as large as the number of values in each categorical feature, but categorical feature 0 has 10765 values. Considering remove this and other categorical features with a large number of values, or add more training examples.

Мой код прост, col_idx - это сгенерированный мной список строк столбцов, который будет передан в stringindexer, col_all - список строк столбцов, который будет передан в stringindexer, а onehotencoder, col_num - числовые имена столбцов.

from pyspark.ml.feature import OneHotEncoderEstimator, StringIndexer, VectorAssembler, IndexToString, VectorIndexer
from pyspark.ml import Pipeline
from pyspark.ml.classification import RandomForestClassifier

my_data.cache()

# stringindexers and encoders
stIndexers = [StringIndexer(inputCol = Col, outputCol = Col + 'Index').setHandleInvalid('keep') for Col in col_idx]
encoder = OneHotEncoderEstimator(inputCols = [Col + 'Index' for Col in col_all], outputCols = [Col + 'ClassVec' for Col in col_all]).setHandleInvalid('keep')

# vector assemblor
col_into_assembler = [cols + 'Index' for cols in col_idx] + [cols + 'ClassVec' for cols in col_all] + col_num
assembler = VectorAssembler(inputCols = col_into_assembler, outputCol = "features")

# featureIndexer, labelIndexer, rf classifier and labelConverter
featureIndexer = VectorIndexer(inputCol = "features", outputCol = "indexedFeatures", maxCategories = 30)
# columns smaller than maxCategories => categorical features, columns larger than maxCategories => numerical / continuous features, smaller value => less categorical features, larger value => more categorical features.
labelIndexer = StringIndexer(inputCol = "label", outputCol = "indexedLabel").fit(my_data)
rf = RandomForestClassifier(featuresCol = "indexedFeatures", labelCol = "indexedLabel")
labelConverter = IndexToString(inputCol = "prediction", outputCol = "predictedLabel", labels=labelIndexer.labels)

# chain all the estimators and transformers stages into a Pipeline estimator
rfPipeline = Pipeline(stages = stIndexers + [encoder, assembler, featureIndexer, labelIndexer, rf, labelConverter])

# split data, cache them
training, test = my_data.randomSplit([0.7, 0.3], seed = 100)
training.cache()
test.cache()

# fit the estimator with training dataset to get a compiled pipeline with transformers and fitted models.
ModelRF = rfPipeline.fit(training)

# make predictions
predictions = ModelRF.transform(test)
predictions.printSchema()
predictions.show(5)

Поэтому мой вопрос: почему в моих данных все еще есть категориальная особенность высокого уровня, даже если я установил для maxCategories значение 30 в VectorIndexer. Я могу установить для maxBins в RF-классификаторе более высокое значение, но мне просто любопытно: почему VectorIndexer работает не так, как ожидалось (ну, как я и ожидал): приведение функции меньше, чем maxCategories, к категориальной функции, больше к числовым функциям.

Ответы на вопрос(1)

Ваш ответ на вопрос