기존 고객평생가치를 기반으로 새로운 잠재고객 빌드

Google Ads에서 유사 잠재고객을 빌드하여 고객평생가치(CLV)를 예측하고 이 데이터를 사용하여 잠재적인 신규 고객을 식별하는 방법을 알아봅니다.

개요

이 가이드에서는 고객의 트랜잭션 내역을 기반으로 지정된 기간 동안 고객별 예상 금전적 가치를 예측하는 방법을 보여줍니다. 이를 위해 필요한 단계는 다음과 같습니다.

  • 트랜잭션 및 고객 데이터를 BigQuery로 가져옵니다.
  • 머신러닝(ML) 모델에 사용하기 위해 데이터를 처리합니다.
  • BigQuery ML을 사용하여 ML 모델을 빌드합니다.
  • 모델 예측을 통해 CLV별 최상위 고객을 식별합니다.
  • 고객 데이터 테이블에서 해당 고객에 대해 이메일 주소를 검색합니다.
  • 이 조합 데이터를 사용해서 Google Ads에 사용할 리마케팅 목록을 만듭니다.
  • 이 리마케팅 목록을 광고 타겟팅에 사용할 유사 잠재고객을 생성하기 위한 기초로 사용합니다.

이 가이드에서는 처방적 가이드 및 단계별 절차와 함께 이러한 목표를 달성하기 위해 AI Platform 노트북을 만드는 과정을 안내합니다. 대신 바로 시작할 수 있도록 완성된 메모장이 필요한 경우에는 선택한 메모장 서버에서 bqml_automl_ltv_activate_lookalike.ipynb를 사용할 수 있습니다.

이 가이드는 비즈니스 의사결정을 돕기 위해 ML 데이터 세트 및 모델을 빌드하는 데이터 엔지니어, 데이터 과학자, 데이터 애널리스트를 대상으로 합니다. 여기에서는 사용자가 다음 기본 지식을 갖고 있다고 가정합니다.

  • 머신러닝 개념 및 Python에 대한 기본 이해
  • 표준 SQL

이 가이드에서는 CLV 예측에 관한 또 다른 가이드 시리즈의 네 번째 마지막 부분인 AutoML Tables를 사용한 고객평생가치 예측에 사용된 예시를 리팩토링합니다. CLV 검색을 위한 특성 추출 및 모델 개발 수행과 관련된 핵심 의사결정 요소를 더 자세히 알고 싶으면 해당 시리즈의 첫 번째 가이드인 AI Platform을 사용한 고객평생가치 예측: 소개를 참조하세요.

이 가이드의 예시가 AutoML Tables를 사용한 고객평생가치 예측의 예시와 다른 점은 다음과 같습니다.

  • 모델 학습에 사용하기 위해 고객별로 여러 레코드를 만듭니다. 이를 위해 고객 트랜잭션을 겹치는 기간으로 분류합니다.
  • 모델을 사용해서 서로 다른 기간에 대해 CLV를 예측할 수 있습니다. 예를 들어 모델 입력 매개변수만 변경하여 1개월 또는 1분기 동안 CLV를 예측할 수 있습니다.
  • BigQuery ML에서 직접 AutoML을 사용하여 개발 시간을 최소화합니다.
  • 영업 및 고객 데이터에 대해 다른 데이터 세트를 사용합니다.
  • CLV 예측을 사용하여 Google Ads에서 유사 잠재고객을 만드는 방법을 보여줍니다.

데이터 세트

유사 잠재고객을 빌드할 수 있는 높은 CLV 고객 목록을 만들려면 두 가지 데이터 세트가 필요합니다.

  • 평가하려는 고객의 영업 트랜잭션. 이 데이터 기반 계산을 사용하여 CLV 모델을 학습시킬 수 있습니다. 프로덕션 사용 사례에서는 주문 처리 시스템에서 이 정보를 가져옵니다.
  • 고객 이메일 주소. 프로덕션 사용 사례에서는 고객 관계 관리(CRM) 시스템에서 이 정보를 가져옵니다.

이 가이드에서는 BigQuery 테이블에 로드하는 두 가지 CSV 파일로 샘플 데이터를 제공합니다. 이러한 두 데이터 세트에는 고객 이메일 주소를 해당 CLV 정보와 연결하기 위해 테이블을 조인할 때 사용하는 고객 ID가 포함되어 있습니다.

모델

이 가이드에서는 고객의 미래 금전적 가치를 예측하기 위해 사용할 회귀 모델을 만드는 방법을 보여줍니다. 이 모델 유형은 CLV 금액과 같은 연속 변수(연속 가치라고도 부름)를 예측하는 데 적합하기 때문입니다.

특히 이 가이드에서는 BigQuery ML을 사용하여 AutoML 회귀 모델을 만듭니다. AutoML을 사용하면 다음과 같이 개발 오버헤드를 최소화하는 데 도움이 됩니다.

  • 특성 추출 - AutoML이 몇 가지 일반적인 특성 추출 태스크를 자동으로 처리합니다.
  • BigQuery ML 통합 - BigQuery ML SQL 문을 사용하여 AutoML 모델을 만들 수 있으므로, 서로 다른 개발 컨텍스트 간에 전환할 필요가 없습니다.
  • 학습 데이터 세트 분할 - 모델을 학습시킬 때는 학습, 검증, 테스트의 세 가지 겹치지 않는 데이터 세트로 데이터를 분할하는 것이 좋습니다. AutoML은 기본적으로 이를 처리합니다. 필요한 경우에는 특정 분할을 지정할 수도 있습니다.

특성 및 라벨 계산

이 가이드에서는 임곗값 날짜를 사용하여 고객 트랜잭션을 시간 경과에 따라 여러 겹치는 기간으로 분류합니다. 임곗값 날짜는 대상 트랜잭션으로부터 입력 트랜잭션을 분리합니다. 입력 트랜잭션은 임곗값 날짜 이전에 발생하며, 모델에 입력하는 특성을 계산하기 위해 사용됩니다. 대상 트랜잭션은 임곗값 날짜 이후에 발생하며, 예측할 모델을 학습시키는 라벨로 사용되는 해당 기간 동안의 CLV를 계산하기 위해 사용됩니다.

RFM 특성

CLV 모델에서 사용되는 세 가지 중요한 특성은 고객 트랜잭션 내역 데이터로부터 계산되는 최근 구매일, 빈도, 금액(RFM) 값입니다.

  • 최근 구매일: 고객이 언제 마지막으로 주문했는가?
  • 빈도: 고객이 얼마나 자주 구매하는가?
  • 금액: 고객이 얼마를 지출하는가?

다음 다이어그램은 네 명의 고객이 과거에 구매한 일련의 기록을 보여줍니다.

고객 4명의 판매 내역

이 다이어그램은 다음과 같은 각 고객 정보를 표시하여 고객의 RFM 값을 보여줍니다.

  • 최근 구매일: 마지막 구매일과 오늘 사이의 시간으로, 오른쪽 끝에 있는 원과 Now라고 표시된 수직 점선 사이의 거리로 표현됩니다.
  • 빈도: 구매 간의 시간으로, 동일 선상에 있는 원 간의 거리로 표현됩니다.
  • 금액: 매번 지출한 구매 금액이며, 원 크기로 표현됩니다.

Google Ads 통합 요구사항

Google Ads 통합에 관한 이 가이드 섹션의 예시 코드는 작동 중인 Google Ads 환경에 대한 액세스 권한이 필요합니다. 자신의 Google Ads 환경에서 예시 코드를 실행할 수 있도록 하려면 다음 항목이 필요합니다.

  • Google Ads 관리자 계정과 Google Ads API에 대한 액세스 권한. 이러한 항목이 아직 없으면 등록 절차의 안내에 따라 항목을 얻습니다.
  • Google Ads 개발자 토큰, OAuth 클라이언트 ID와 클라이언트 보안 비밀번호, Google Ads Python 클라이언트 라이브러리의 OAuth 갱신 토큰. 이러한 항목이 아직 없으면 AdWords API 액세스 설정의 안내에 따라 항목을 얻습니다. 이 절차의 5단계에서는 googleads-python-lib/examples/adwords/authentication/generate_refresh_token.py를 사용하여 갱신 토큰을 가져오는 방법을 확인할 수 있습니다.
  • CLV 계산을 위해 사용할 수 있는 트랜잭션 데이터와 고객 이메일 주소가 포함된 고객 데이터. 데이터 가져오기 섹션에 제공된 샘플 데이터 위치에 이를 사용합니다. 데이터의 테이블 이름 및 스키마가 샘플 데이터와 동일한지 확인해야 합니다. 다음 표에서는 예상되는 BigQuery 테이블을 설명합니다.

