Я настроил объект CrossValidator
в сочетании с конвейером линейной регрессии и сеткой гиперпараметров для выбора. В частности, я запускаю 5-кратную перекрестную проверку на 9 различных настройках, полученных в результате сочетания двух гиперпараметров (каждый из которых принимает 3 значения), и отслеживаю все 45 полученных моделей, устанавливая collectSubModels
флаг True
:
...
lr = LinearRegression(featuresCol="features", labelCol="label")
pipeline = Pipeline(stages=indexers + [encoder] + [assembler] + [lr])
param_grid = ParamGridBuilder()\
.addGrid(lr.regParam, [0.0, 0.05, 0.1]) \
.addGrid(lr.elasticNetParam, [0.0, 0.5, 1.0])\
.build()
cross_val = CrossValidator(estimator=pipeline,
estimatorParamMaps=param_grid,
evaluator=RegressionEvaluator(metricName="rmse"),
numFolds=5,
collectSubModels=True
)
# Run cross-validation, and choose the best set of parameters
cv_model = cross_val.fit(train)
return cv_model
Кажется, что все идет гладко, за исключением того факта, что когда я печатаю производительность (т. Е. Среднеквадратичное значение) каждой модели (т. Е. 9 моделей для каждый раз), и я пытаюсь «вручную» вычислить среднее значение для каждого раза, полученные в результате 9 средних значений не вообще совпадают со значениями, которые я получаю, когда использую внутреннее свойство avgMetrics
CrossValidator
. Просто в качестве примера приведем следующие 5 значений RMSE, которые я получил, используя первую комбинацию двух гиперпараметров (т. Е. Оба установлены в 0):
*************** Fold #1 ***************
--- Model #1 out of 9 ---
Parameters: lambda=[0.000]; alpha=[0.000]
RMSE: 149354.656
*************** Fold #2 ***************
--- Model #1 out of 9 ---
Parameters: lambda=[0.000]; alpha=[0.000]
RMSE: 146038.521
*************** Fold #3 ***************
--- Model #1 out of 9 ---
Parameters: lambda=[0.000]; alpha=[0.000]
RMSE: 148739.919
*************** Fold #4 ***************
--- Model #1 out of 9 ---
Parameters: lambda=[0.000]; alpha=[0.000]
RMSE: 146816.473
*************** Fold #5 ***************
--- Model #1 out of 9 ---
Parameters: lambda=[0.000]; alpha=[0.000]
RMSE: 149868.621
Как видите, все значения RMSE ниже 150000. Я ожидал, что если бы я взял среднее из этих значений выше, я бы получил первый элемент списка avgMetrics
(который, действительно, предположительно содержит среднее значение перекрестной проверки для каждой комбинации гиперпараметров, вычисленной по сгибам). Вместо этого, если я использую cv_model.avgMetrics
, я получу следующее:
[150091.7372030353, 150091.7372030353, 150091.7372030353, 150091.7345116686, 150093.66131828527, 150090.52769066638, 150091.7338301999, 150090.52716106002, 150091.59829053417]
Ожидается 9 элементов, но ни один из них не выглядит правильно! На самом деле, все они превышают 150 000, хотя ни одна из моих 45 моделей (не только те 5, которые я перечислил выше) достигает этих цифр.
Похоже, что заполнение avgMetrics
неверно. Я знаю, что была проблема еще в 2016 году, когда это значение по ошибке содержало сумму показателей перекрестной проверки, а не среднее значение, но, по-видимому, это было исправлено .
Я также пытался проверить текущая реализация метода _fit
объекта CrossValidator
и - хотя я не слишком много времени уделял этому - по-видимому, все выглядит хорошо:
for i in range(nFolds):
validateLB = i * h
validateUB = (i + 1) * h
condition = (df[randCol] >= validateLB) & (df[randCol] < validateUB)
validation = df.filter(condition).cache()
train = df.filter(~condition).cache()
tasks = _parallelFitTasks(est, train, eva, validation, epm, collectSubModelsParam)
for j, metric, subModel in pool.imap_unordered(lambda f: f(), tasks):
metrics[j] += (metric / nFolds)
if collectSubModelsParam:
subModels[i][j] = subModel
Имеет кто-нибудь еще сталкивался с такой же проблемой?
РЕДАКТИРОВАТЬ: Я слепо предположил, что проблема (если таковая имеется) в avgMetrics
свойство; однако, возможно, что эти средние значения на самом деле верны, в то время как отдельные показатели, которые я напечатал выше, вызывая .summary.rootMeanSquaredError
для каждой подмодели, вычисляются неправильно. В любом случае, между ними есть явное несоответствие.