본문 바로가기
데이터 분석/데이터 전처리

R전처리 - 조건에 따라 결합할 마스터 테이블 변경

by BLOSSOMED_IN 2021. 2. 15.

데이터 분석 전처리에서는 특별한 전처리가 요구되기도 합니다. 값에 따라 결합 대상을 변경하는 결합 처리도 그중 하나입니다. 결합 처리도 그중 하나입니다. 예를 들어 호텔 예약 사이트에서 호텔별로 다른 호텔을 추천하고 싶은 상황을 생각해봅시다. 특정 호텔 A에 대해서 A 호텔을 제외한 모든 호텔이 추천 대상이 되므로 추천 후보가 되는 호텔 수는 (모든 호텔 수 -1)입니다. 모든 호텔의 조합 (A에서 B의 추천과 B에서 A의 추천은 다른 것으로 생각합니다)에서 추천 순위를 생각하면 (모든 호텔 수) X (모든 호텔 수 - 1)에서 호텔별 우선순위를 매겨야 합니다. 모든 호텔 수가 1천 건 정도라도 1000x(1000-1)=약 100만 건으로 늘어납니다. 이 정도는 계산할 수는 있겠지만, 만약 건수가 1만 건만 돼도 조합은 약 1억 가까이 늘어나 쉽게 계산을 할 수 없습니다.

 

이러한 문제를 해결하기 위해 같은 지역의 호텔만을 추천하여 호텔의 추천 후보 수를 줄일 수는 있지만, 이는 또 다른 문제를 일으킵니다. 지역에 따라 호텔 수가 충분하지 않아 추천 후보가 부족하게 됩니다. 이 문제는 대상 지역을 넓혀서 호텔을 추천하는 식으로 대응할 수 있으며, 조건에 따른 결합 처리가 필요합니다.

 

조건에 따른 결합 처리는 코드가 복잡해집니다. 기본적으로 우선 결합할 테이블에 각 조건식에서 참조할 결합 키를 위한 열을 새로 생성한 후 두개의 마스터 테이블에서 결합에 필요한 공통 열로 하나의 테이블을 만듭니다. 그리고 마지막으로 테이블을 결합합니다.

 

마스터 테이블 변경

데이터셋은 호텔 예약 레코드를 사용합니다. 호텔 테이블에 있는 모든 호텔에 추천 후보 호텔을 연결한 데이터를 작성합시다. 같은 소규모 지역 단위(small_area_name)에 추천 호보수가 20건 이상이면 같은 소규모 지역 단위의 호텔을 후보로 하고, 같은 소규모 지역 단위의 호텔 건수가 20건 미만이면 같은 대규모 지역 단위(big_area_name)의 호텔을 추천 후보로 합니다.

 

R로 전처리하기

dplyr 패키지의 파이프라인으로 처리의 흐름도 알기 쉽게 작성할 수 있습니다. 데이터 크기에 따른 메모리 사용량에 주의하면서 불필요한 복제를 최대한 줄이도록 합시다.

small_area_name별로 호텔 수를 카운팅 하고, 결합 키를 판정하기 위한 테이블

: small_area_mast <-

       hotel_tb %>%

           group_by(big_area_name, small_area_name) %>%

 

# -1로 자신을 제외한다.

           summarise(hotel_cnt = n() -1) %>%

 

# 집약 처리 후에 그룹화를 해제한다.

           ungroup() %>%

 

# 20건 이상이면 join_area_id를 small_area_name으로 지정한다.

# 20건 미만이면 join_area_id를 big_area_name으로 지정한다.

       mutate(join_area_id =

                   ifelse(hotel_cnt >= 20, small_area_name, big_area_name)) %>%

       select(small_area_name, join_area_id) 

 

# 추천 후보 대상 호텔에 small_area_mst를 결합하여 join_area_id를 설정한다.

: base_hotel_mst <-

      inner_join(hotel_tb, small_area_mst, by = 'small_area_name') %>%

          select(hotel_id, join_area_id)

 

# 필요에 따라 메모리를 해체한다(메모리에 여유가 없을 때 사용)

rm(small_area_mst)

 

# recommend_hotel_mst는 추천 후보 테이블

recommend_hotel_mst <-

    bind_rows(

        # join_area_id를 big_area_name으로 한 추천 후보 마스터

        hotel_tb %>%

              rename(rec_hotel_id = hotel_id, join_area_id = big_area_name) %>%

              select(join_area_id, rec_hotel_id),

 

   # joing_area_id를 small_area_name으로 한 추천 후보 마스터

         hotel_tb %>%

              rename(rec_hotel_id = hotel_id, join_area_id = small_area_name) %>%

              select(join_area_id, rec_hotel_id)

       )

 

댓글