clv.sales 테이블

데이터 유형
customer_id INTEGER
order_id STRING
transaction_date DATE
product_sku STRING
qty INTEGER
unit_price FLOAT

clv.customers 테이블

데이터 유형
customer_id INTEGER
full_name STRING
age INTEGER
job_title STRING
email STRING

목표

  1. BigQuery를 사용하여 학습 데이터를 준비하고 탐색합니다.
  2. BigQuery ML을 사용하여 ML 모델을 빌드, 학습 및 배포합니다.
  3. 배포된 모델로부터 CLV 예측을 얻습니다.
  4. CLV의 상위 20%를 나타내는 고객 목록을 만듭니다.
  5. 상위 CLV 고객 목록을 기준으로 Google Ads 리마케팅 목록을 만들고, 이를 사용해서 해당 고객에 대한 유사 잠재고객을 생성합니다.

비용

이 가이드에서는 다음과 같은 비용이 청구될 수 있는 Google Cloud 구성요소를 사용합니다.

  • AI Platform
  • BigQuery
  • BigQuery ML
  • Compute Engine

가격 계산기를 사용하면 예상 사용량을 기준으로 예상 비용을 산출할 수 있습니다. Google Cloud를 처음 사용하는 사용자는 무료 체험판을 사용할 수 있습니다.

시작하기 전에

  1. Google Cloud 계정에 로그인합니다. Google Cloud를 처음 사용하는 경우 계정을 만들고 Google 제품의 실제 성능을 평가해 보세요. 신규 고객에게는 워크로드를 실행, 테스트, 배포하는 데 사용할 수 있는 $300의 무료 크레딧이 제공됩니다.
  2. Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.

    프로젝트 선택기로 이동

  3. Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다. 프로젝트에 결제가 사용 설정되어 있는지 확인하는 방법을 알아보세요.

  4. Compute Engine, BigQuery, and Notebooks API를 사용 설정합니다.

    API 사용 설정

노트북 만들기

  1. Notebooks 콘솔을 엽니다.
  2. 새 인스턴스를 클릭합니다.
  3. Python 2 및 3을 선택합니다.
  4. 인스턴스 이름clv를 입력합니다.
  5. 만들기를 클릭합니다. 메모장 인스턴스가 생성되는 데 몇 분 정도 걸립니다.
  6. 인스턴스를 사용할 수 있으면 JupyterLab 열기를 클릭합니다.
  7. JupyterLab 런처의 메모장 섹션에서 Python 3을 클릭합니다.

라이브러리 설치

이 가이드에 필요한 googleads 및 기타 라이브러리를 설치합니다.

  1. 다음 코드를 메모장의 첫 번째 셀에 복사합니다.

    # Install libraries.
    %pip install -q googleads
    %pip install -q -U kfp matplotlib Faker --user
    
    # Restart kernel after installs
    import IPython
    app = IPython.Application.instance()
    app.kernel.do_shutdown(True)
    
  2. 메뉴 바에서 실행을 클릭합니다.

패키지 가져오기

다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 이 가이드에 필요한 패키지를 설치합니다.

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os, json, random
import hashlib, uuid
import time, calendar, math
import pandas as pd, numpy as np
import matplotlib.pyplot as plt, seaborn as sns
from datetime import datetime
from google.cloud import bigquery
from googleads import adwords

BigQuery 클라이언트 만들기

다음 코드를 노트북의 다음 빈 셀에 복사한 후 이를 실행하여 BigQuery용 Python 클라이언트 라이브러리에 대한 BigQuery 클라이언트를 만듭니다. myProject를 이 가이드를 완료하는 데 사용할 프로젝트의 ID로 바꿉니다. Google Cloud 프로젝트 대시보드프로젝트 정보 카드에서 프로젝트 ID를 찾을 수 있습니다.

bq_client = bigquery.Client(project="myProject")

데이터 가져오기

다음 섹션의 안내에 따라 샘플 데이터를 BigQuery로 가져온 후 ML 모델 학습에 사용할 수 있도록 처리합니다.

작동 중인 Google Ads 환경이 있으면 샘플을 가져오는 대신 자신의 데이터를 사용할 수 있습니다. CLV 계산에 사용할 수 있는 트랜잭션 데이터를 clv.sales 테이블에 채우고 고객 이메일 주소가 포함된 고객 데이터를 clv.customers 테이블에 채웁니다.

데이터 세트 만들기

예시 데이터에 대해 BigQuery 테이블을 만들려면 먼저 이를 포함할 데이터 세트를 만들어야 합니다.

다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 clv 데이터 세트를 만듭니다. myProject를 이 가이드를 완료하는 데 사용할 프로젝트의 ID로 바꿉니다.

PROJECT_ID = "myProject"
! bq mk $PROJECT_ID:clv

영업 데이터 가져오기

다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 clv.sales 테이블을 만들고 채웁니다.

! bq load \
--project_id $PROJECT_ID \
--skip_leading_rows 1 \
--max_bad_records 100000 \
--replace \
--field_delimiter "," \
--autodetect \
clv.sales \
gs://solutions-public-assets/analytics-componentized-patterns/ltv/sales_*

고객 데이터 가져 오기

다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 clv.customers 테이블을 만들고 채웁니다.

! bq load \
--project_id $PROJECT_ID \
--skip_leading_rows 1 \
--max_bad_records 100000 \
--replace \
--field_delimiter "," \
--autodetect \
clv.customers \
gs://solutions-public-assets/analytics-componentized-patterns/ltv/crm.csv

데이터 준비

ML 모델 학습에 사용할 수 있도록 고객 트랜잭션 데이터를 준비하려면 다음 태스크를 완료해야 합니다.

  • 주문 금전적 가치 및 항목 수량에 대해 허용된 표준 편차를 결정하는 매개변수를 설정합니다. 이러한 매개변수는 고객 트랜잭션 데이터의 초기 집계를 수행할 때 각 고객의 이상점 레코드를 식별하고 삭제하기 위해 사용됩니다.
  • 고객 트랜잭션 데이터를 집계합니다.
  • 데이터를 더 세분화하려는 영역을 확인할 수 있도록 고객별 트랜잭션, 주문별 항목 수와 같은 기준으로 집계 데이터 분포를 확인합니다.
  • RFM 값과 같은 집계 데이터로부터 계산할 특성을 정의합니다.
  • 특성 계산에 사용할 기간을 정의하는 매개변수를 설정합니다. 예를 들어 임곗값 날짜 사이에 있어야 하는 일 수를 설정할 수 있습니다.
  • 모델 학습에 필요한 특성을 계산합니다.

집계 매개변수 설정

집계 절차에 다음 매개변수를 사용하여 최대 표준 편차 값을 정의합니다.

  • MAX_STDV_MONETARY - 고객별 금전적 가치의 표준 편차입니다.
  • MAX_STDV_QTY - 고객별 제품 수량의 표준 편차입니다.

다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 사용할 표준 편차 값을 결정할 매개변수를 설정합니다.

AGG_PARAMS = {
    'MAX_STDV_MONETARY': 500,
    'MAX_STDV_QTY': 100
}

프로덕션 사용 사례에서는 주문 값 및 항목 수량에 허용되는 값 범위를 결정하기 위해 이러한 매개변수를 수정할 수 있습니다.

고객 트랜잭션 데이터 집계

다음 쿼리는 고객별로 모든 일별 주문을 집계합니다. 이 ML 태스크는 주 또는 월과 같은 일정 기간 동안 금전적 가치를 예측하는 것이기 때문에, 일도 고객별 트랜잭션을 그룹화하기 위한 시간 단위로 작동합니다.

