실험 보고서

실험에 대한 보고서를 생성하는 방법은 크게 두 가지입니다.

  • 직접 실험 보고서: 측정항목에 대해 experiment 리소스를 쿼리합니다. 이 옵션은 광고효과 및 p값과 같은 통계 비교 데이터와 함께 단일 응답으로 대조 부문과 실험 부문의 측정항목을 제공합니다. 캠페인 내 실험에 대한 보고서를 생성하는 유일한 방법입니다.
  • 캠페인 보고서: campaign 리소스 를 측정항목에 대해 쿼리하고 campaign.experiment_type를 사용하여 기본 캠페인과 실험 캠페인을 구분합니다. 이 옵션은 시스템 관리 실험과 같이 별도의 대조 캠페인과 실험 캠페인을 사용하는 실험에만 사용할 수 있습니다.

이 가이드에서는 보고서를 지원하는 모든 실험 유형과 호환되는 직접 실험 보고서에 중점을 둡니다.

직접 실험 보고서

experiment 리소스를 직접 쿼리하여 대조 부문과 실험 부문 간의 실적 측정항목과 통계 비교를 가져올 수 있습니다.

측정항목 및 통계적 유의성

클릭수, 노출수, 비용, 전환수, 전환 가치와 같은 핵심 측정항목의 경우 experiment 리소스는 동일한 행에서 실험 측정항목 (예: metrics.clicks)과 대조 측정항목 (예: metrics.control_clicks)을 모두 제공합니다.

또한 부문 간의 차이의 통계적 유의성을 평가하는 데 도움이 되는 필드를 제공합니다.

  • metrics.*_p_value: 실험이 측정항목에 실제 영향을 미치지 않는 경우 관찰된 결과가 발생할 확률입니다. p값이 낮을수록 통계적 유의성이 높습니다.
  • metrics.*_point_estimate: 대조 부문에 비해 실험 부문의 지정된 측정항목에서 추정된 광고효과 (양수 또는 음수)의 백분율입니다. margin_of_error와 함께 추정되는 차이에 대해 규정된 신뢰 수준으로 신뢰 구간을 설명합니다. 추정되는 수량은 (실험 / 대조 - 1)입니다. 점 추정치는 신뢰 구간의 중심입니다.
  • metrics.*_margin_of_error: point_estimate를 중심으로 하는 신뢰 구간의 반지름입니다. 실험 유형에 따라 달라지는 규정된 신뢰 수준에 대해 계산됩니다.

다음과 같은 핵심 측정항목 필드는 실험 그룹 값, 대조 그룹 값, 이전에 나열된 통계 필드를 비롯하여 experiment 리소스에서 지원됩니다.

  • clicks
  • impressions
  • cost_micros
  • conversions
  • cost_per_conversion
  • conversion_value
  • conversion_value_per_cost

특히 전환의 경우 통계 필드는 상대적 값이 아닌 다음 absolute_change 필드를 통해 사용할 수 있습니다.

experiment 리소스에 대한 유효한 쿼리를 구성하는 데 도움이 필요하면 Google Ads 쿼리 빌더 도구를 사용하세요.

예시 검색어

다음 GAQL 쿼리는 실험의 주요 측정항목을 가져옵니다.

SELECT
  experiment.experiment_id,
  experiment.name,
  experiment.type,
  metrics.clicks,
  metrics.control_clicks,
  metrics.clicks_point_estimate,
  metrics.clicks_margin_of_error,
  metrics.clicks_p_value,
  metrics.conversions,
  metrics.control_conversions,
  metrics.conversions_absolute_change_point_estimate,
  metrics.conversions_absolute_change_margin_of_error,
  metrics.conversions_absolute_change_p_value
FROM experiment
WHERE experiment.experiment_id = EXPERIMENT_ID

결과 해석

