K-средства кластеризации является итерационным алгоритмом, который делает несколько проходов по данным. В каждом проходе точки назначаются центроидам кластеров, а затем после того, как все точки были назначены, центроиды кластера пересчитываются как среднее из назначенных точек. Вы не можете «передавать» данные в алгоритм в традиционном смысле, так как вам нужно будет вернуться к нему во время последующих итераций.
Что касается реализации OpenIMAJ FloatKMeans
: да это может обрабатывать «большие данные» в том смысле, что он не возражает, где он получает данные из - за DataSource
, например, что он принимает в качестве входных данных может считывать данные с диска при необходимости. Единственное требование состоит в том, что вы можете удерживать все центроиды в памяти во время выполнения алгоритма. Реализация многопоточная, поэтому все ядра процессора могут использоваться во время вычислений. Здесь приведен пример кода: https://github.com/openimaj/openimaj/blob/master/demos/examples/src/main/java/org/openimaj/examples/ml/clustering/kmeans/BigDataClusterExample.java. Методы OpenIMAJ IOUtils.writeBinary(...)
могут использоваться для сохранения результирующих центроидов кластера в объекте FloatCentroidsResult
.
Одной из самых больших затрат в K-Means является вычисление расстояний между каждой точкой данных и каждым центроидом кластера, чтобы найти ближайший. Стоимость этого связана с размерностью данных и количеством центроидов. Если у вас есть большое количество центроидов и высокоразмерных данных, то использование приблизительной реализации K-Means может иметь большие преимущества скорости за счет небольшой потери точности (например, FloatKMeans.createKDTreeEnsemble()
- здесь используется ансамбль KD -Trees для ускорения вычислений соседа).
Что касается интеграции с Hadoop, можно реализовать K-Means как серию задач Map-Reduce (каждая пара соответствует итерации алгоритма).См. Эту статью для обсуждения: http://eprints.soton.ac.uk/344243/1/paper.pdf. Если вы хотите спуститься по этому маршруту, OpenIMAJ имеет здесь очень грубую реализацию, которую вы могли бы построить: https://github.com/openimaj/openimaj/tree/master/hadoop/tools/HadoopFastKMeans. Как упоминалось в связанной статье, Apache Mahout также содержит реализацию: https://mahout.apache.org. Одна из проблем в обеих этих реализациях заключается в том, что они требовали передачи большого количества данных между преобразователями и редуктором (каждый преобразователь испускает текущую точку данных и назначенный ей идентификатор кластера). Степень этого может означать, что было бы быстрее использовать реализацию алгоритма, отличную от Hadoop, но это будет зависеть от того, какие ресурсы обработки у вас имеются и характер набора данных. Проблема передачи данных между картой и сокращением, вероятно, также может быть уменьшена с помощью умного Hadoop Combiner
и вычисляет взвешенные центроиды из подмножеств данных, а затем передает их на (модифицированный) редуктор, чтобы вычислить фактические центроиды.