본문 바로가기

Project

[AARRR] #1. Acquisition(획득) [Google Analytics(GA)]

Google Analytics란?

 

Google Analytics는 구글에서 제공하는 웹 및 모바일 앱의 트래픽과 사용자 행동을 분석하는 대표적인 웹 분석 도구이다. 웹사이트나 앱에 제공되는 자바스크립트 트래킹 코드를 삽입하면, 방문자가 사이트에 접속할 때마다 그 행동(페이지 조회, 세션 지속 시간, 이탈률, 전환 등)을 자동으로 기록하고, 이 데이터를 기반으로 다양한 보고서를 생성한다.

 

 

BigQuery란?

 

빅쿼리(BigQuery)는 구글 클라우드 플랫폼에서 제공하는 서버리스 데이터 웨어하우스 서비스이다. 별도의 인프라 관리 없이, SQL을 통해 페타바이트(PB) 규모의 대용량 데이터를 빠르게 저장, 분석, 쿼리할 수 있도록 설계되어 있다.

 

 

AARRR 분석이란?

 

AARRR은 사용자의 서비스 이용흐름을 기반으로 고객 획/ 활성화/ 유지/ 수익/ 추천 이라는 5가지 카테고리를 정의하고 각 카테고리에서 핵심이 되는 지표를 발굴하고 이를 측정/ 개선하는 지표관리 방법론이다.

 

  1. Acquisition (획득):
    고객이 어떻게 해당 서비스나 제품을 알게 되었는지, 즉 유입 경로(검색, 미디어, 광고 등)를 분석.
  2. Activation (활성화):
    첫 방문 후 고객이 긍정적인 경험을 했는지 평가. 예를 들어, 회원 가입, 첫 구매, 앱 내 첫 행동 등이 이에 해당 됨.
  3. Retention (유지):
    고객이 제품이나 서비스를 반복적으로 이용하는지를 측정. 즉, 초기 경험 후 얼마나 많은 고객이 돌아오는지를 분석.
  4. Revenue (수익):
    고객으로부터 얼마나 수익을 창출할 수 있는지를 파악. 구매, 구독, 광고 클릭 등의 수익 창출 지표를 포함.
  5. Referral (추천):
    기존 고객이 다른 사람에게 제품이나 서비스를 추천하는지, 즉 자연스러운 입소문 효과를 분석.

 

이번 포스팅에서는 데이터 소개와 AARRR의 첫 번째 순서인 Acqusition(획득) 단계에 대해 분석할 것이다.


데이터 확인

  • 원본 데이터 : Google Analytics Sample
  • 데이터가 수집된 사이트 : Google Merchandise Store
  • 기간 : 2016년 8월 1일 ~ 2017년 8월 1일
  • 요약 (구글 애널리틱스에서 제공되는 데이터 종류) :
    • 트래픽 소스 데이터: 웹사이트 방문자의 출처에 대한 정보(자연 트래픽, 유료 검색 트래픽, 디스플레이 트래픽 등)
    • 콘텐츠 데이터: 사이트에서 사용자의 행동에 대한 정보(방문자가 보는 페이지의 URL, 콘텐츠와 상호 작용하는 방식 등)
    • 거래 데이터: 웹사이트에서 발생하는 거래에 관한 정보.
    • etc.

 

먼저, 분석에 사용할 데이터를 확인해보자.

from google.cloud import bigquery
import pandas as pd
import numpy as np

import os
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = r"/content/drive/MyDrive/Colab Notebooks/AARRR/aarrr-project-3f905304d852.json"

# Client 객체 생성
client = bigquery.Client()

# 데이터셋 참조경로(reference) 설정
dataset_ref = client.dataset('google_analytics_sample', project='bigquery-public-data')

# 해당 경로로부터 데이터셋 추출
dataset = client.get_dataset(dataset_ref)

# 데이터셋을 테이블 단위로 보기
tables = list(client.list_tables(dataset))
table_names = sorted([t.table_id for t in tables])

# 테이블 단위로 간단한 정보 확인
print(f"""table 개수 : {len(tables)}
tables : {", ".join(table_names[:3])}, ...
date 범위 : {table_names[0][-8:]} ~ {table_names[-1][-8:]}""")

 

데이터셋은 여러 개의 테이블로 구성되어 있으며, 각 테이블의 컬럼 정보는 다음과 같다.

# 테이블 경로 생성
table_ref_temp = dataset_ref.table(table_names[0])

# 테이블 가져오기
table_temp = client.get_table(table_ref_temp)