p값, 점 추정치, 오차 범위 필드를 사용하여 실험에서 통계적으로 유의미한 결과가 나왔는지 확인할 수 있습니다. 예를 들어 conversions_absolute_change_p_value가 선택한 임곗값 (예: 95% 신뢰도의 경우 0.05)보다 낮고 conversions_absolute_change_point_estimate - conversions_absolute_change_margin_of_error가 0보다 크면 실험 부문의 전환수가 대조 부문보다 훨씬 더 높다는 의미입니다.

다음은 p값 및 광고효과 추정치를 기반으로 결과를 평가하는 방법을 보여주는 Python 스니펫입니다.

자바

private void evaluateExperiment(
    GoogleAdsClient googleAdsClient, long customerId, GoogleAdsRow row) {
  Metrics metrics = row.getMetrics();
  String experimentResourceName = row.getExperiment().getResourceName();

  // 1. Evaluate conversion success as a primary success signal if available.
  // - Point Estimate: Represents the estimated average lift or difference in conversions.
  // - Margin of Error: Outlines the confidence interval bounds. Note that the margin_of_error
  //   provided by the API is calculated for a preset confidence level which is set based on the
  //   experiment type.
  // - Lower Bound: (Point Estimate - Margin of Error). If this value is above 0,
  //   we have statistical significance that performance has improved.
  double convPValue = metrics.getConversionsAbsoluteChangePValue();
  double convLift = metrics.getConversionsAbsoluteChangePointEstimate();
  double convError = metrics.getConversionsAbsoluteChangeMarginOfError();
  double convLowerBound = convLift - convError;

  if (convPValue <= P_VALUE_THRESHOLD) {
    if (convLowerBound > 0) {
      System.out.printf(
          "Significant Success: Conversions increased. Even at the lower bound, the lift is %.2f."
              + " Promoting changes.%n",
          convLowerBound);
      promoteExperiment(googleAdsClient, customerId, experimentResourceName);
      return;
    } else if ((convLift + convError) < 0) {
      System.out.printf(
          "Significant Decline: Even the upper bound (%.2f) is below zero. Ending experiment.%n",
          convLift + convError);
      endExperiment(googleAdsClient, customerId, experimentResourceName);
      return;
    }
  }

  // 2. Fall back to evaluating click metrics if conversions are inconclusive.
  double clickPValue = metrics.getClicksPValue();
  double clickLift = metrics.getClicksPointEstimate();
  double clickError = metrics.getClicksMarginOfError();
  double clickLowerBound = clickLift - clickError;

  if (clickPValue <= P_VALUE_THRESHOLD && clickLowerBound > 0) {
    System.out.printf("Click volume is significantly up (+%.1f%%).%n", clickLift * 100);

    // Graduation is only supported for separate campaign experiments, not
    // intra-campaign experiments where there is no separate treatment campaign.
    ExperimentType experimentType = row.getExperiment().getType();
    if (experimentType != ExperimentType.ADOPT_BROAD_MATCH_KEYWORDS
        && experimentType != ExperimentType.ADOPT_AI_MAX) {
      System.out.println("Graduating treatment campaign for further manual analysis.");
      graduateExperiment(googleAdsClient, customerId, experimentResourceName);
    } else {
      System.out.println(
          "Intra-campaign trial detected: graduation is not supported. Continuing to run the"
              + " experiment to gather more conversion data.");
    }
  } else {
    // 3. Print status if no action was taken.
    System.out.printf(
        "Inconclusive: No significant lift in Conversions (p=%.2f) or Clicks (p=%.2f). Current"
            + " estimated lift: %.2f +/- %.2f. Allowing the experiment to continue running.%n",
        convPValue, clickPValue, convLift, convError);
  }
}

      

C#