이 쿼리는 또한 각 고객의 이상점에 해당하는 주문을 삭제합니다. 주문 값 또는 제품 수량이 MAX_STDV_MONETARYMAX_STDV_QTY로 지정된 허용 가능한 표준 편차 값을 벗어나는 주문은 제외됩니다.

  1. 다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 집계된 고객 트랜잭션 데이터로 테이블을 만듭니다.

    %%bigquery --params $AGG_PARAMS --project $PROJECT_ID
    
    DECLARE MAX_STDV_MONETARY INT64 DEFAULT @MAX_STDV_MONETARY;
    DECLARE MAX_STDV_QTY INT64 DEFAULT @MAX_STDV_QTY;
    
    CREATE OR REPLACE TABLE `clv.aggregation` AS
    SELECT
      customer_id,
      order_day,
      ROUND(day_value_after_returns, 2) AS value,
      day_qty_after_returns as qty_articles,
      day_num_returns AS num_returns,
      CEIL(avg_time_to_return) AS time_to_return
    FROM (
      SELECT
        customer_id,
        order_day,
        SUM(order_value_after_returns) AS day_value_after_returns,
        STDDEV(SUM(order_value_after_returns)) OVER(PARTITION BY customer_id ORDER BY SUM(order_value_after_returns)) AS stdv_value,
        SUM(order_qty_after_returns) AS day_qty_after_returns,
        STDDEV(SUM(order_qty_after_returns)) OVER(PARTITION BY customer_id ORDER BY SUM(order_qty_after_returns)) AS stdv_qty,
        CASE
          WHEN MIN(order_min_qty) < 0 THEN count(1)
          ELSE 0
        END AS day_num_returns,
        CASE
          WHEN MIN(order_min_qty) < 0 THEN AVG(time_to_return)
          ELSE NULL
        END AS avg_time_to_return
      FROM (
        SELECT
          customer_id,
          order_id,
          -- Gives the order date vs return(s) dates.
          MIN(transaction_date) AS order_day,
          MAX(transaction_date) AS return_final_day,
          DATE_DIFF(MAX(transaction_date), MIN(transaction_date), DAY) AS time_to_return,
          -- Aggregates all products in the order
          -- and all products returned later.
          SUM(qty * unit_price) AS order_value_after_returns,
          SUM(qty) AS order_qty_after_returns,
          -- If negative, order has qty return(s).
          MIN(qty) order_min_qty
        FROM
          `clv.sales`
        GROUP BY
          customer_id,
          order_id)
      GROUP BY
        customer_id,
        order_day)
    WHERE
      -- [Optional] Remove dates with outliers per a customer.
      (stdv_value < MAX_STDV_MONETARY
        OR stdv_value IS NULL) AND
      (stdv_qty < MAX_STDV_QTY
        OR stdv_qty IS NULL);
    
  2. 다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 결과 clv.aggregation 테이블로 데이터 샘플을 표시합니다.

    %%bigquery
    
    SELECT * FROM clv.aggregation LIMIT 5;
    

    다음과 비슷한 결과가 표시됩니다.

    집계 데이터의 처음 5개 행

프로덕션 사용 사례에서는 다음 옵션과 같은 추가 선택 기준을 적용하여 데이터를 더 세분화해야 할 수 있습니다.

  • 양수 항목 수량 및 구입 금액이 없는 레코드를 삭제합니다.
  • 고객 ID가 없는 레코드를 삭제합니다.
  • 일정 기준에 따른 활성 고객만 유지합니다. 예를 들어 이전 90일 내에 물건을 구입한 고객에게만 집중할 수 있습니다.

데이터 분포 확인

이 가이드에서는 데이터 정리를 최소화하고 대신 모델에 작동하도록 트랜잭션 데이터의 기본 변환 수행에 집중합니다. 이 섹션에서는 데이터 분포를 확인하여 이상점이 있는 부분과 추가 데이터 세분화가 필요한 부분을 식별합니다.

날짜별 분포 확인

  1. 다음 코드를 노트북의 다음 빈 셀에 복사한 후 이를 실행하여 df_dist_dates 데이터 프레임을 만들고 집계된 데이터의 날짜 데이터를 채웁니다.

    %%bigquery df_dist_dates --project $PROJECT_ID
    
    SELECT count(1) c, SUBSTR(CAST(order_day AS STRING), 0, 7) as yyyy_mm
    FROM `clv.aggregation`
    WHERE qty_articles > 0
    GROUP BY yyyy_mm
    ORDER BY yyyy_mm
    
  2. 다음 코드를 노트북의 다음 빈 셀에 복사한 후 이를 실행하여 seaborn을 사용해서 날짜 데이터를 시각화합니다.

    plt.figure(figsize=(12,5))
    sns.barplot( x='yyyy_mm', y='c', data=df_dist_dates)
    

    다음과 비슷한 결과가 표시됩니다.

    날짜 데이터 분포의 시각화

    이 데이터 세트에서 캡처된 처음 몇 개월은 주문이 조금 낮지만, 주문이 한 해 동안 고르게 분포되어 있습니다. 프로덕션 사용 사례에서는 특성 계산 절차에 대한 시간 매개변수를 설정할 때 날짜별 데이터 분포를 고려할 한 가지 요소로 사용할 수 있습니다.

고객별 트랜잭션별 분포 확인

  1. 다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 df_dist_customers 데이터 프레임을 만들고 집계된 트랜잭션의 고객 트랜잭션 수로 채웁니다.

    %%bigquery df_dist_customers --project $PROJECT_ID
    
    SELECT customer_id, count(1) c
    FROM `clv.aggregation`
    GROUP BY customer_id
    
  2. 다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 seaborn을 사용해서 고객 트랜잭션 데이터를 시각화합니다.

    plt.figure(figsize=(12,4))
    sns.distplot(df_dist_customers['c'], hist_kws=dict(ec="k"), kde=False)
    

    다음과 비슷한 결과가 표시됩니다.

    고객 데이터 분포의 시각화

    이 데이터는 분포가 잘 되어 있고 고객별 트랜잭션 수가 좁은 범위에 걸쳐 분산되어 있고 확실한 이상점이 없습니다.

항목 수량별 분포 확인

  1. 다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 df_dist_qty 데이터 프레임을 만들고 집계된 트랜잭션의 항목 수량 데이터를 채웁니다.

    %%bigquery df_dist_qty --project $PROJECT_ID
    
    SELECT qty_articles, count(1) c
    FROM `clv.aggregation`
    GROUP BY qty_articles
    
  2. 다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 seaborn을 사용해서 항목 수량 데이터를 시각화합니다.

    plt.figure(figsize=(12,4))
    sns.distplot(df_dist_qty['qty_articles'], hist_kws=dict(ec="k"), kde=False)
    

    다음과 비슷한 결과가 표시됩니다.

    항목 수량 데이터 분포의 시각화

    일부 고객은 해당 주문의 수량이 매우 많지만, 일반적으로 분포가 양호합니다. 프로덕션 사용 사례에서는 이 영역에서 더 많은 데이터 엔지니어링을 수행할 수 있습니다. 예를 들어 일반적으로 1~2개의 물품을 구입하는 고객의 경우 20개 품목에 해당하는 트랜잭션을 삭제하는 등의 방식으로 개별 고객의 이상점에 해당하는 트랜잭션을 삭제해야 할 수 있습니다. 일반적으로 다른 고객보다 많은 품목을 구입하는 측면에서 이상점이 있는 고객은 유지해야 할 수 있습니다.

