Кортни Уэлен — старший специалист по обработке и анализу данных компании B23, работающая над платформой данных B23.

Являясь членом группы разработчиков B23 Data Platform и специалистов по обработке и анализу данных, мы с радостью продолжаем выпускать новые инновационные и безопасные функции, которые позволяют специалистам по обработке данных обрабатывать данные более эффективно и быстро, чем раньше. возможный. В начале 2016 года мы запустили платформу данных B23 в качестве платформы для оркестровки данных. Платформа данных B23 — это как рынок данных, так и рынок стеков больших данных, которые можно подготовить за считанные минуты. Большинство автоматизированных инструментов инициализации — это просто чистый холст, но с B23 Data Platform у вас есть доступ как к наборам данных, так и к защищенным стекам в облаке. Используя функцию B23 EasyIngest, специалистам по обработке и анализу данных достаточно нескольких щелчков мыши и нескольких минут, чтобы проанализировать данные в защищенном стеке.

Недавно у меня была возможность поработать над проектом, который подчеркивает возможности платформы данных B23 — геопространственный анализ с использованием Apache Spark. Это включало использование большого набора данных, содержащего сетевые данные о местоположении в географических координатах. В частности, этот набор данных содержал более миллиарда строк показателей широты и долготы с отметками времени за многолетний период. Задача состояла в том, чтобы выяснить, сколько из этих «местоположений» сопоставляются с определенными точками интереса («POI») каждый день, используя этот первоначальный необработанный набор данных. Я смог выполнить эту задачу геопространственного обогащения, выполнив следующие 5 шагов:

1. Получение данных POI

2. Определите способ объединения наборов данных

3. Преобразование данных

4. Геозонирование данных POI

5. Запустить пространственное объединение

Получить данные POI

Моим первым шагом было получение второго набора данных, содержащего геопространственные данные для конкретной точки интереса. Мы использовали данные POI, которые содержат адреса более 1000 сетей ресторанов в Северной Америке. В одном случае я загрузил данные для ресторана Chipotle, который насчитывает 2076 заведений (по состоянию на 13.06.16).

Определить, как объединять наборы данных

Теперь, когда я получил свои наборы данных, мне нужен был план, чтобы присоединиться к ним. Первый набор данных содержит около 6,5 миллионов записей в день. После некоторых вычислений я понял, что объединение каждой из этих точек местоположения с более чем 2000 точками местоположения Chipotle приведет к более чем 13 миллиардам записей в день. Декартовский анализ был быстро выброшен за дверь.

Я быстро нашел библиотеку под названием SpatialSpark, которая подходила для моих целей. Как следует из названия, SpatialSpark использует Spark в качестве базового механизма. Алгоритм перебирает больший набор данных и эффективно запрашивает меньший набор данных, преобразовывая меньший набор данных в R-дерево и сохраняя его в памяти. [1]

Преобразование данных

Прежде чем я смог протестировать библиотеку SpatialSpark, мне нужно было выполнить несколько преобразований данных. SpatialSpark использует JTS Topology Suite, который предоставляет геометрическую модель и ряд геометрических функций [2], поэтому каждую точку широты/долготы в моих наборах данных нужно было преобразовать в геометрический объект.

Каждую точку также нужно было спроецировать на новую систему координат. Это связано с тем, что географические координаты представляют Землю в форме шара. Когда вы пытаетесь изобразить эту сферу на плоской поверхности, она искажается. Линии долготы, которые должны пересекаться на полюсах Земли, на самом деле проходят параллельно друг другу при переносе на плоскую поверхность и, следовательно, никогда не пересекаются. Из-за этого искажения, чем дальше вы удаляетесь от экватора, тем шире и более искаженной становится область. [3]

Чтобы решить эту проблему, я использовал библиотеку GeoTools для проецирования каждой точки широты/долготы на систему отсчета координат (CRS), которая корректирует изменение масштаба. Существует несколько проекций CRS для Соединенных Штатов, которые были созданы для сохранения различных свойств карты (площади, формы, направления и т. д.). [4] Я остановился на конкретной CRS под названием ESRI:102005, которая пытается сохранять дистанцию ​​между объектами.

