Как сравнить с картами RDD[(Int,Int)]?

Я самостоятельно реализую k-means со Spark в качестве упражнения. Для этого мне нужно сравнить 2 карты id -> cluster_id на каждом шаге. В настоящее время я делаю это, собирая их обе и сравнивая как две простые карты scala.

Есть ли способ сделать это параллельно? Стоит ли оно того?

ОБНОВЛЕНИЕ:

Позвольте мне подробно описать ситуацию, начиная с алгоритма K-MEANS Clustering (это просто)

  1. выбрать случайные K точек из всех N точек, сделав их центроидами.
  2. назначьте каждую точку ближайшему центроиду (в соответствии с евклидовым расстоянием)
  3. пересчитать центроиды, сгруппировав все точки по назначенным центроидам, вычислив среднее значение этих
  4. повторите шаги 2–3, если пересчет сгенерировал сопоставление (obj_id -> centroid_id), отличное от того, что было на предыдущем шаге

Шаг № 4 является проблемой. Мне нужно сравнить сопоставление, которое у меня было на предыдущем шаге, с тем, которое у меня есть сейчас, и это должно быть как-то сделано параллельно без слишком большого количества случайных чтений между рабочими процессами.


person Ilya Smagin    schedule 23.10.2014    source источник


Ответы (1)


Я не уверен в том, что вы подразумеваете под "сравнением" их. Ответ на ваш вопрос действительно зависит от этого! Если бы вы могли предоставить более подробную информацию, я соответствующим образом отредактирую свой ответ, но общий вопрос может дать только общий ответ ^_^

Если вам просто нужно проверить равенство, это довольно просто (и независимо от порядка, как и ожидалось от карты):

val x = Map[Int, Int](1->2, 2->3)
val y = Map[Int, Int](2->3, 1->2)
(x == y) == true

Если вы хотите только проверить, что у них одинаковые наборы ключей, но разные сопоставления (возможно, потому, что вы хотите проверить завершение шага обновления), вы можете напрямую сравнивать ключи либо как итераторы, либо как наборы.

(x.keys == y.keySet) == true

Если ваша проблема возникает из-за того, что ваши карты слишком велики, и вы хотите сделать проверку на равенство параллельно, все становится сложнее: вы можете сделать разбиение пар по ключам и иметь параллельную проверку на каждом срезе: если все ваши чеки положительны, тогда у вас равенство. Вы можете сделать это либо путем разделения x AND y на фрагменты в соответствии со значением/хэшем ключа и отправки разным актерам (например, если вы используете актеров), либо просто перебирая x и проверяя значение y на другом актере. для этого ключа.

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

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

EDIT Учитывая новую информацию, мой ответ практически не изменился. Просто разделите записи в x на n фрагментов, назначенных хэшем ключа, и проверьте, содержит ли y их с тем же значением.

person Diego Martinoia    schedule 23.10.2014
comment
Я добавил некоторые детали к вопросу. - person Ilya Smagin; 23.10.2014