private static void EvaluateExperiment(GoogleAdsClient client, long customerId, GoogleAdsRow row)
{
    // This function evaluates performance metrics and immediately takes action
    // to update the experiment's status (promote, end, or graduate) if
    // statistical significance thresholds are met.
    var metrics = row.Metrics;
    string experimentResourceName = row.Experiment.ResourceName;

    bool hasConvMetrics = metrics.HasConversionsAbsoluteChangePValue
        && metrics.HasConversionsAbsoluteChangePointEstimate
        && metrics.HasConversionsAbsoluteChangeMarginOfError;

    bool hasClickMetrics = metrics.HasClicksPValue
        && metrics.HasClicksPointEstimate
        && metrics.HasClicksMarginOfError;

    // 1. Evaluate conversion success as a primary success signal if available.
    // - Point Estimate: Represents the estimated average lift or difference in conversions.
    // - Margin of Error: Outlines the confidence interval bounds. Note that the margin_of_error
    //   provided by the API is calculated for a preset confidence level which is set based on
    //   the experiment type.
    // - Lower Bound: (Point Estimate - Margin of Error). If this value is above 0,
    //   we have statistical significance that performance has improved.
    if (hasConvMetrics)
    {
        double convPValue = metrics.ConversionsAbsoluteChangePValue;
        double convLift = metrics.ConversionsAbsoluteChangePointEstimate;
        double convError = metrics.ConversionsAbsoluteChangeMarginOfError;
        double convLowerBound = convLift - convError;

        if (convPValue <= P_VALUE_THRESHOLD)
        {
            if (convLowerBound > 0)
            {
                Console.WriteLine(
                    $"Significant Success: Conversions increased. Even at the lower" +
                    $" bound, the lift is {convLowerBound:F2}. Promoting changes.");
                PromoteExperiment(client, customerId, experimentResourceName);
                return;
            }
            else if ((convLift + convError) < 0)
            {
                Console.WriteLine(
                    $"Significant Decline: Even the upper bound ({convLift + convError:F2}) " +
                    $"is below zero. Ending experiment.");
                EndExperiment(client, customerId, experimentResourceName);
                return;
            }
        }
    }

    // 2. Evaluate click volume as a secondary signal.
    // This is helpful as an early indicator or for lower-volume accounts.
    if (hasClickMetrics)
    {
        double clickPValue = metrics.ClicksPValue;
        double clickLift = metrics.ClicksPointEstimate;
        double clickError = metrics.ClicksMarginOfError;
        double clickLowerBound = clickLift - clickError;

        if (clickPValue <= P_VALUE_THRESHOLD && clickLowerBound > 0)
        {
            // We have a directional winner: high confidence in more traffic,
            // but not enough data to confirm conversion impact yet.
            Console.WriteLine(
                $"Click volume is significantly up (+{clickLift * 100:F1}%).");

            // Graduation is only supported for separate campaign experiments, not
            // intra-campaign experiments where there is no separate treatment campaign.
            if (row.Experiment.Type != ExperimentType.AdoptBroadMatchKeywords
                && row.Experiment.Type != ExperimentType.AdoptAiMax)
            {
                Console.WriteLine("Graduating treatment campaign for further manual analysis.");
                GraduateExperiment(client, customerId, experimentResourceName);
            }
            else
            {
                Console.WriteLine(
                    "Intra-campaign trial detected: graduation is not supported. " +
                    "Continuing to run the experiment to gather more conversion data.");
            }
            return;
        }
    }

    // 3. Print status if no action was taken.
    if (hasConvMetrics || hasClickMetrics)
    {
        string convStatus = hasConvMetrics
            ? $"Conversions (p={metrics.ConversionsAbsoluteChangePValue:F2}, " +
              $"lift={metrics.ConversionsAbsoluteChangePointEstimate:F2} +/- " +
              $"{metrics.ConversionsAbsoluteChangeMarginOfError:F2})"
            : "Conversions (not populated)";

        string clickStatus = hasClickMetrics
            ? $"Clicks (p={metrics.ClicksPValue:F2}, " +
              $"lift={metrics.ClicksPointEstimate:F2} +/- " +
              $"{metrics.ClicksMarginOfError:F2})"
            : "Clicks (not populated)";

        Console.WriteLine(
            $"Inconclusive: No significant action taken. {convStatus}, {clickStatus}. " +
            "Allowing the experiment to continue running.");
    }
    else
    {
        Console.WriteLine(
            "Conversion and click performance metrics are not yet populated. " +
            "Allowing the experiment to continue running.");
    }
}
      