# 컬럼 확인
client.list_rows(table_temp, max_results=5).to_dataframe()

데이터셋에서 하나의 테이블을 추출해서 컬럼 정보와 구성을 확인할 수 있음.

 

 

아래는 위의 각 스키마가 어떤 데이터로 이루어졌는지 확인하는 과정이다.

def format_schema_field(schema_field, indent=0):
    """
    빅쿼리 스키마의 (중첩된 구조 내부까지) 필드 이름과 데이터 타입을 출력하는 함수
    """

    indent_str = "  " * indent
    field_info = f"{indent_str}{schema_field.name} ({schema_field.field_type})"

    if schema_field.mode != "NULLABLE":
        field_info += f" - {schema_field.mode}"

    if schema_field.description:
        field_info += f" - {schema_field.description}"

    nested_indent = indent + 2
    if schema_field.field_type == "RECORD":
        for sub_field in schema_field.fields:
            field_info += "\n" + format_schema_field(sub_field, nested_indent)

    return field_info

# Display schemas
print("SCHEMA field for the 'totals' column:\n")
print(format_schema_field(table_temp.schema[5]))
print()

print("\nSCHEMA field for the 'trafficSource' column:\n")
print(format_schema_field(table_temp.schema[6]))
print()


print("\nSCHEMA field for the 'device' column:\n")
print(format_schema_field(table_temp.schema[7]))
print()

print("\nSCHEMA field for the 'geoNetwork' column:\n")
print(format_schema_field(table_temp.schema[8]))
print()

print("\nSCHEMA field for the 'customDimensions' column:\n")
print(format_schema_field(table_temp.schema[9]))
print()

print("\nSCHEMA field for the 'hits' column:\n")
print(format_schema_field(table_temp.schema[10]))

실행 결과 일부


Acquisition (획득)

사용자들을 어떻게 데려올 것인가? 

사용자를 우리 서비스로 데려오는 것과 관련된 활동. 즉, 신규 고객이 생기는 것을 의미한다.

Aquisition의 핵심은 고객 유치에 기여(Attribution)한 채널의 성과를 판단할 수 있는 모델을 만드는 것이다.

어떤 채널을 통해 들어온 사용자들이 꾸준히 남아서 활동하는지, 결제로 전환되는 비율이 얼마나 되는지 등을 바탕으로 각 채널의 가치를 정확히 판단할수 있어야 이를 기반으로 전체적인 전략을 수립하거나 예산을 분배할 수 있기 때문이다. 

 

KPI

방문자 수, 유입 경로, 전환율, 이탈율


1. 유입 경로

(1) 최다 유입 경로

# 유입이 가장 많이 된 경로 탑 10 쿼리 작성
query = f"""
SELECT
    trafficSource.source AS source,
    count(*) AS visit_count
FROM
    `bigquery-public-data.google_analytics_sample.ga_sessions_*`
WHERE
    _TABLE_SUFFIX BETWEEN '20160801' AND '20170801'
GROUP BY
    source
ORDER BY
    visit_count DESC
LIMIT 10
"""

# 쿼리 실행 및 데이터 가져오기
query_job = client.query(query)
df_inflow = query_job.to_dataframe()

# 결과 출력
df_inflow

(direct)는 외부 링크나 검색엔진 등을 통해 유입되지 않고, 직접 사이트에 접근한 경우이다. ex) 모바일 앱, 북마크, URL직접입력

 

직접 접근한 경우(direct)와 구글, 유튜브가 대부분의 유입 경로를 차지하고 있다.

 

 

(2) 월별 유입 경로

# 월별 유입 경로 분석 쿼리 작성
query = """
WITH 
grouped AS (
  SELECT
      SUBSTR(_TABLE_SUFFIX, 1, 6) AS month,
      trafficSource.source AS source,
      COUNT(*) AS visit_count
  FROM 
      `bigquery-public-data.google_analytics_sample.ga_sessions_*`
  WHERE 
      _TABLE_SUFFIX BETWEEN '20160801' AND '20170731'
  GROUP BY 
      SUBSTR(_TABLE_SUFFIX, 1, 6), trafficSource.source
),
ranked AS (
  SELECT
      month,
      source,
      visit_count,
      ROW_NUMBER() OVER (
        PARTITION BY month
        ORDER BY visit_count DESC
      ) AS rn
  FROM 
      grouped
)
SELECT
    month,
    source,
    visit_count
FROM 
    ranked
WHERE 
    rn <= 5
ORDER BY 
    month, visit_count DESC;
"""