def transformGeom(longitude: Double, latitude: Double): Geometry = {
// create CRS
 val EPSG_102005: String = "PROJCS[\"USA_Contiguous_Equidistant_Conic\",GEOGCS[\"GCS_North_American_1983\",DATUM[\"North_American_Datum_1983\",SPHEROID[\"GRS_1980\",6378137,298.257222101]],PRIMEM[\"Greenwich\",0],UNIT[\"Degree\",0.017453292519943295]],PROJECTION[\"Equidistant_Conic\"],PARAMETER[\"False_Easting\",0],PARAMETER[\"False_Northing\",0],PARAMETER[\"Longitude_Of_Center\",-96],PARAMETER[\"Standard_Parallel_1\",33],PARAMETER[\"Standard_Parallel_2\",45],PARAMETER[\"Latitude_Of_Center\",39],UNIT[\"Meter\",1],AUTHORITY[\"EPSG\",\"102005\"]]";
 val sourceCRS: CoordinateReferenceSystem = CRS.parseWKT(EPSG_102005);
// project lat/long points on CRS
 val sourceGeom = new WKTReader().read(fact.createPoint(new Coordinate(longitude, latitude)).toString)
 val mathTransform: MathTransform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, sourceCRS, true)
 JTS.transform(sourceGeom, mathTransform);
}

Гео-ограждение данных POI

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

def bufferGeom(geom: Geometry, distance: Double): Geometry = {
 
 // create polygon around Geometry object
 geom.buffer(distance)
 
 }

Выполнить пространственное соединение

Теперь, когда мои данные были подготовлены, я был готов начать процесс присоединения. Я преобразовал каждый из своих наборов данных, а затем вызвал метод соединения SpatialSpark, чтобы увидеть, какие точки пересекаются с многоугольником Chipotle в определенный день. Весь процесс занял меньше минуты, и результаты были довольно точными!

B23 может легко помочь вам настроить среду для проведения этого анализа. Платформа данных B23 может принимать ваши данные, безопасно хранить эти данные в облаке и предоставлять стек Spark за пятнадцать минут или меньше.

// RDD with pairs (id, point) for a person's location
 val personRdd: RDD[(Long, Geometry)] = personDf.map { row => (row.getLong(0), transformGeom(row.getDouble(2), row.getDouble(1)) )}
// RDD with pairs (id, polygon) for a Chipotle's location
 val chipotleRdd: RDD[(Long, Geometry)] = chipotleDf.map { row =>(row.getInt(0).toInt, bufferGeom(transformGeom(row.getDouble(2), row.getDouble(1)), 4.0) )}
// RDD with pairs (id, id) of intersecting person/Chipotle locations
 val joinedRdd: RDD[(Long, Long)] = BroadcastSpatialJoin(sc, personRdd, chipotleRdd, SpatialOperator.Intersects, 0.0)

Для первого результата (широта, долгота) chipotle_id=714 равна (33,562836, -84,324768), а (широта, долгота) location_id=4338942 равна (33,5628122, -84,3247918).

Apache Spark быстро становится инструментом де-факто для обработки больших наборов данных в любом масштабе. В B23 мы считаем, что эластичная облачная инфраструктура — идеальный компаньон для обработки больших объемов данных. Ключевым отличием для нас является снятие «тяжелой работы» с запуском масштабируемых решений для работы с большими данными, таких как Spark, и выполнение этого безопасно и за считанные минуты.

Своевременное объединение миллиардов строк данных в любом контексте — непростая задача. Используя стороннюю библиотеку под названием SpatialSpark, я смог объединить очень большой сетевой набор данных о местоположении с набором данных POI, чтобы за считанные минуты получить пересечение людей и местоположений сотен ресторанов в Северной Америке.

Результатом этой обработки стал продукт данных, который позволил нам отслеживать посещаемость пользователей в более чем 1000 определенных ресторанов в Северной Америке ежедневно в течение длительного периода времени. Попробуйте сами на Платформе данных B23.

[1] http://getindata.com/blog/post/geospatial-analytics-on-hadoop/

[2] https://en.wikipedia.org/wiki/JTS_Topology_Suite

[3] https://docs.qgis.org/2.6/en/docs/training_manual/vector_analysis/reproject_transform.html

[4] https://en.wikipedia.org/wiki/Map_projection

Первоначально опубликовано на medium.com 30 августа 2016 г.