금전적 가치별 분포 확인

  1. 다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 df_dist_values 데이터 프레임을 만들고 집계된 트랜잭션의 금전적 가치 데이터를 채웁니다.

    %%bigquery df_dist_values --project $PROJECT_ID
    
    SELECT value
    FROM `clv.aggregation`
    
  2. 다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 seaborn을 사용해서 금전적 가치 데이터를 시각화합니다.

    axv = sns.violinplot(x=df_dist_values["value"])
    axv.set_xlim(-200, 3500)
    

    다음과 비슷한 결과가 표시됩니다.

    금전적 데이터 분포의 시각화

    이 분포는 평균보다 상당히 많은 금액을 소비하는 몇 가지 이상점을 보여줍니다. 프로덕션 사용 사례에서는 이 영역에서 더 많은 데이터 엔지니어링을 수행할 수 있습니다. 예를 들어 일반적으로 트랜잭션별로 $50 정도를 소비하는 고객의 경우 $1,000 트랜잭션을 삭제하는 등의 방식으로 개별 고객의 이상점에 해당하는 트랜잭션을 삭제해야 할 수 있습니다. 일반적으로 다른 고객보다 많은 금액을 소비하는 측면에서 이상점이 있는 고객은 유지해야 할 수 있습니다.

특성 정의

다음 표에서는 모델 학습을 위해 계산되는 특성을 설명합니다.

특성 이름 유형 설명
monetary FLOAT 특정 기간 동안 특정 고객의 모든 트랜잭션에 해당하는 금전적 가치의 합계입니다.
frequency INTEGER 특정 기간 동안 특정 고객에 의해 발생한 트랜잭션의 수입니다.
recency INTEGER 특정 기간 동안 특정 고객에 의해 발생한 첫 번째 트랜잭션과 마지막 트랜잭션 사이의 시간입니다.
T INTEGER 데이터 세트의 첫 번째 트랜잭션과 입력 트랜잭션 기간의 종료 지점 사이의 시간입니다.
time_between FLOAT 특정 기간 동안 특정 고객의 트랜잭션 간 평균 시간입니다.
avg_basket_value FLOAT 특정 기간 동안 고객의 바구니의 평균 금전적 가치입니다.
avg_basket_size FLOAT 특정 기간 동안 특정 고객이 자신의 바구니에 갖고 있는 평균 항목 수입니다.
has_returns STRING 특정 고객이 특정 기간 동안 하나 이상의 트랜잭션에 대해 물품을 반품했는지 여부입니다.
avg_time_to_return FLOAT 특정 고객이 트랜잭션에 대해 첫 번째 물품을 반환하기까지 걸리는 시간입니다.
num_returns INTEGER 특정 기간에 포함된 트랜잭션과 관련해서 고객이 반품한 물품의 수입니다.

특성 계산 매개변수 설정

다음 매개변수는 특성 계산에 사용할 기간을 정의합니다.

  • WINDOW_STEP - 임곗값 사이의 일 수를 지정합니다. 특성 및 라벨 계산 빈도를 결정합니다.
  • WINDOW_STEP_INITIAL - 학습 데이터의 첫 번째 주문 날짜와 첫 번째 임곗값 사이의 일 수를 지정합니다.
  • WINDOW_LENGTH - 입력 트랜잭션에 사용할 이전 일 수를 지정합니다. 기본값은 지정된 임곗값 이전의 모든 트랜잭션을 사용하는 0 값을 사용하는 것입니다.
  • LENGTH_FUTURE - ML 라벨로 사용되는 monetary 값을 예측하기 위한 미래 일 수를 지정합니다. 각 임곗값에서 BigQuery는 해당 임곗값 날짜 이후의 LENGTH_FUTURE에 발생하는 모든 주문에 대해 라벨 값을 계산합니다.

예를 들어 최초 트랜잭션 날짜가 1/1/2015인 데이터 세트에서는 매개변수 값이 다음과 같이 지정됩니다.

  • WINDOW_STEP: 30
  • WINDOW_STEP_INITIAL: 90
  • WINDOW_LENGTH: 0
  • LENGTH_FUTURE: 30

특성 만들기 절차의 처음 몇 개 루프의 기간은 다음과 같이 작동합니다.

첫 번째 루프

매개변수 계산 방법
임곗값 날짜 최초 트랜잭션 날짜 + WINDOW_STEP_INITIAL 값, 따라서 1/1/2015 + 90일 4/1/2015
기간 시작 WINDOW_LENGTH가 0이므로, 임곗값 이전의 모든 트랜잭션이 사용됩니다. 최초 트랜잭션은 1/1/2015입니다. 1/1/2015
입력 트랜잭션 기간 기간 시작 날짜부터 임곗값 날짜(포함)까지의 기간입니다. 1/1/2015 - 4/1/2015
대상 트랜잭션 기간 임곗값 날짜(제외)부터 임곗값 날짜 + LENGTH_FUTURE로 지정된 일 수까지의 기간입니다(4/1/2015 + 30일). 4/2/2015 - 5/1/2015

두 번째 루프

매개변수 계산 방법
임곗값 날짜 이전 루프의 임곗값 날짜 + WINDOW_STEP 값, 따라서 4/1/2015 + 30일입니다. 5/1/2015
기간 시작 WINDOW_LENGTH가 0이므로, 임곗값 이전의 모든 트랜잭션이 사용됩니다. 최초 트랜잭션은 1/1/2015입니다. 1/1/2015
입력 트랜잭션 기간 기간 시작 날짜부터 임곗값 날짜(포함)까지의 기간입니다. 1/1/2015 - 5/1/2015
대상 트랜잭션 기간 임곗값 날짜(제외)부터 임곗값 날짜 + LENGTH_FUTURE로 지정된 일 수까지의 기간입니다(5/1/2015 + 30일). 5/2/2015 - 5/31/2015

값이 15가 되도록 WINDOW_LENGTH를 수정할 경우 기간이 대신 다음과 같이 작동합니다.

첫 번째 루프

매개변수 계산 방법
임곗값 날짜 최초 트랜잭션 날짜 + WINDOW_STEP_INITIAL 값, 따라서 1/1/2015 + 90일 4/1/2015
기간 시작 임곗값 날짜 - WINDOW_LENGTH 값, 따라서 4/1/2015 - 15일입니다. 3/17/2015
입력 트랜잭션 기간 기간 시작 날짜부터 임곗값 날짜(포함)까지의 기간입니다. 3/17/2015 - 4/1/2015
대상 트랜잭션 기간 임곗값 날짜(제외)부터 임곗값 날짜 + LENGTH_FUTURE로 지정된 일 수까지의 기간입니다(4/1/2015 + 30일). 4/2/2015 - 5/1/2015

두 번째 루프

매개변수 계산 방법
임곗값 날짜 이전 루프의 임곗값 날짜 + WINDOW_STEP 값, 따라서 4/1/2015 + 30일입니다. 5/1/2015
기간 시작 임곗값 날짜 - WINDOW_LENGTH 값, 따라서 5/1/2015 - 15일입니다. 4/16/2015
입력 트랜잭션 기간 기간 시작 날짜부터 임곗값 날짜(포함)까지의 기간입니다. 4/16/2015 - 5/1/2015
대상 트랜잭션 기간 임곗값 날짜(제외)부터 임곗값 날짜 + LENGTH_FUTURE로 지정된 일 수까지의 기간입니다(5/1/2015 + 30일). 5/2/2015 - 5/31/2015

다음 코드를 노트북의 다음 빈 셀에 복사한 후 이를 실행하여 특성 계산 기간을 결정하도록 매개변수를 설정합니다.

CLV_PARAMS = {
    'WINDOW_LENGTH': 0,
    'WINDOW_STEP': 30,
    'WINDOW_STEP_INITIAL': 90,
    'LENGTH_FUTURE': 30
}

프로덕션 사용 사례에서는 작업 중인 데이터에 가장 적합한 결과를 가져오도록 이러한 매개변수를 수정할 수 있습니다. 예를 들어 고객이 한 주에 여러 번 물품을 구입하는 경우, 주간 기간을 사용하여 특성을 계산할 수 있습니다. 또는 데이터가 많은 경우에는 해당 크기를 줄이고, 임곗값 날짜 사이의 일 수를 줄여서 더 많은 기간을 만들 수 있습니다. 초매개변수 조정 외에도 이러한 매개변수 실험을 통해 모델 성능을 향상시킬 수 있습니다.

