[TIL] 퍼널 분석 / 리텐션 분석

한울·2025년 12월 25일

Core Concepts

퍼널 분석

  1. 퍼널이란?

    funnel
    사진 출처

    • 깔대기 구조: 처음 단계에서는 사용자 수가 많고, 뒷 단계로 갈수록 사용자수가 줄어든다.

    • 홈 -> 상품 검색 -> 상품 검색 결과 페이지 -> 상품 세부 페이지 -> 장바구니 페이지 -> 결제 페이지 -> 주문 완료 페이지

  2. 목적

    • 사용자가 어느 단계에서, 왜, 얼마나 포기하는지 찾기 위한 분석
    • 단계별 전환율을 분석해 개선 우선순위를 정할 수 있다.
  3. 퍼널의 종류

    • Closed Funnel

      • 퍼널 단계의 순서가 고정된 퍼널
      • 사용자는 중간 단계를 건너뛸 수 없다.
      • 이전 단계를 거치지 않으면 다음 단계의 전환은 인정되지 않는다.
      • 따라서 단계가 진행될수록 전환율은 단조 감소한다.
      • UX 설계를 강하게 할 경우, 사용자가 의도된 순서를 따르도록 유도할 수 있다.
    • Open Funnel

      • 사용자가 중간 단계를 건너 뛰어 진입할 수 있는 퍼널
      • 진입 지점이 여러 개이기 때문에 단계 순서가 고정되지 않는다.
      • 이전 단계를 거치지 않아도 다음 단계를 진입할 수 있다.
      • 웹의 경우 특정 단계를 거치지 않고도 URL로 이동 가능하다. 따라서 Open Funnel 구조가 자연스럽게 발생한다.
  4. 어떤 기준으로 집계할 것인가?

    • 유저 별 집계 : 고유한 사용자 수를 세는 방식
    • 페이지 뷰 별 집계: 페이지뷰 이벤트가 발생한 횟수를 세는 방식
    • 세션 별 집계
      • 세션의 단위는 보통 30분 단위이기 때문에 하나의 이용 흐름 안에서 유저의 행동을 분석할 수 있다.
      • 세션 별 집계를 안 한다면 며칠 뒤에 한 행동도 같은 전환 흐름으로 생각할 수 있다.
      • 보다 정확한 유저 행동 분석을 위해 세션 별 집계를 사용한다.

리텐션 분석

  1. 리텐션(retention)이란?

    • 한 번 유입된 사용자가 일정 시간이 지난 뒤에도 다시 돌아와 서비스를 사용하는 비율
    • 서비스가 사용자에게 가치를 준다면 리텐션 비율이 높을 것이다.
    • 신규 유저가 계속 유입되더라도 기존 유저가 서비스를 이용하지 않는다면 매출 성장이 없을 것이다.
    • 따라서, 서비스의 성장 가능성과 지속 가능성을 나타내는 지표이다.
  2. 리텐션을 어떻게 정의할 것인가?

  • 앱 접속 기준 : 앱에 한 번이라도 접속한사용자

    • 서비스의 초기 단계 분석 때 적합하다.
    • 하지만 사용자의 서비스 사용 이유, 목적을 분석하진 못한다.
  • 핵심 이벤트 기준 : 서비스의 핵심 이벤트를 수행한 사용자

    • 값이 낮게 나올 수 있다.
    • 대신 제품 핵심에 가깝다.
  • 실무에서는 서비스의 초기 단계 때 앱 접속 리텐션을 기준으로 서비스의 생존 여부를 파악한다. 이후 서비스의 성장 단계 때부터 핵심 이벤트 기준 리텐션을 기준으로 서비스의 어떤 이벤트가 리텐션을 만들어냈는지 확인한다.

  1. 리텐션의 종류
  • Classic

    • 사용자가 처음 참여한 날 이후 정확히 N일 뒤에 다시 참여했는지 계산
    • 딱 하루를 본다.
    • 가장 보수적인 접근법
  • Range

    • 최초 참여 이후, 특정 기간 내 다시 참여했는지 계산
    • 기간 안을 본다.
    • 가장 유연한 접근법
  • Rolling

    • 최초 참여일 이후 N일 이후 다시 참여했는지 계산
    • 이후 어떤 시점이든 본다.
    • 가장 낙관적인 접근법

Confusing Points

user_id가 NULL?

  • 강사님이 주신 테이블로 쿼리를 짜다가 user_idNULL인 행을 보고 당황했다.
  • 생각해보니 회원가입/로그인을 강제하지 않고 기능을 사용할 수 있는 웹사이트도 존재했다.
  • user_idNULL일 경우를 대비해 GA4는 user_pseudo_id을 사용한다.

