grep

Engineering

여기어때 검색 광고: 랭킹 부스팅 구축기

서창균Ocean(오션) / 랭킹추천개발팀여기어때

2025년 11월 7일

원문에서 보기 ↗

안녕하세요 여기어때 랭킹추천개발팀의 오션입니다.

이번에 여기어때에 새로 추가 된 검색 광고에 대해 소개드립니다.

여기어때의 검색 랭킹 시스템은 단순한 정렬 알고리즘이 아닙니다.

수많은 비즈니스 로직과 사용자 경험 요소가 얽혀 있는 꽤나 복잡한 구조의 시스템 입니다.

최근 우리팀은 랭킹 시스템 위에 ‘광고 상품을 통한 랭킹 부스트 기능’을 새로 구현해야 하는 과제를 맡게 되었습니다. 제휴파트너에게 일정 조건하에 더 높은 검색 순위를 제공하는 기능을 만드는 것이었죠.

이번 글에서는 이 기능을 설계하고 구현하는 과정에서 겪은 기술적 고민과 결정 포인트들을 공유하려고 합니다.

“검색 랭킹에 인위적인 조정 요소를 더한다”는 것은 단순히 점수에 +α를 더하는 일이 아닙니다.

검색 품질, 사용자 신뢰, 광고 효율 세 가지 축 사이의 균형을 맞추는 일입니다.

1. 초기 방식: 노출 수 보장

개발 초기 우리는 비즈니스 목표에 맞춰 “광고 상품 구매 시, N%의 랭킹 부스트가 M%의 노출 수 상승을 보장해야 한다”는 가설에서 출발했습니다.

이는 제휴파트너에게 명확한 광고 효과를 제시하기 위한 매력적인 시나리오였습니다.

이 가설을 검증하기 위해, 우리는 목표 노출 수 달성하기 위한 필요 랭킹 스코어를 역산하는 모델을 수립했습니다.

가설 검증

우리가 시도했던 구체적인 로직은 아래와 같았습니다.

  1. 목표 노출 수 설정

비즈니스 요구사항에 따라, “제휴점 A가 현재보다 10%의 노출 수 상승을 원한다”고 가정했습니다.

  1. 노출 수-랭킹 스코어 관계 모델링

가장 큰 난관은 “902회의 노출을 얻으려면 몇 점의 랭킹스코어가 필요한가?”를 알아내는 것이었습니다.

단순히 두 개의 데이터 포인트로 기울기를 구하는 대신, 모든 제휴점의(노출 수, 랭킹스코어) 쌍을 수집하여, 이 데이터셋에 선형 회귀 모델을 적용했습니다.

이 모델을 통해 노출횟수로 랭킹스코어를 예측하는 함수를 도출했습니다.

  1. 필요 스코어 예측

이제 이 회귀 모델에 목표 노출 수 902회를 대입하여 필요한 랭킹 스코어를 예측했습니다.

  1. 델타 스코어계산

마지막으로 해당 제휴점의 현재 스코어(AS-IS)를 기준으로 추가해야 할 가중치(Delta Score)를 계산했습니다.

이 Delta Score를 해당검색 시 합산해주는 것이 초기 모델의 골자였습니다.

이 모델은 실제 데이터를 검증하는 과정에서 보장하려는 노출 수를 정확히 예측하기 어렵다는 문제가 있었습니다.

테스트 결과 노출 수와 랭킹 스코어 간에는 분명한 상관관계가 존재했습니다. 하지만 예측한 모델의 변동폭이 여전히 컸습니다.

근본적인 원인은 “검색 랭킹의 상대성” 때문이었습니다.

랭킹 스코어 804점의 순위는 절대적이지 않았습니다.

검색어와 입실일에 어떤 다른 제휴점들이 함께 노출되는지에 따라 804점의 실제 순위는 매번 달라졌습니다.

이는 곧, 우리가 제휴파트너에게 “10% 향상된 노출 횟수”를 일관되게 보장해 드리기 어렵다는 문제로 이어졌습니다.

물론 검색어 및 입실일로 데이터를 모두 세분화하여 각각의 회귀모델을 만들었다면 정확도는 지금보다 훨씬 더 올라갔을 것입니다.

하지만 우리는 노출 수라는 간접적이고 변동성이 큰 지표로 파트너분들과 소통하기보다는 “현재 순위에서 N등 올려드리기”와 같이 직관적인 가치를 제공하는 것이 파트너분들께 더 낫다고 판단했습니다.

이 경험을 통해 우리는 노출수를 예측하는 대신 현재 순위를 기준으로 목표 순위까지 필요한 스코어를 계산하여 주입하는 현재의 2차 모델을 설계하게 되었습니다.

검색어 1의 제휴점 Score의 노출횟수 분포도

검색어 2 의 제휴점 Score의 노출횟수 분포도

2. 새로운 접근: 상승 순위 보장

앞서 노출 수-스코어 선형 모델이 실패한 이유는 랭킹의 상대성 때문이었습니다. 예를 들어 1위 숙소의 랭킹 스코어는 어떤 검색어로 검색했는지에 따라 다르며 동일한 강남역 키워드 내에서도 어떤 입실일(평일인지 주말인지)을 선택했는지에 따라 매번 완전히 달라집니다.

그래서 노출 수처럼 불확실한 결과를 예측하는 대신 제휴파트너들께 “현재 50등이신데, 광고를 하시면 약 25등이 될 수 있습니다”처럼 명확한 순위 상승을 제시하는 방식으로 방향을 바꿨습니다.

즉, 몇 점을 더 준다는 절대적인 개념이 아니라, 현재 50등에서 25등이 되려면 정확히 몇 점이 필요한가?를 계산하는 아키텍처를 설계했습니다.