# 쿼리 실행 및 데이터 가져오기
query_job = client.query(query)
df_monthly = query_job.to_dataframe()

# 결과 출력
df_monthly

결과의 일부

 

 

(3) 유입 경로별 신규/재방문자의 비율

# 유입 경로별 신규 방문자, 재방문자 비율 분석 쿼리 작성
# 이때, totals.newVisit 변수의 경우 신규 방문자는 1, 재방문자는 NULL이다.
query = """
SELECT
    trafficSource.source AS source,
    COUNT(*) AS visit_count,
    SUM(CASE WHEN totals.newVisits = 1 THEN 1 ELSE 0 END) / COUNT(*) AS new_visitors_rate,
    SUM(CASE WHEN totals.newVisits = 1 THEN 0 ELSE 1 END) / COUNT(*) AS returning_visitors_rate
FROM
    `bigquery-public-data.google_analytics_sample.ga_sessions_*`
WHERE
    _TABLE_SUFFIX BETWEEN '20160801' AND '20170731'
GROUP BY
    source
ORDER BY
    visit_count DESC
LIMIT 10
"""

# 쿼리 실행 및 데이터 가져오기
query_job = client.query(query)
df_visit = query_job.to_dataframe()

# 결과 출력
df_visit

세션 수 상위 10개 유입 경로의 신규/재방문자 비율

  • dfa: Google의 DFA(Campaign Manager 360의 이전 버전) 광고 캠페인에서 유입
  • sites.google.com: 다른 사용자가 만든 Google Sites 페이지에 판매자의 웹사이트 링크가 포함되어 있어, 해당 링크를 통해 방문자가 유입 (이번 분석에서 판매자는 Goolge Merchandise Store)

 

(4) 유입 경로별 체류 시간

  • 정규분포를 따르지 않고 이상치가 존재
  • 그러므로 평균이 아닌 중앙값 사용
  • totals.timeOnScreen: 사용자가 웹사이트에서 머문 총 시간을 초 단위로 나타낸 변수
# 유입 경로별 체류 시간 분석 쿼리 작성
query = """
SELECT
    trafficSource.source AS source,
    COUNT(*) AS visit_count,
    APPROX_QUANTILES(totals.timeOnSite, 100)[SAFE_ORDINAL(50)] AS median_sreen_time
FROM
    `bigquery-public-data.google_analytics_sample.ga_sessions_*`
WHERE
    _TABLE_SUFFIX BETWEEN '20160801' AND '20170801'
GROUP BY
    source
ORDER BY
    visit_count DESC
LIMIT 11
"""

# 쿼리 실행 및 데이터 가져오기
query_job = client.query(query)
df_timeOnScreen = query_job.to_dataframe()

# 결과 출력
df_timeOnScreen

세션 수 상위 11개의 유입 경로별 체류 시간

  • Partner: Google과 제휴 관계에 있는 타사 플랫폼이나 서비스를 통해 유입된 트래픽

 

위의 결과로 태블로 대시보드를 제작해보았다.

유입 경로 분석 대시보드


2. 캠페인별 세션 수

# 캠페인별 세션 수 분석 쿼리 작성
query = """
SELECT
    trafficSource.campaign AS campaign,
    COUNT(*) AS visit_count,
FROM
    `bigquery-public-data.google_analytics_sample.ga_sessions_*`
WHERE
    _TABLE_SUFFIX BETWEEN '20160801' AND '20170801'
GROUP BY
    campaign
ORDER BY
    visit_count DESC
"""

# 쿼리 실행 및 데이터 가져오기
query_job = client.query(query)
df_campaign = query_job.to_dataframe()

# 결과 출력
df_campaign


3. 방문 매체별 세션 수

# 방문 매체별 세션 수 분석 쿼리 작성
query = """
SELECT
    trafficSource.medium AS medium,
    COUNT(*) AS visit_count,
FROM
    `bigquery-public-data.google_analytics_sample.ga_sessions_*`
WHERE
    _TABLE_SUFFIX BETWEEN '20160801' AND '20170801'
GROUP BY
    medium
ORDER BY
    visit_count DESC
"""

# 쿼리 실행 및 데이터 가져오기
query_job = client.query(query)
df_medium = query_job.to_dataframe()

# 결과 출력
df_medium

스키마 trafficSource.medium의 구성 요소


none

  • 보통 직접 방문(Direct Traffic)을 의미.
  • 사용자가 URL을 직접 입력하거나 즐겨찾기를 통해 접속하는 경우, 캠페인 정보 없이 medium이 "(none)"으로 표시됨.

