pyspark 에서 반경검색을 빠르고 효율적으로 사용하는방법

람다식으로 각 row마다 거리를 계산하는 방법을 앞에서 소개하였지만,spark의 실행 최적화가 안되기 때문에 느립니다.

DF의 기본 Filter기능과 geopy.distance 모듈을 사용하여 빠르게 위경도 인근지역 가까운순 리스트를 뽑아 내는 방법입니다.

Spark와 위경도 반경처리에 관련된 연동 모듈이 다양하고 고성능 엔진도 존재할것이지만

여기서는 적당한 성능을 내고 간단하게 사용할수 있는 pyspark 반경검색을 알아보겠습니다.


사용모듈

from pyspark.sql.functions import udf
from geopy.distance import great_circle
from pyspark.sql.functions import lit, struct

@udf("float")
def great_circle_udf(x, y):
    return great_circle(x, y).kilometers


근처 반경검색

tbl_NHotel , sqlContext.createDataFrame 에서 변환된 DataFrame이다.
RDD를 DataFrame으로 변환하는 방법은 앞장을 참고 


point = struct(lit(33.5425784002482), lit(126.665174019924))
# 3키로 이내에놈을 가까운순으로 보여죠...
nearNaver = tbl_NHotel.filter(great_circle_udf(point, struct(tbl_NHotel.latitude, tbl_NHotel.longitude)) < 3 )
nearNaver.show(10)

# 이 결과는 1초이내에 수행됩니다. 분석대상 범위를 축소하는데 중요한 역활을 합니다.

결과
+-------+-----+--------------+----------+-----------+-------+-------+
|     id|price|     goodsname|  latitude|  longitude|region1|region2|
+-------+-----+--------------+----------+-----------+-------+-------+
|1053561|42760|   제주 오션그랜드 호텔| 33.542571| 126.665239|     제주|     제주|
|2007411|75000|   제주 파크 비치 호텔|  33.54912|  126.68461|     제주|     제주|
|2664432|70000|       푸른바다 펜션|33.5496324|126.6529224|     제주|     제주|
|3011035|40201|       제주와요 펜션|  33.53298|  126.63868|     제주|     제주|
|2915731|72222|      씨에코비치 펜션|   33.5483|   126.6472|     제주|     제주|
|2748674|51090|       오션 베스트빌|  33.54975| 126.652189|     제주|     제주|
|2824549|60500|더 아트스테이 제주함덕호텔|33.5424614|126.6659324|     제주|     제주|
|1269784|70000|     제주 선샤인 호텔|33.5438538|126.6624146|     제주|     제주|
|2917523|50111|   제주 비치 함덕 호텔|33.5433172|126.6636515|     제주|     제주|
|3499445|58200|       호텔 베스트원|33.5442712|126.6569594|     제주|     제주|
|1820463|49735|     비치 스토리 호텔|  33.54208|  126.66549|     제주|     제주|
|3010720|58006|       소곤닥 하우스| 33.542671| 126.663479|     제주|     제주|
|3012776|50440|        포엠 하우스|33.5432169|126.6638897|     제주|     제주|
|1945210|42000|         필 하우스|33.5450923|126.6864073|     제주|     제주|
|2944847|51718|        친친 하우스| 33.527757| 126.686415|     제주|     제주|
+-------+-----+--------------+----------+-----------+-------+-------+

# 이 기능으로 여러가지 정보를 알게되었습니다. 다수결의 원칙을 적용하여
# 해당 위경도의 지역정보가 호텔정보를 베이스로 제주임을 알수가 있으며
# 가까운 순으로, 처리할 우측 아이템순을 제한하여 보여주니 
# 이름 유사도 검사라던지 기타등의 부가적인 매칭룰을 적은 루프로 적용할수가 있습니다. 


개선

위 내용은 데이터가 얼마되지 않은 반경분석처리 에서는 모두 커버가 될것으로 보이지만

조금더 큰 데이터 즉 해외의 모든 데이터라는 범위확장을 하고

반경필터외에, 지역이 생겨먹은 도형을 기준으로 포함처리까지 가능하게하면서

고성능 분산처리까지되게하려면 조금더 고급처리 기법이 필요합니다.


아직 시도해보지는 못했지만, 아래 아티컬이 그러한것을 커버하는 아키텍쳐로 보여집니다.

https://github.com/sabman/PySparkGeoAnalysis/blob/master/slides.md




  • No labels