핵심은 현재 스코어를 기준으로 목표 스코어를 계산하고, 그 차액인 Delta Score를 검색 쿼리에 동적으로 주입하는 것입니다.

이 시스템은 크게 3개의 모듈로 구성됩니다.

1) 데이터 수집 모듈

부스팅을 하려면 먼저 현재 상태(입실일 및 검색어에 따른 제휴점들의 Ranking Score 및 순위)를 정확히 알아야 합니다. 이를 위해 data-collector라는 모듈을 개발했습니다.

2) Delta Score 계산 모듈

1단계에서 수집한 데이터를 기반으로 부스팅에 필요한 Delta Score를 계산합니다.

3) 검색 쿼리에 가중치 주입 (검색 API)

사용자가 검색을 요청할 때 2단계에서 계산한 Delta Score를 동적으로 적용합니다.

  1. 사용자 검색 요청이 들어오면(검색어, 입실일 포함)
  2. 검색 API는 해당 redis에 검색어-입실일에 대한 부스팅 데이터가 있는지 확인합니다.
  3. 데이터가 존재할 경우, 기존의 query에 function_score를 동적으로 주입 합니다.
  4. functions 배열 안에, 부스팅이 필요한 각 affiliate_id를 filter (term 쿼리)로 지정하고, 2단계에서 계산한 delta_score를 가중치로 부여합니다.
  5. 기존 스코어(score)에 delta_score를 합산합니다. (Final_Score = score + delta_score)
/* 실제 쿼리는 더 복잡하지만 예시입니다.
*/
"query": {
  "function_score": {
    "query": { 
      /* ... 기존 사용자 검색 쿼리 (필터, 정렬 등) ... */ 
    },
    "functions": [
      { 
        "filter": { "term": { "affiliate_id": "제휴점_A" } }, 
        "weight": 120.5 // 제휴점 A의 (B-A) Delta Score
      },
      { 
        "filter": { "term": { "affiliate_id": "제휴점_B" } }, 
        "weight": 95.0  // 제휴점 B의 (B-A) Delta Score
      }
      // ... 부스팅 대상만큼 함수 추가 ...
    ],
    ...
  }
}

3. 검증: A/B 테스트

실제 사용자에게 적용하기 전 우리는 두 가지를 검증했습니다.

  1. 순위 상승이 실제로 제휴점의 비즈니스 지표(클릭, 예약)에 긍정적인 영향을 주는가?
  2. 부스팅이 다른 제휴점들의 노출 기회를 과도하게 빼앗아 전체 검색 생태계 품질을 떨어뜨리지는 않는가?

이를 위해 다음과 같이 A/B 테스트를 설계했습니다.

테스트 설계

검증 지표 및 결과

우리는 두 가지 관점에서 지표를 분석했습니다.

  1. 부스팅 그룹 성과: 부스팅이 적용된 제휴점 샘플군의 클릭률(CTR)과 예약률(CVR)이 Group A(대조군) 대비 유의미하게 증가했는지 확인했습니다.
  2. 생태계 영향 : 부스팅되지 않은 ‘나머지’ 파트너들의 클릭률과 예약률이 어느 정도 하락하는지(혹은 유지되는지)를 모니터링했습니다.

세부적인 지표는 공개하기 어렵지만, 부스팅을 적용한 Group B, C에서 클릭률(CTR) 및 예약률(CVR)이 A그룹(대조군) 대비 통계적으로 유의미하게 상승하는 것을 확인할 수 있었습니다. 동시에 나머지 파트너들의 지표 하락 폭을 확인하며 우리가 감내할 수 있는 수준인지를 검토할 수 있었습니다.

이 A/B 테스트 결과를 바탕으로 실제 비즈니스 가치를 창출한다는 확신을 얻고 기능 배포를 결정할 수 있었습니다.

4. 남은 과제들

제휴파트너분들을 위한 데이터 제공 방식의 고민

기술적으로 랭킹을 올리는 데는 성공했지만, 이 성과를 “어떻게 효과적으로 보여드릴 것인가?”라는 숙제가 남았습니다.

검색어 커버리지 확장

아키텍처 효율성 및 확장성 문제

현재의 구조는 검색어-입실일 별로 모든 AS-IS 데이터를 수집하고 Delta Score를 계산합니다. 이 방식은 두 가지 큰 효율성 문제를 안고 있습니다.

맺음말

검색 랭킹 부스트 기능은 단순히 특정 숙소를 상단에 노출하는 것이 아니라, 기존 검색 품질을 해치지 않으면서 비즈니스 요구사항(Boosting)을 동시에 만족시켜야 하는 도전적인 과제였습니다. 검색 플랫폼을 운영하는 많은 분이 공감하시겠지만, 이 두 가치 사이의 균형점을 찾는 것은 언제나 가장 어려운 숙제입니다.

우리는 현재 두 가지의 과제를 진행하고 있습니다.

  1. 어떻게 더 효율적으로: 폭증하는 검색어-입실일 조합과 늘어나는 제휴점 수를 감당하기 위해, 데이터 파이프라인을 고도화하고 아키텍처의 확장성을 확보하는 기술적 과제를 해결하고 있습니다.
  2. 어떻게 더 친절하게: 순위가 올랐다는 사실을 넘어, 파트너님들이 체감할 수 있는 가치 리포트와 미래 순위 예측 데이터를 제공하는 프로덕트적 과제를 풀고 있습니다.

여기어때 검색서비스는 사용자와 제휴파트너 모두가 윈윈(Win-Win)할 수 있는 건강한 생태계를 만드는 것을 목표로 합니다. 이 목표를 위해 저희는 앞으로도 끊임없이 데이터를 분석하고 시스템을 개선하며 다음 단계의 프로덕트를 준비해 나가겠습니다.

긴 글 읽어주셔서 감사합니다.