referral

  • 다른 웹사이트에서 링크를 통해 유입된 트래픽.
  • 방문자가 외부 사이트의 링크를 클릭해 도착한 경우 medium이 "referral"로 설정됨.

organic

  • 유료 광고가 아닌, 검색엔진의 자연 검색 결과(Organic Search)에서 유입된 트래픽.
  • 구글, 네이버, 빙 등에서 자연 검색 결과로 방문했을 때 medium은 "organic".

affiliate

  • 제휴(affiliate) 마케팅을 통해 유입된 트래픽.
  • 제휴 프로그램 링크를 통해 방문한 경우 이 값이 사용됨.

cpc

  • 클릭당 비용(Cost Per Click) 광고를 통해 유입된 트래픽.
  • 구글 애즈와 같은 유료 검색 캠페인에서 클릭을 통해 방문한 경우 medium은 "cpc".

cpm

  • 천 회 노출당 비용(Cost Per Mille) 광고를 통해 유입된 트래픽.
  • 노출 기반의 광고 캠페인에서 유입된 트래픽의 경우 "cpm"이 사용될 수 있다.

not set

  • 캠페인 매개변수나 추적 정보가 제대로 전달되지 않아, medium 값이 설정되지 않은 경우에 나타남.
  • 설정 오류나 데이터 누락 등으로 인해 "not set"으로 표시됨.

4. 국가별 세션 수

# 국가별 세션 수 분석 쿼리 작성
query = """
SELECT
    geoNetwork.country AS country,
    COUNT(*) AS visit_count,
FROM
    `bigquery-public-data.google_analytics_sample.ga_sessions_*`
WHERE
    _TABLE_SUFFIX BETWEEN '20160801' AND '20170801'
GROUP BY
    country
ORDER BY
    visit_count DESC
LIMIT 10
"""

# 쿼리 실행 및 데이터 가져오기
query_job = client.query(query)
df_country = query_job.to_dataframe()

# 결과 출력
df_country


인사이트

1. 유입 경로 분석 (세션 수 기준)

  • 총 세션 수: 877,993회
  • 최다 유입 경로:
    • (direct) (42.31%) >  google (27.48%) > youtube.com (24.21%)
    • 직접 방문 (direct)이 가장 높은 비중을 차지, 브랜드 인지도가 높거나 즐겨찾기 활용 가능성이 큼
    • google, youtube를 통한 유입이 많아 검색 및 콘텐츠 기반 유입이 중요

2. 신규 방문자 vs 재방문자 비율

  • youtube.com과 baidu를 통해 들어온 방문자는 신규 방문자 비율(0.94, 0.93)이 매우 높음
  • 반면 dfa, sites.google.com 등은 재방문자 비율(0.73, 0.65)이 상대적으로 높음
  • 검색 및 추천(YouTube, Baidu) 기반 유입은 신규 유저가 많음 → 콘텐츠 최적화 필요
  • dfa, sites.google.com의 경우 광고 캠페인이 특정 관심사를 가진 타깃 그룹에게 노출될 가능성이 있고, 특히 dfa의 경우 리마케팅 캠페인을 통해 기존 방문자에게 다시 다가가는 전략이 작동하여 재방문율이 높음 → 충성도 높은 고객 관리 필요

3. 유입 경로별 체류 시간 분석

  • facebook.com (144초) > Partners (105초) > (direct) (99초) 순으로 체류 시간이 김
  • youtube.com은 체류 시간이 52초로 가장 짧음
    • 유튜브는 신규 방문자가 많지만, 체류 시간이 짧아 즉각적인 이탈 가능성이 있음
    • 반면, facebook.com은 체류 시간이 가장 길어, 콘텐츠 소비 시간이 김

4. 방문 매체별 세션 수 분석

  • (none), referral, organic 방문이 압도적으로 많음
  • 광고 유입 (cpc: 13,079, cpm: 6,184) 비중이 낮음
    • 유료 광고보다는 자연 검색 및 추천을 통한 유입이 많음
    • 광고 최적화(ROAS 분석) 필요

5. 국가별 방문자 분석

  • United States (364,744)이 가장 많고, India (51,140), United Kingdom (37,393) 순
  • 미국 유저 비율이 압도적 → 미국 시장 맞춤형 콘텐츠 필요
  • 아시아 국가(Vietnam, Thailand, Japan) 유입도 존재 → 다국적 타겟팅 고려 가능

참조 노트북