user의 수를 구할 때는 DISTINCT로 구하자!

  • 수업 시간에 리텐션 쿼리를 짤 때 방문한 사용자의 수를 구했어야 했는데, DISTINCT 로 하루에 여러 번 방문한 유저 수를 제거하지 못했다.
  • DISTINCT 없이 구한다면 Page View가 된다는 걸 기억하자!

weekly retention 분석하기

  • 유독 시간을 많이 들였던 문제였다. daily retention까지는 구했는데, weekly retention에 어떤 컬럼을 둘지부터 헷갈렸다.
  • 처음에는 처음에는 daily retention 코드를 그대로 가져와 DATETIME_DIFF의 단위만 DAY에서 WEEK로 변경하고, 기준도 여전히 first_date를 사용했다.
  • 하루 단위로는 event_date을 그대로 쓰면 됐지만, 주 단위 분석에서 "같은 주"의 기준을 어떻게 맞출 것인가가 핵심이라는 점을 뒤늦게 깨달았다.
  • 모든 이벤트 날짜를 동일한 주 시작 시점으로 변환하기 위해 DATE_TRUNC(event_date, WEEK)을 사용했다. 이를 기준으로 첫 방문 주 (first_week)와 이후 주를 비교할 수 있었다.
  • 이렇게 주 단위로 기준을 맞추니 첫 주 이후 N주 뒤에도 다시 활동했는가?라는 weekly retention의 정의가 훨씬 명확해졌고, 쿼리 구조도 자연스럽게 정리가 됐다.
  • 분석 단위에 맞는 시간 축을 먼저 설계해야 한다는 점을 명심하자!
WITH base AS (
  SELECT
    user_pseudo_id,
    event_date,
    event_name,
    event_timestamp,
    param.key,
    param.value.string_value,
    param.value.int_value
  FROM advanced.app_logs
  CROSS JOIN UNNEST(event_params) AS param
  WHERE event_date BETWEEN "2022-08-01" AND "2022-08-18" 
), pivot_data AS (
  SELECT
    user_pseudo_id,
    DATE_TRUNC(event_date, WEEK) AS event_week,
    event_name,
    event_timestamp,
    MAX(IF(key = "firebase_screen", string_value, NULL)) AS firebase_screen,
    MAX(IF(key = "food_id", int_value, NULL)) AS food_id,
    MAX(IF(key = "session_id", string_value, NULL)) AS session_id
  FROM base
  GROUP BY ALL
), first_week_table AS (
  SELECT
    DISTINCT
      user_pseudo_id,
      event_week,
    FIRST_VALUE(event_week) OVER (PARTITION BY user_pseudo_id ORDER BY event_week) AS first_week
  FROM
    pivot_data
), diff_of_table AS (
  SELECT
    *, 
    DATE_DIFF(event_week, first_week, WEEK) AS diff_of_week
  FROM
    first_week_table
  ORDER BY
    event_week
), weekly_retention AS (
  SELECT
    first_week,
    diff_of_week,
    COUNT(DISTINCT user_pseudo_id) AS user_cnt
  FROM
    diff_of_table
  GROUP BY
    first_week,
    diff_of_week
  ORDER BY
    first_week,
    diff_of_week
)

SELECT 
  *,
  ROUND(SAFE_DIVIDE(user_cnt, first_cnt), 2) AS weekly_retention_ratio
FROM (
  SELECT 
    *,
    FIRST_VALUE(user_cnt) OVER(PARTITION BY first_week ORDER BY diff_of_week) AS first_cnt
  FROM
    weekly_retention
)

느낀 점

부트캠프 당시 프론트엔드를 맡아 화면 기획과 구현을 동시에 진행했었다. 짧은 개발 일정 속에서 기능을 완성하는 것이 최우선이었고, 발표 이후 서버가 약 일주일 이후까지만 운영되는 구조였기 때문에 이미 구현한 화면을 어떻게 개선할 수 있을지까지 고민할 여유는 없었다. 그 당시의 화면 기획은 대부분 직관과 경험에 의존한 선택에 가까웠다.

그러나 퍼널 분석과 리텐션 분석 수업을 들으면서 화면 개선 역시 감각의 영역이 아니라 분석을 기반으로 한 방법론적 접근이 가능하다는 사실을 처음으로 알게 되었다. 사용자가 어느 단계에서 이탈하는지, 특정 화면 이후 재방문이 이루어지는지와 같은 지표를 통해 화면의 문제를 정의하고 개선 방향을 설정할 수 있다.

화면 개선이 단순한 미적 수정이 아니라 데이터를 통해 문제를 정의하고 개선할 수 있는 영역이라는 점이 새롭게 다가온 하루였다.

profile
데이터 공부

0개의 댓글