특성 만들기

  1. 다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 모델 학습을 위해 계산된 특성으로 테이블을 만듭니다.

    %%bigquery --params $CLV_PARAMS --project $PROJECT_ID
    
    -- Length
    -- Date of the first order in the dataset.
    DECLARE MIN_DATE DATE;
    -- Date of the final order in the dataset.
    DECLARE MAX_DATE DATE;
    -- Date that separates inputs orders from target transactions.
    DECLARE THRESHOLD_DATE DATE;
    -- How many days back for inputs transactions. 0 means from the start.
    DECLARE WINDOW_LENGTH INT64 DEFAULT @WINDOW_LENGTH;
    -- Date at which an input transactions window starts.
    DECLARE WINDOW_START DATE;
    -- How many days between thresholds.
    DECLARE WINDOW_STEP INT64 DEFAULT @WINDOW_STEP;
    -- How many days for the first window.
    DECLARE WINDOW_STEP_INITIAL INT64 DEFAULT @WINDOW_STEP_INITIAL;
    -- Index of the window being run.
    DECLARE STEP INT64 DEFAULT 1;
    -- How many days to predict for.
    DECLARE LENGTH_FUTURE INT64 DEFAULT @LENGTH_FUTURE;
    
    SET (MIN_DATE, MAX_DATE) = (
      SELECT AS STRUCT
        MIN(order_day) AS min_days,
        MAX(order_day) AS max_days
      FROM
        `clv.aggregation`
    );
    
    SET THRESHOLD_DATE = MIN_DATE;
    
    -- For more information about the features of this table,
    -- see https://github.com/CamDavidsonPilon/lifetimes/blob/master/lifetimes/utils.py#L246
    -- and https://cloud.google.com/solutions/machine-learning/clv-prediction-with-offline-training-train#aggregating_data
    CREATE OR REPLACE TABLE clv.features
    (
      customer_id STRING,
      monetary FLOAT64,
      frequency INT64,
      recency INT64,
      T INT64,
      time_between FLOAT64,
      avg_basket_value FLOAT64,
      avg_basket_size FLOAT64,
      has_returns STRING,
      avg_time_to_return FLOAT64,
      num_returns INT64,
      -- threshold DATE,
      -- step INT64,
      target_monetary FLOAT64,
    );
    
    -- Using a BigQuery scripting loop
    -- (https://cloud.google.com/bigquery/docs/reference/standard-sql/scripting#loop)
    -- lets you enhance the logic of your query without the need of another
    -- programming language or client code.
    
    LOOP
      -- Can choose a longer original window in case
      -- there were not many orders in the early days.
      IF STEP = 1 THEN
        SET THRESHOLD_DATE = DATE_ADD(THRESHOLD_DATE, INTERVAL WINDOW_STEP_INITIAL DAY);
      ELSE
        SET THRESHOLD_DATE = DATE_ADD(THRESHOLD_DATE, INTERVAL WINDOW_STEP DAY);
      END IF;
      SET STEP = STEP + 1;
    
      IF THRESHOLD_DATE >= DATE_SUB(MAX_DATE, INTERVAL (WINDOW_STEP) DAY) THEN
        LEAVE;
      END IF;
    
      -- Takes all transactions before the threshold date unless you decide
      -- to use a different window length to test model performance.
      IF WINDOW_LENGTH != 0 THEN
        SET WINDOW_START = DATE_SUB(THRESHOLD_DATE, INTERVAL WINDOW_LENGTH DAY);
     ELSE
        SET WINDOW_START = MIN_DATE;
      END IF;
       INSERT clv.features
      SELECT
        CAST(tf.customer_id AS STRING),
        ROUND(tf.monetary_orders, 2) AS monetary,
        tf.cnt_orders AS frequency,
        tf.recency,
        tf.T,
        ROUND(tf.recency/cnt_orders, 2) AS time_between,
        ROUND(tf.avg_basket_value, 2) AS avg_basket_value,
        ROUND(tf.avg_basket_size, 2) AS avg_basket_size,
        has_returns,
        CEIL(avg_time_to_return) AS avg_time_to_return,
        num_returns,
        ROUND(tt.target_monetary, 2) AS target_monetary,
      FROM (
          -- This SELECT uses only data before THRESHOLD_DATE to make features.
          SELECT
            customer_id,
            SUM(value) AS monetary_orders,
            DATE_DIFF(MAX(order_day), MIN(order_day), DAY) AS recency,
            DATE_DIFF(THRESHOLD_DATE, MIN(order_day), DAY) AS T,
            COUNT(DISTINCT order_day) AS cnt_orders,
            AVG(qty_articles) avg_basket_size,
            AVG(value) avg_basket_value,
            CASE
              WHEN SUM(num_returns) > 0 THEN 'y'
              ELSE 'n'
            END AS has_returns,
            AVG(time_to_return) avg_time_to_return,
            THRESHOLD_DATE AS threshold,
            SUM(num_returns) num_returns,
          FROM
            `clv.aggregation`
          WHERE
            order_day <= THRESHOLD_DATE AND
            order_day >= WINDOW_START
          GROUP BY
            customer_id
        ) tf
          INNER JOIN (
        -- This SELECT uses all data after threshold as target.
        SELECT
          customer_id,
          SUM(value) target_monetary
        FROM
          `clv.aggregation`
        WHERE
          order_day <= DATE_ADD(THRESHOLD_DATE, INTERVAL LENGTH_FUTURE DAY)
          -- For the sample data, the overall value is similar to the value
          -- after threshold, and prediction performs better using the overall
          -- value. When using your own data, try uncommenting the following
          -- AND clause and see which version of the procedure gives you better
          -- results.
          -- AND order_day > THRESHOLD_DATE
        GROUP BY
          customer_id) tt
      ON
          tf.customer_id = tt.customer_id;
      END LOOP;
    
  2. 다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 결과 clv.features 테이블로 한 고객의 데이터 샘플을 표시합니다.

    %%bigquery
    
    SELECT * FROM `clv.features` WHERE customer_id = "10"
    UNION ALL
    (SELECT * FROM `clv.features` LIMIT 5)
    ORDER BY customer_id, frequency, T LIMIT 5
    
    

    다음과 비슷한 결과가 표시됩니다.

    특성 데이터의 처음 5개 행

모델 학습

이 가이드에서는 BigQuery ML의 AUTOML_REGRESSOR를 사용하여 AutoML 회귀 모델을 생성, 학습, 배포합니다.

이 가이드에서는 기본 설정을 사용하여 모델을 학습시킵니다. 프로덕션 사용 사례에서는 모델 향상을 위해 추가적인 특성 추출 기법 및 여러 다른 학습 데이터 분할을 시도할 수 있습니다.

다음 코드를 노트북의 다음 빈 셀에 복사한 후 이를 실행하여 clv_model 모델을 만들고 채웁니다.

%%bigquery

CREATE OR REPLACE MODEL `clv.clv_model`
       OPTIONS(MODEL_TYPE="AUTOML_REGRESSOR",
               INPUT_LABEL_COLS=["target_monetary"],
               OPTIMIZATION_OBJECTIVE="MINIMIZE_MAE")
AS SELECT
  * EXCEPT(customer_id)
FROM
  `clv.features`

그러면 작업을 시작할 좋은 기본 모델이 준비됩니다. 고유 데이터 및 사용 사례에 맞게 모델을 조정하기 위해서는 초매개변수 조정, 특성 추출, 기타 기법을 사용하여 최적화할 수 있습니다.

CLV 예측

다음 단계에서는 각 고객의 모델로부터 CLV 예측을 얻고 이 데이터를 테이블로 작성합니다. 예측 레코드에는 다음 테이블에 설명된 필드가 포함됩니다.

필드 이름 유형 설명
customer_id STRING 고객 ID
monetary_so_far FLOAT 예측 날짜 전 고객이 지불한 총 금액입니다.
monetary_predicted FLOAT 고객이 지불하는 총 예측 금액이며, monetary_so_farmonetary_future 필드 값의 합계입니다.
monetary_future FLOAT 예측 날짜와 예측 기간의 종료 시점 사이에 고객이 지불할 미래 예측 금액입니다.
  1. 다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 clv.predictions 테이블을 만들고 채웁니다.

    %%bigquery --params $CLV_PARAMS --project $PROJECT_ID
    
    -- How many days back for inputs transactions. 0 means from the start.
    DECLARE WINDOW_LENGTH INT64 DEFAULT @WINDOW_LENGTH;
    -- Date at which an input transactions window starts.
    DECLARE WINDOW_START DATE;
    
    -- Date of the first transaction in the dataset.
    DECLARE MIN_DATE DATE;
    -- Date of the final transaction in the dataset.
    DECLARE MAX_DATE DATE;
    -- Date from which you want to predict.
    DECLARE PREDICT_FROM_DATE DATE;
    
    SET (MIN_DATE, MAX_DATE) = (
      SELECT AS STRUCT
        MIN(order_day) AS min_days,
        MAX(order_day) AS max_days
      FROM
        `clv.aggregation`
    );
    
    -- You can set any date here. In production, it is generally today.
    SET PREDICT_FROM_DATE = MAX_DATE;
    IF WINDOW_LENGTH != 0 THEN
      SET WINDOW_START = DATE_SUB(PREDICT_FROM_DATE, INTERVAL WINDOW_LENGTH DAY);
    ELSE
      SET WINDOW_START = MIN_DATE;
    END IF;
    
    CREATE OR REPLACE TABLE `clv.predictions`
    AS (
    SELECT
      customer_id,
      monetary AS monetary_so_far,
      ROUND(predicted_target_monetary, 2) AS monetary_predicted,
      ROUND(predicted_target_monetary - monetary, 2) AS monetary_future
    FROM
      ML.PREDICT(
        -- To use your own model, set the model name here.
        MODEL clv.clv_model,
        (
          SELECT
            customer_id,
            ROUND(monetary_orders, 2) AS monetary,
            cnt_orders AS frequency,
            recency,
            T,
            ROUND(recency/cnt_orders, 2) AS time_between,
            ROUND(avg_basket_value, 2) AS avg_basket_value,
            ROUND(avg_basket_size, 2) AS avg_basket_size,
            has_returns,
            CEIL(avg_time_to_return) AS avg_time_to_return,
            num_returns
          FROM (
            SELECT
              customer_id,
              SUM(value) AS monetary_orders,
              DATE_DIFF(MAX(order_day), MIN(order_day), DAY) AS recency,
              DATE_DIFF(PREDICT_FROM_DATE, MIN(order_day), DAY) AS T,
              COUNT(DISTINCT order_day) AS cnt_orders,
              AVG(qty_articles) avg_basket_size,
              AVG(value) avg_basket_value,
              CASE
                WHEN SUM(num_returns) > 0 THEN 'y'
                ELSE 'n'
              END AS has_returns,
              AVG(time_to_return) avg_time_to_return,
              SUM(num_returns) num_returns,
            FROM
              `clv.aggregation`
            WHERE
              order_day <= PREDICT_FROM_DATE AND
              order_day >= WINDOW_START
            GROUP BY
              customer_id
          )
        )
      )
    )
    
  2. 다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 결과 clv.features 테이블로 데이터 샘플을 표시합니다.

    %%bigquery
    
    SELECT * FROM clv.predictions
    ORDER BY customer_id
    LIMIT 5;
    

    다음과 비슷한 결과가 표시됩니다.

    예측 데이터의 처음 5개 행

예측 데이터 평가

데이터 분포를 더 효과적으로 이해하고 명확한 추세가 있는지 확인하기 위해 예측 데이터를 시각화하고 통계를 생성합니다.

  1. clv.predictions 테이블을 기준으로 데이터 프레임을 만듭니다.

    %%bigquery df_predictions --project $PROJECT_ID
    
    clv.predictions
    
  2. 다음 코드를 노트북의 다음 빈 셀에 복사한 후 이를 실행하여 pandas.DataFrame.describe를 사용해서 예측 데이터로 자세한 통계를 생성합니다.

    df_predictions.describe()
    

    다음과 비슷한 결과가 표시됩니다.

    예측 데이터의 통계입니다.

  3. 다음 코드를 노트북의 다음 빈 셀에 복사한 후 이를 실행하여 matplotlib.gridspec를 사용해서 예측 데이터를 시각화합니다.

    from matplotlib.gridspec import GridSpec
    
    fig = plt.figure(constrained_layout=True, figsize=(15, 5))
    gs = GridSpec(2, 2, figure=fig)
    
    sns.set(font_scale = 1)
    plt.tick_params(axis='x', labelsize=14)
    
    ax0 = plt.subplot(gs.new_subplotspec((0, 0), colspan=1))
    ax1 = plt.subplot(gs.new_subplotspec((0, 1), colspan=1))
    ax2 = plt.subplot(gs.new_subplotspec((1, 0), colspan=2))
    
    sns.violinplot(df_predictions['monetary_so_far'], ax=ax0, label='monetary_so_far')
    sns.violinplot(df_predictions['monetary_predicted'], ax=ax1, label='monetary_predicted')
    sns.violinplot(df_predictions['monetary_future'], ax=ax2, label='monetary_future')
    

    다음과 비슷한 결과가 표시됩니다.

    예측 데이터 분포의 시각화

    금전적 분포 분석은 전체 과거 값과 비교되는 다음 달의 금전적 가치를 보여줍니다. 한 가지 이유는 LENGTH_FUTURE 매개변수에 지정된 대로 다음 달의 가치를 예측하도록 모델이 학습되었다는 것입니다. 이 값을 변경하여 다음 분기에 대한 학습 및 예측을 실험해보고(LENGTH_FUTURE = 90), 분포가 어떻게 달라지는지 확인할 수 있습니다.

유사 잠재고객 만들기

이 섹션의 절차에 따라 높은 CLV의 고객 목록을 만들어서 내보내고 이 목록을 사용하여 Google Ads에서 유사 잠재고객을 만듭니다.

CLV별 상위 고객 식별 이후 섹션의 코드 예시는 작동 중인 Google Ads 환경에 대해 액세스 권한이 있는 경우에만 실행할 수 있습니다. 고유 Google Ads 환경에서 이 예시 코드를 실행할 수 있도록 Google Ads 통합 요구사항을 확인하세요.

CLV별 상위 고객 식별

유사 잠재고객을 만드는 첫 번째 단계로 예측한 CLV를 기준으로 상위 고객을 식별한 후 이러한 고객과 이메일 주소를 연결해야 합니다. 이를 위해서는 고객 ID를 사용하여 예측 테이블을 이 정보가 포함된 고객 데이터 테이블과 조인합니다.

이 가이드에서는 CLV를 기준으로 상위 20% 고객을 사용합니다. TOP_CLV_RATIO 매개변수를 수정하여 선택한 고객 비율을 변경할 수 있습니다. 고객을 선택하는 SQL 문은 PERCENT_RANK 함수를 사용하여 고객을 식별합니다. 이 함수는 예측된 미래 지출에 따라 TOP_CLV_RATIO 값으로 식별된 비율 또는 그 위에 고객을 배치합니다.

  1. 다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 TOP_CLV_RATIO 매개변수를 설정합니다.

    CLV_PARAMS = {
        'TOP_CLV_RATIO': 0.2
    }
    
  2. 다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 df_top_ltv 데이터 프레임을 만들고 채웁니다.

    %%bigquery df_top_ltv --params $CLV_PARAMS --project $PROJECT_ID
    
    DECLARE TOP_CLV_RATIO FLOAT64 DEFAULT @TOP_CLV_RATIO;
    
    SELECT
      p.customer_id,
      monetary_future,
      c.email AS email
    FROM (
      SELECT
        customer_id,
        monetary_future,
        PERCENT_RANK() OVER (ORDER BY monetary_future DESC) AS percent_rank_monetary
      FROM
        `clv.predictions` ) p
    INNER JOIN (
      SELECT
        customer_id,
        email
      FROM
        `clv.customers` ) c
    ON
      p.customer_id = c.customer_id
    WHERE
      -- Decides the size of your list of emails. For similar-audience use cases
      -- where you need to find a minimum of matching emails, 20% should provide
      -- enough potential emails.
      percent_rank_monetary <= TOP_CLV_RATIO
    ORDER BY monetary_future DESC
    
  3. 다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 df_top_ltv 데이터의 샘플을 확인합니다.

    df_top_ltv.head(5)
    

    다음과 비슷한 결과가 표시됩니다.

    CLV 데이터별 상위 고객의 처음 5개 행

Google Ads 구성 파일 만들기

Google Ads 클라이언트에 대해 구성 YAML 파일을 만듭니다.

  1. 아래의 자리표시자 변수를 해당 환경에 적절한 값으로 바꿔서 Google Ads API에 대해 액세스를 제어하는 YAML 파일 변수를 설정합니다. 필요한 토큰 및 OAuth 사용자 인증 정보가 아직 없을 때 이를 가져오는 방법은 Google Ads 통합 요구사항을 참조하세요.

    다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행합니다.

    DEVELOPER_TOKEN = "myDeveloperToken"
    OAUTH_2_CLIENT_ID = "myClientId"
    CLIENT_SECRET = "myClientSecret"
    REFRESH_TOKEN = "myRefreshToken"
    
  2. 다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 YAML 파일 콘텐츠를 만듭니다.

    ADWORDS_FILE = "/tmp/adwords.yaml"
    
    adwords_content = f"""
    # AdWordsClient configurations
    adwords:
      #############################################################################
      # Required Fields                                                           #
      #############################################################################
      developer_token: {DEVELOPER_TOKEN}
      #############################################################################
      # Optional Fields                                                           #
      #############################################################################
      # client_customer_id: INSERT_CLIENT_CUSTOMER_ID_HERE
      # user_agent: INSERT_USER_AGENT_HERE
      # partial_failure: True
      # validate_only: True
      #############################################################################
      # OAuth2 Configuration                                                      #
      # Below you may provide credentials for either the installed application or #
      # service account flows. Remove or comment the lines for the flow you're    #
      # not using.                                                                #
      #############################################################################
      # The following values configure the client for the installed application
      # flow.
      client_id: {OAUTH_2_CLIENT_ID}
      client_secret: {CLIENT_SECRET}
      refresh_token: {REFRESH_TOKEN}
      # The following values configure the client for the service account flow.
      # path_to_private_key_file: INSERT_PATH_TO_JSON_KEY_FILE_HERE
      # delegated_account: INSERT_DOMAIN_WIDE_DELEGATION_ACCOUNT
      #############################################################################
      # ReportDownloader Headers                                                  #
      # Below you may specify boolean values for optional headers that will be    #
      # applied to all requests made by the ReportDownloader utility by default.  #
      #############################################################################
        # report_downloader_headers:
        # skip_report_header: False
        # skip_column_header: False
        # skip_report_summary: False
        # use_raw_enum_values: False
    
    # AdManagerClient configurations
    ad_manager:
      #############################################################################
      # Required Fields                                                           #
      #############################################################################
      application_name: INSERT_APPLICATION_NAME_HERE
      #############################################################################
      # Optional Fields                                                           #
      #############################################################################
      # The network_code is required for all services except NetworkService:
      # network_code: INSERT_NETWORK_CODE_HERE
      # delegated_account: INSERT_DOMAIN_WIDE_DELEGATION_ACCOUNT
      #############################################################################
      # OAuth2 Configuration                                                      #
      # Below you may provide credentials for either the installed application or #
      # service account (recommended) flows. Remove or comment the lines for the  #
      # flow you're not using.                                                    #
      #############################################################################
      # The following values configure the client for the service account flow.
      path_to_private_key_file: INSERT_PATH_TO_JSON_KEY_FILE_HERE
      # delegated_account: INSERT_DOMAIN_WIDE_DELEGATION_ACCOUNT
      # The following values configure the client for the installed application
      # flow.
      # client_id: INSERT_OAUTH_2_CLIENT_ID_HERE
      # client_secret: INSERT_CLIENT_SECRET_HERE
      # refresh_token: INSERT_REFRESH_TOKEN_HERE
    
    # Common configurations:
    ###############################################################################
    # Compression (optional)                                                      #
    # Below you may specify whether to accept and automatically decompress gzip   #
    # encoded SOAP requests. By default, gzip compression is not enabled.         #
    ###############################################################################
    # enable_compression: False
    ###############################################################################
    # Logging configuration (optional)                                            #
    # Below you may specify the logging configuration. This will be provided as   #
    # an input to logging.config.dictConfig.                                      #
    ###############################################################################
    # logging:
      # version: 1
      # disable_existing_loggers: False
      # formatters:
        # default_fmt:
          # format: ext://googleads.util.LOGGER_FORMAT
      # handlers:
        # default_handler:
          # class: logging.StreamHandler
          # formatter: default_fmt
          # level: INFO
      # loggers:
        # Configure root logger
        # "":
          # handlers: [default_handler]
          # level: INFO
    ###############################################################################
    # Proxy configurations (optional)                                             #
    # Below you may specify an HTTP or HTTPS Proxy to be used when making API     #
    # requests. Note: You must specify the scheme used for the proxy endpoint.    #
    #                                                                             #
    # For additional information on configuring these values, see:                #
    # http://docs.python-requests.org/en/master/user/advanced/#proxies            #
    ###############################################################################
    # proxy_config:
      # http: INSERT_HTTP_PROXY_URI_HERE
      # https: INSERT_HTTPS_PROXY_URI_HERE
      # If specified, the given cafile will only be used if certificate validation
      # is not disabled.
      # cafile: INSERT_PATH_HERE
      # disable_certificate_validation: False
    ################################################################################
    # Utilities Included (optional)                                                #
    # Below you may specify whether the library will include utilities used in the #
    # user agent. By default, the library will include utilities used in the user  #
    # agent.                                                                       #
    ################################################################################
    # include_utilities_in_user_agent: True
    ################################################################################
    # Custom HTTP headers (optional)                                               #
    # Specify one or more custom headers to pass along with all requests to        #
    # the API.                                                                     #
    ################################################################################
    # custom_http_headers:
    #   X-My-Header: 'content'
    """
    
  3. 다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 YAML 파일을 채웁니다.

    with open(ADWORDS_FILE, "w") as adwords_file:
        print(adwords_content, file=adwords_file)
    

Google Ads 리마케팅 목록 만들기

최상위 CLV 고객의 이메일을 사용해서 Google Ads 리마케팅 목록을 만듭니다.

  1. 다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 최상위 CLV 고객의 이메일이 포함된 목록을 만듭니다.

    ltv_emails = list(set(df_top_ltv['email']))
    
  2. 다음 코드를 메모장의 다음 빈 셀에 복사한 후 이를 실행하여 리마케팅 목록을 만듭니다.

    """Adds a user list and populates it with hashed email addresses.
    
    Note: It may take several hours for the list to be populated with members. Email
    addresses must be associated with a Google account. For privacy purposes, the
    user list size will show as zero until the list has at least 1000 members. After
    that, the size will be rounded to the two most significant digits.
    """
    
    import hashlib
    import uuid
    
    # Import appropriate modules from the client library.
    from googleads import adwords
    
    def main(client):
      # Initialize appropriate services.
      user_list_service = client.GetService('AdwordsUserListService', 'v201809')
    
      user_list = {
          'xsi_type': 'CrmBasedUserList',
          'name': 'Customer relationship management list #%d' % uuid.uuid4(),
          'description': 'A list of customers that originated from email addresses',
          # CRM-based user lists can use a membershipLifeSpan of 10000 to indicate
          # unlimited; otherwise normal values apply.
          'membershipLifeSpan': 30,
          'uploadKeyType': 'CONTACT_INFO'
      }
    
      # Create an operation to add the user list.
      operations = [{
          'operator': 'ADD',
          'operand': user_list
      }]
    
      result = user_list_service.mutate(operations)
      user_list_id = result['value'][0]['id']
    
      emails = ['customer1@example.com', 'customer2@example.com',
                ' Customer3@example.com ']
      members = [{'hashedEmail': NormalizeAndSHA256(email)} for email in emails]
    
      # Add address info.
      members.append({
          'addressInfo': {
              # First and last name must be normalized and hashed.
              'hashedFirstName': NormalizeAndSHA256('John'),
              'hashedLastName': NormalizeAndSHA256('Doe'),
              # Country code and zip code are sent in plaintext.
              'countryCode': 'US',
              'zipCode': '10001'
          }
      })
    
      mutate_members_operation = {
          'operand': {
              'userListId': user_list_id,
              'membersList': members
          },
          'operator': 'ADD'
      }
    
      response = user_list_service.mutateMembers([mutate_members_operation])
    
      if 'userLists' in response:
        for user_list in response['userLists']:
          print('User list with name "%s" and ID "%d" was added.'
                % (user_list['name'], user_list['id']))
    
    def NormalizeAndSHA256(s):
      """Normalizes (lowercase, remove whitespace) and hashes a string with SHA-256.
    
      Args:
        s: The string to perform this operation on.
    
      Returns:
        A normalized and SHA-256 hashed string.
      """
      return hashlib.sha256(s.strip().lower()).hexdigest()
    
    if __name__ == '__main__':
      # Initialize the client object with the config
      # file you created in the previous section.
      adwords_client = adwords.AdWordsClient.LoadFromStorage(ADWORDS_FILE)
      main(adwords_client)
    

유사 잠재고객 추가

리마케팅 목록이 있으면 Google Ads 문서의 안내에 따라 대상에 유사 잠재고객을 추가합니다.

다음 단계(선택 사항)

다음 섹션의 정보에 따라 선택적으로 모델 성능을 향상시키고 ML 워크플로를 자동화합니다.

모델 향상

이 가이드에서는 고객의 미래 금전적 가치를 예측하기 위해 기본 모델을 만들기 위해 사용할 수 있는 한 가지 가능한 방법을 보여주었습니다. 이 방법을 더 세밀하게 조사해보고 싶으면 다음 제안에 따라 모델을 실험하거나 향상시킬 수 있습니다.

  • 데이터에 이상점이 많으면 데이터 엔지니어링을 추가로 구생하거나 추가적인 학습 데이터를 찾아보세요.
  • 기간 경계를 조정하거나 대상 트랜잭션에 대해 입력 비율을 변경하여 여러 가지 특성 만들기 방법을 시도해보세요.
  • 모델을 비교할 때는 모델 성능을 확실히 비교하기 위해 동일한 테스트 데이터 집합을 사용하는 것이 좋습니다. 예를 들어 이 가이드에서는 다음 30일 동안의 주문 예측을 위해 데이터를 준비합니다. 모델로 다음 분기에 대한 예측을 수행하려면 LENGTH_FUTURE 매개변수를 업데이트하고 특성을 다시 계산해야 합니다.
  • 예시 데이터 세트에는 제한된 개수의 필드가 사용됩니다. 고유 데이터에 제품 카테고리, 지리적 리전, 인구통계 정보와 같은 다른 측정기준이 포함된 경우, 해당 모델에 대해 추가적인 특성을 만들어보세요.

ML 워크플로 자동화

이전 단계에서는 BigQuery 및 BigQuery ML을 사용하여 머신러닝에 맞게 데이터를 준비하고, 모델을 생성 및 학습시키고, 예측을 얻고, Google Ads 통합을 위해 데이터를 준비하는 방법을 배웠습니다.

프로덕션 사용 사례에서는 이 모든 것이 반복적으로 수행되어야 할 것입니다. 이 단계를 매번 수동으로 실행할 수도 있지만, 프로세스를 자동화하는 것이 좋습니다. 이 가이드에는 이러한 단계를 자동화하기 위한 BigQuery 저장 프로시저 집합을 제공하는 GitHub 컴패니언 코드와 이를 실행하는 데 사용할 수 있는 셸 스크립트 run.sh가 포함되어 있습니다.

사용자 환경에서 작동하도록 구성하기 위해 run.sh 스크립트를 호출할 때 다음 매개변수를 사용할 수 있습니다.

변수 설명 기본
PROJECT_ID 프로젝트 ID 필수
DATASET_ID 데이터 세트 ID 필수
TRAIN_MODEL_ID 학습된 모델의 이름입니다. 모델을 학습시키지 않으려면 *null*로 설정합니다. 시간 기반의 문자열
USE_MODEL_ID 예측에 사용할 모델의 이름입니다. 데이터 세트를 포함해야 함: [DATASET].[MODEL] 시간 기반의 문자열
WINDOW_LENGTH 입력 트랜잭션의 기간(일 수)입니다. 0
WINDOW_STEP 두 기간 간의 일 수입니다. 두 임곗값 날짜 사이의 시간과 같습니다. 30
WINDOW_STEP_INITIAL 첫 번째 임곗값 날짜를 설정하기 전의 초기 시간(일 수)입니다. 90
LENGTH_FUTURE 예측을 수행할 기간(일 수)입니다. 30
MAX_STDV_MONETARY 스크립트가 트랜잭션을 삭제하는 고객별 금전적 가치에 대한 표준 편차의 상한값입니다. 500
MAX_STDV_QTY 스크립트가 트랜잭션을 삭제하는 고객별 수량 값에 대한 표준 편차의 상한값입니다. 100
TOP_LTV_RATIO 추출할 상위 고객의 비율입니다. 0.2

자동화를 위해 run.sh 스크립트를 사용하려면 다음 단계를 따르세요.

  1. GitHub 저장소를 클론합니다.

    git clone https://github.com/GoogleCloudPlatform/analytics-componentized-patterns.git
    
  2. run.sh 스크립트를 업데이트하여 해당 환경과 일치하도록 매개변수 값을 설정합니다.

  3. 자체 트랜잭션 데이터를 사용하는 경우 10_procedure_match.sql을 업데이트하여 트랜잭션 테이블에서 적합한 열을 지정합니다.

  4. 실행할 수 있도록 run.sh 스크립트에 대한 권한을 조정합니다.

    chmod +x run.sh
    
  5. 매개변수 설정 방법에 대한 자세한 내용은 명령줄 도움말을 참조하세요.

    ./run.sh --help
    
  6. 스크립트를 실행합니다.

    ./run.sh --project-id [YOUR_PROJECT_ID] --dataset-id [YOUR_DATASET_ID]
    

프로덕션 사용 사례에서는 쉬운 사용을 위해 데이터 엔지니어 및 DevOps팀에 연락하여 저장 프로시저를 자신의 도구에 통합할 수 있는지 확인할 수 있습니다.

정리

이 가이드에서 사용한 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 리소스가 포함된 프로젝트를 삭제하거나 프로젝트만 유지하고 해당 리소스를 삭제합니다.

어느 쪽이든 향후 리소스 비용이 청구되지 않도록 이러한 리소스를 삭제해야 합니다. 다음 섹션에서는 이러한 리소스를 삭제하는 방법을 설명합니다.

프로젝트 삭제

청구되지 않도록 하는 가장 쉬운 방법은 가이드에서 만든 프로젝트를 삭제하는 것입니다.

  1. Cloud Console에서 리소스 관리 페이지로 이동합니다.

    리소스 관리로 이동

  2. 프로젝트 목록에서 삭제할 프로젝트를 선택하고 삭제를 클릭합니다.
  3. 대화상자에서 프로젝트 ID를 입력한 후 종료를 클릭하여 프로젝트를 삭제합니다.

구성요소 삭제

프로젝트를 삭제하지 않으려면 다음 섹션을 사용하여 이 가이드의 청구 가능 구성요소를 삭제합니다.

BigQuery 데이터 세트 및 테이블 삭제

  1. BigQuery 콘솔을 엽니다.
  2. 리소스 섹션에서 이 가이드를 완료한 프로젝트를 확장하고 clv 데이터 세트를 선택합니다.
  3. 데이터 세트 창의 헤더에서 데이터 세트 삭제를 클릭합니다.
  4. 오버레이 창이 나타나면 clv을 입력한 다음 삭제를 클릭합니다.

AI Platform 노트북 삭제

  1. AI Platform Notebooks 페이지 열기
  2. clv 메모장 인스턴스의 체크박스를 선택합니다.
  3. 삭제를 클릭합니다.
  4. 오버레이 창이 나타나면 삭제를 클릭합니다.

다음 단계