Почему алгоритм Spark Mllib KMeans чрезвычайно медленный?

У меня такая же проблема, как в этом сообщении, но у меня нет достаточного количества баллов для добавления комментария. У моего набора данных 1 миллион строк, 100 колос. Я тоже использую Mllib KMeans, и он очень медленный. Работа никогда не заканчивается на самом деле, и я должен ее убить. Я запускаю это в облаке Google (dataproc). Он запускается, если я попрошу меньшее количество кластеров (k = 1000), но все равно занимает более 35 минут. Мне нужно, чтобы он работал для k ~ 5000. Я понятия не имею, почему это так медленно. Данные должным образом разделены с учетом числа рабочих/узлов и SVD на 1 миллионную матрицу размером ~ 300 000 колонок, занимает ~ 3 минуты, но когда дело доходит до KMeans, оно просто переходит в черную дыру. Я сейчас пытаюсь использовать меньшее количество итераций (2 вместо 100), но я чувствую, что что-то не так.

KMeansModel Cs = KMeans.train(datamatrix, k, 100);//100 iteration, changed to 2 now. # of clusters k=1000 or 5000

Ответ 1

Похоже, что причина относительно проста. Вы используете довольно большой k и комбинируете его с дорогостоящим алгоритмом инициализации.

По умолчанию Spark использует в качестве распределенного варианта K-означает ++ под названием K-mean || (см. Что такое параметр initializationSteps в Kmeans ++ в Spark MLLib?). Распределенная версия примерно равна O (k), поэтому при увеличении k вы можете ожидать более медленного запуска. Это должно объяснить, почему вы не видите улучшения при уменьшении количества итераций.

Использование больших K также дорого, когда модель обучена. Искры использует вариант Lloyds, который примерно равен O (nkdi).

Если вы ожидаете сложной структуры данных, там, скорее всего, будут лучшие алгоритмы для обработки этого, чем K-Means, но если вы действительно хотите придерживаться этого, вы начнете с использования случайной инициализации.

Ответ 2

Попробуйте другие реализации k-средств. Некоторые, подобные вариантам ELKI, лучше, чем Spark, даже на одном процессоре. Вы будете удивлены, сколько производительности вы можете получить из одного node, не переходя в кластер! Из моих экспериментов вам понадобится, по крайней мере, 100 кластер node, чтобы, к сожалению, превзойти хорошие локальные реализации.

Я читал, что эти версии С++ являются многоядерными (но single- node) и, вероятно, самыми быстрыми K-средствами, которые вы можете найти прямо сейчас, но я еще не пробовал это сам (для всех моих нужд, версии ELKI были невероятно быстрыми, заканчивая через несколько секунд на моих самых больших наборах данных).