Нет ничего особенно плохого в вашем коде, когда дело касается параллелизма:
- Распределенная и параллельная часть - это процесс подгонки модели
ml_kmeans(...)
. Цикл for не влияет на это. Каждая модель будет обучаться с использованием ресурсов, доступных в вашем кластере, как и ожидалось.
Внешний цикл - это код драйвера. При нормальных условиях мы используем стандартный однопоточный код (не то, чтобы многопоточность на этом уровне действительно была опцией R) при работе со Spark.
В общем случае (Scala, Python, Java) можно использовать отдельные потоки для одновременной отправки нескольких заданий Spark, но на практике это требует большой настройки и доступа к низкоуровневому API. Даже там это редко стоит суеты, если в вашем распоряжении нет значительного кластера.
При этом имейте в виду, что если вы сравните Spark K-Means с локальными реализациями данных, которые помещаются в память, все будет относительно медленно. Использование рандомизированной инициализации может помочь ускорить процесс :
ml_kmeans(id_ip4, centers = i, init_mode = "random",
seed = 1234, features_col = colnames(id_ip4))
В примечании с алгоритмами, которые можно легко оценить с помощью одного из доступных оценщиков (ml_binary_classification_evaluator
, ml_multiclass_classification_evaluator
, ml_regression_evaluator
), вы можете использовать ml_cross_validator
/ ml_train_validation_split
вместо ручных циклов.