PHP

This example is not yet available in PHP; you can take a look at the other languages.
    

Python

def evaluate_experiment(
    client: GoogleAdsClient, customer_id: str, row: GoogleAdsRow
) -> None:
    """Evaluates the performance of the experiment and updates it accordingly
    (for example, promotes, ends, or graduates).

    Checks conversion and click metrics against statistical significance thresholds
    to determine the appropriate action to take on the experiment.

    Args:
        client: an initialized GoogleAdsClient instance.
        customer_id: a client customer ID.
        row: a GoogleAdsRow containing the experiment and metrics.
    """
    # This function evaluates performance metrics and immediately takes action
    # to update the experiment's status (promote, end, or graduate) if
    # statistical significance thresholds are met.
    metrics = row.metrics
    experiment_resource_name = row.experiment.resource_name

    has_conv_metrics = (
        "conversions_absolute_change_p_value" in metrics
        and "conversions_absolute_change_point_estimate" in metrics
        and "conversions_absolute_change_margin_of_error" in metrics
    )
    has_click_metrics = (
        "clicks_p_value" in metrics
        and "clicks_point_estimate" in metrics
        and "clicks_margin_of_error" in metrics
    )

    # 1. Evaluate conversion success as a primary success signal if available.
    # - Point Estimate: Represents the estimated average lift or difference in conversions.
    # - Margin of Error: Outlines the confidence interval bounds. Note that the margin_of_error provided by the API is calculated for a preset confidence level which is set based on the experiment type.
    # - Lower Bound: (Point Estimate - Margin of Error). If this value is above 0,
    #   we have statistical significance that performance has improved.
    if has_conv_metrics:
        conv_p_value = metrics.conversions_absolute_change_p_value
        conv_lift = metrics.conversions_absolute_change_point_estimate
        conv_error = metrics.conversions_absolute_change_margin_of_error
        conv_lower_bound = conv_lift - conv_error

        if conv_p_value <= P_VALUE_THRESHOLD:
            if conv_lower_bound > 0:
                print(
                    "Significant Success: Conversions increased. Even at the lower"
                    f" bound, the lift is {conv_lower_bound:.2f}. Promoting"
                    " changes."
                )
                promote_experiment(
                    client, customer_id, experiment_resource_name
                )
                return
            elif (conv_lift + conv_error) < 0:
                print(
                    "Significant Decline: Even the upper bound"
                    f" ({conv_lift + conv_error:.2f}) is below zero. Ending"
                    " experiment."
                )
                end_experiment(client, customer_id, experiment_resource_name)
                return

        # 2. Evaluate click volume as a secondary signal.
        # This is helpful as an early indicator or for lower-volume accounts.
        click_p_value = metrics.clicks_p_value
        click_lift = metrics.clicks_point_estimate
        click_error = metrics.clicks_margin_of_error
        click_lower_bound = click_lift - click_error

        if click_p_value <= P_VALUE_THRESHOLD and click_lower_bound > 0:
            # We have a directional winner: high confidence in more traffic,
            # but not enough data to confirm conversion impact yet.
            print(f"Click volume is significantly up (+{click_lift*100:.1f}%).")

            # Graduation is only supported for separate campaign experiments, not
            # intra-campaign experiments where there is no separate treatment campaign.
            experiment_type_name = row.experiment.type_.name
            if (
                experiment_type_name != "ADOPT_BROAD_MATCH_KEYWORDS"
                and experiment_type_name != "ADOPT_AI_MAX"
            ):
                print(
                    "Graduating treatment campaign for further manual analysis."
                )
                graduate_experiment(
                    client, customer_id, experiment_resource_name
                )
            else:
                print(
                    "Intra-campaign trial detected: graduation is not supported. "
                    "Continuing to run the experiment to gather more conversion data."
                )
            return

    # 3. Print status if no action was taken.
    if has_conv_metrics or has_click_metrics:
        conv_status = (
            f"Conversions (p={metrics.conversions_absolute_change_p_value:.2f}, "
            f"lift={metrics.conversions_absolute_change_point_estimate:.2f} +/- "
            f"{metrics.conversions_absolute_change_margin_of_error:.2f})"
            if has_conv_metrics
            else "Conversions (not populated)"
        )
        click_status = (
            f"Clicks (p={metrics.clicks_p_value:.2f}, "
            f"lift={metrics.clicks_point_estimate:.2f} +/- "
            f"{metrics.clicks_margin_of_error:.2f})"
            if has_click_metrics
            else "Clicks (not populated)"
        )
        print(
            f"Inconclusive: No significant action taken. {conv_status}, {click_status}."
            " Allowing the experiment to continue running."
        )
    else:
        print(
            "Conversion and click performance metrics are not yet populated. "
            "Allowing the experiment to continue running."
        )
      

Ruby

This example is not yet available in Ruby; you can take a look at the other languages.
    

Perl

This example is not yet available in Perl; you can take a look at the other languages.
    

curl

캠페인 보고서에 비해 이점

직접 실험 보고서는 캠페인 보고서를 별도로 쿼리하는 것보다 다음과 같은 여러 이점을 제공합니다.

  1. 중앙 집중식 측정항목: 단일 행에서 대조 및 실험의 측정항목을 가져옵니다.
  2. 통계적 신뢰도 데이터: 계산된 p값, 점 추정치, 오차 범위를 제공합니다.
  3. 효율성: 여러 보고서의 결과를 수동으로 조인하거나 비교할 필요가 없습니다.
  4. 캠페인 내 지원: 트래픽이 단일 캠페인 내에서 분할되는 캠페인 내 실험의 경우 대조와 실험을 비교하는 유일한 방법입니다.

캠페인 보고서

별도의 실험 캠페인 (예: SEARCH_CUSTOM)을 만드는 실험의 경우 campaign 리소스를 쿼리하고 campaign.experiment_type를 사용하여 BASE (대조) 및 EXPERIMENT (실험) 캠페인을 식별할 수 있습니다. 이 접근 방식은 측정항목을 더 세분화된 수준 (예: 광고그룹 또는 키워드)으로 분류하거나 experiment 리소스에서 사용할 수 없는 캠페인 메타데이터를 확인해야 하는 경우에 유용합니다. 하지만 실적 비교 및 통계 계산을 수동으로 수행해야 합니다.

트래픽 분할은 단일 캠페인 내에서 내부적으로 발생하므로 캠페인 수준 보고서를 사용하여 캠페인 내 실험의 부문을 비교할 수 없습니다. 캠페인 내 실험에 대해 campaign을 쿼리하면 집계된 총계만 반환됩니다.

권장사항

  • 적절한 신뢰 수준 선택: p값 임곗값을 낮게 설정하면 특히 예산 또는 전환수가 낮은 경우 방향성 안내를 더 빠르게 제공할 수 있습니다. 95% 신뢰도 (p값 <= 0.05)는 학문적 표준으로 간주되며 장기적으로 더 정확한 결과를 얻는 데 더 적합할 수 있습니다.
  • 실험을 충분히 오래 실행: 주간 실적 주기, 전환 지연, 학습 기간을 고려하여 실험을 4주 이상 실행합니다.
  • 실적 향상에 필요한 시간 제공: 자동 입찰을 사용하거나 새로운 기능을 테스트하는 캠페인의 경우 입찰 모델과 트래픽 수준이 분할에 맞게 재조정될 수 있도록 처음 1~2주간의 데이터는 무시합니다.
  • 50/50 분할 사용: 일반적으로 50/50 트래픽 분할이 통계적으로 유의미한 결과를 가장 빠르게 얻을 수 있는 방법입니다.
  • 미리 예약: 광고 검토 및 승인 프로세스에 필요한 시간을 제공하려면 실험 시작일을 3~7일 후로 설정합니다.
  • 캠페인당 한 번에 하나의 실험만 실행할 수 있습니다.