有关预测功能的基础知识

简介

本指南阐明了 ForecastService,并简要说明了如何使用两种不同类型的预测:广告资源预测和投放预测。

在开始使用 ForecastService 之前,请务必对 DFP 广告管理系统(以下简称 DFP)中的预测功能进行充分了解。

广告资源预测

广告资源预测会报告可供订单项预订的可用单元最大数量。这种预测类似于界面中的检查广告资源功能。

预测范围包括可用的单元数量、匹配的单元数量、可能的单元数量、已投放的单元数量和预订的单元数量。它可能也会涵盖所有竞争订单项,以及每项细分定位条件的可用单元数量,具体取决于 AvailabilityForecastOptions 中设置的选项。默认情况下,这种预测未涵盖这两个方面。

细分定位条件的预测范围包括每项定位条件的匹配单元数量和可用单元数量。这些细分条目是根据订单项定位条件自动生成的。例如,定位到广告单元 ID 123456 的订单项会包括与下面类似的细分定位条件:

<targetingCriteriaBreakdowns>
  <targetingDimension>AD_UNIT</targetingDimension>
  <targetingCriteriaId>123456</targetingCriteriaId>
  <targetingCriteriaName>My Ad Unit Name</targetingCriteriaName>
   <excluded>false</excluded>
   <availableUnits>1000</availableUnits>
   <matchedUnits>2300</matchedUnits>
</targetingCriteriaBreakdowns>

您可以针对现有订单项或预测性订单项运行广告资源预测。

现有订单项

您可以使用现有订单项的 ID 针对这类订单项运行广告资源预测。

Java


  // Get the ForecastService.
  ForecastServiceInterface forecastService =
      dfpServices.get(session, ForecastServiceInterface.class);

  // Get forecast for line item.
  AvailabilityForecastOptions options = new AvailabilityForecastOptions();
  options.setIncludeContendingLineItems(true);
  options.setIncludeTargetingCriteriaBreakdown(true);
  AvailabilityForecast forecast =
      forecastService.getAvailabilityForecastById(lineItemId, options);

  long matched = forecast.getMatchedUnits();
  double availablePercent = (forecast.getAvailableUnits() / (matched * 1.0)) * 100;
  String unitType = forecast.getUnitType().toString().toLowerCase();

  System.out.printf("%d %s matched.%n", matched, unitType);
  System.out.printf("%.2f%% %s available.%n", availablePercent, unitType);

  if (forecast.getPossibleUnits() != null) {
    double possiblePercent = (forecast.getPossibleUnits() / (matched * 1.0)) * 100;
    System.out.printf("%.2f%% %s possible.%n", possiblePercent, unitType);
  }

  System.out.printf("%d contending line items.%n",
      forecast.getContendingLineItems() == null ? 0 : forecast.getContendingLineItems().length);
    

Python


  # Initialize appropriate service.
  forecast_service = client.GetService('ForecastService', version='v201805')

  # Set forecasting options.
  forecast_options = {
      'includeContendingLineItems': True,
      'includeTargetingCriteriaBreakdown': True,
  }

  # Get forecast for line item.
  forecast = forecast_service.getAvailabilityForecastById(
      line_item_id, forecast_options)
  matched = long(forecast['matchedUnits'])
  available_units = long(forecast['availableUnits'])

  if matched > 0:
    available_percent = (float(available_units) / matched) * 100.
  else:
    available_percent = 0

  contending_line_items = getattr(forecast, 'contentingLineItems', [])

  # Display results.
  print '%s %s matched.' % (matched, forecast['unitType'].lower())
  print '%s%% %s available.' % (available_percent, forecast['unitType'].lower())
  print '%d contending line items.' % len(contending_line_items)

  if 'possibleUnits' in forecast and matched:
    possible_percent = (long(forecast['possibleUnits'])/float(matched)) * 100.
    print '%s%% %s possible' % (possible_percent, forecast['unitType'].lower())
    

PHP


      $forecastService = $serviceFactory->createForecastService($session);

      // Get forecast for line item.
      $options = new AvailabilityForecastOptions();
      $options->setIncludeContendingLineItems(true);
      $options->setIncludeTargetingCriteriaBreakdown(true);
      $forecast = $forecastService->getAvailabilityForecastById(
          $lineItemId,
          $options
      );

      // Print out forecast results.
      $matchedUnits = $forecast->getMatchedUnits();
      $unitType = strtolower($forecast->getUnitType());
      printf("%d %s matched.\n", $matchedUnits, $unitType);

      if ($matchedUnits > 0) {
          $percentAvailableUnits = $forecast->getAvailableUnits() / $matchedUnits * 100;
          $percentPossibleUnits = $forecast->getPossibleUnits() / $matchedUnits * 100;
          printf("%.2d%% %s available.\n", $percentAvailableUnits, $unitType);
          printf("%.2d%% %s possible.\n", $percentPossibleUnits, $unitType);
      }

      printf(
          "%d contending line items.\n",
          count($forecast->getContendingLineItems())
      );
    

C#


  using (ForecastService forecastService =
      (ForecastService) user.GetService(DfpService.v201805.ForecastService)) {
    // Get forecast for line item.
    AvailabilityForecastOptions options = new AvailabilityForecastOptions();
    options.includeContendingLineItems = true;
    options.includeTargetingCriteriaBreakdown = true;
    AvailabilityForecast forecast =
        forecastService.getAvailabilityForecastById(lineItemId, options);

    // Display results.
    long matched = forecast.matchedUnits;
    double availablePercent = (double) (forecast.availableUnits / (matched * 1.0)) * 100;
    String unitType = forecast.unitType.ToString().ToLower();

    Console.WriteLine("{0} {1} matched.\n{2} % {3} available.", matched, unitType,
        availablePercent, unitType);
    if (forecast.possibleUnitsSpecified) {
      double possiblePercent = (double) (forecast.possibleUnits / (matched * 1.0)) * 100;
      Console.WriteLine(possiblePercent + "% " + unitType + " possible.\n");
    }
    Console.WriteLine("{0} contending line items.", (forecast.contendingLineItems != null) ?
        forecast.contendingLineItems.Length : 0);
    

Ruby


  # Get the ForecastService.
  forecast_service = dfp.service(:ForecastService, API_VERSION)
  # Set forecasting options.
  forecast_options = {
    :include_contending_line_items => True,
    :include_targeting_criteria_breakdown => True,
  }

  # Get forecast for the line item.
  forecast = forecast_service.get_availability_forecast_by_id(
      line_item_id, forecast_options
  )

  unless forecast.nil?
    # Display results.
    matched = forecast[:matched_units]
    available_percent = forecast[:available_units] * 100.0 / matched
    unit_type = forecast[:unit_type].to_s.downcase
    puts '%.2f %s matched.' % [matched, unit_type]
    puts '%.2f%% of %s available.' % [available_percent, unit_type]
    puts '%d contending line items.' % forecast[:contending_line_items].size
    unless forecast[:possible_units].nil?
      possible_percent = forecast[:possible_units] * 100.0 / matched
      puts '%.2f%% of %s possible.' % [possible_percent, unit_type]
    end
  end
    

此示例的输出结果与以下结果类似:

100 clicks matched.
2 contending line items.

预测性订单项

或者,您可以创建一个预测性订单项,然后进行预测,而无需保存该订单项。为此,请创建一个本地订单项,然后在 ProspectiveLineItem 上对其进行设置。如果您设置了广告客户 ID,则这种预测还会将统一屏蔽规则考虑在内。

Java


  // Get forecast for prospective line item.
  ProspectiveLineItem prospectiveLineItem = new ProspectiveLineItem();
  prospectiveLineItem.setAdvertiserId(advertiserId);
  prospectiveLineItem.setLineItem(lineItem);
  AvailabilityForecastOptions options  = new AvailabilityForecastOptions();
  options.setIncludeContendingLineItems(true);
  options.setIncludeTargetingCriteriaBreakdown(true);

  AvailabilityForecast forecast =
      forecastService.getAvailabilityForecast(prospectiveLineItem, options);
    

Python


  prospective_line_item = {
      'lineItem': line_item,
      'advertiserId': advertiser_id
  }

  # Set forecasting options.
  forecast_options = {
      'includeContendingLineItems': True,
      'includeTargetingCriteriaBreakdown': True,
  }

  # Get forecast.
  forecast = forecast_service.getAvailabilityForecast(
      prospective_line_item, forecast_options)
    

PHP


      // Get forecast for prospective line item.
      $prospectiveLineItem = new ProspectiveLineItem();
      $prospectiveLineItem->setAdvertiserId($advertiserId);
      $prospectiveLineItem->setLineItem($lineItem);
      $options = new AvailabilityForecastOptions();
      $options->setIncludeContendingLineItems(true);
      $options->setIncludeTargetingCriteriaBreakdown(true);

      $forecast = $forecastService->getAvailabilityForecast(
          $prospectiveLineItem,
          $options
      );
    

C#


    // Get availability forecast.
    AvailabilityForecastOptions options = new AvailabilityForecastOptions();
    options.includeContendingLineItems = true;
    options.includeTargetingCriteriaBreakdown = true;
    ProspectiveLineItem prospectiveLineItem = new ProspectiveLineItem();
    prospectiveLineItem.advertiserId = advertiserId;
    prospectiveLineItem.lineItem = lineItem;
    AvailabilityForecast forecast =
        forecastService.getAvailabilityForecast(prospectiveLineItem, options);
    

Ruby


  prospective_line_item = {
    :advertiser_id => advertiser_id,
    :line_item => line_item
  }

  # Set forecasting options.
  forecast_options = {
    :include_contending_line_items => true,
    :include_targeting_criteria_breakdown => true,
  }

  # Get forecast for the line item.
  forecast = forecast_service.get_availability_forecast(
      prospective_line_item, forecast_options)
    

投放预测

如果您想模拟多个竞争订单项的投放,可以通过 DeliveryForecast 实现此目的。这种预测类似于界面中的销售管理预测

现有订单项

您可以使用现有订单项的 ID 针对这类订单项运行投放预测。

Java


  // Get the ForecastService.
  ForecastServiceInterface forecastService =
      dfpServices.get(session, ForecastServiceInterface.class);

  DeliveryForecastOptions options = new DeliveryForecastOptions();

  DeliveryForecast forecast = forecastService.getDeliveryForecastByIds(
      Longs.toArray(lineItemIds), options);

  for (LineItemDeliveryForecast lineItemForecast : forecast.getLineItemDeliveryForecasts()) {
    String unitType = lineItemForecast.getUnitType().toString().toLowerCase();
    System.out.printf("Forecast for line item %d:%n", lineItemForecast.getLineItemId());
    System.out.printf("\t%d %s matched%n", lineItemForecast.getMatchedUnits(), unitType);
    System.out.printf("\t%d %s delivered%n", lineItemForecast.getDeliveredUnits(), unitType);
    System.out.printf("\t%d %s predicted%n",
        lineItemForecast.getPredictedDeliveryUnits(), unitType);
  }
    

Python


  # Initialize appropriate service.
  forecast_service = client.GetService('ForecastService', version='v201805')

  # Get forecast for line item.
  forecast = forecast_service.getDeliveryForecastByIds(
      [line_item_id1, line_item_id2], None)

  for single_forecast in forecast['lineItemDeliveryForecasts']:
    unit_type = single_forecast['unitType']
    print ('Forecast for line item %d:\n\t%d %s matched\n\t%d %s delivered\n\t'
           '%d %s predicted\n' % (
               single_forecast['lineItemId'], single_forecast['matchedUnits'],
               unit_type, single_forecast['deliveredUnits'], unit_type,
               single_forecast['predictedDeliveryUnits'], unit_type))

if __name__ == '__main__':
  # Initialize client object.
  dfp_client = dfp.DfpClient.LoadFromStorage()
  main(dfp_client, LINE_ITEM_ID_1, LINE_ITEM_ID_2)

    

PHP


      $forecastService = $serviceFactory->createForecastService($session);

      // Get forecast for the line items with no options set.
      $forecast = $forecastService->getDeliveryForecastByIds(
          [$lineItemId1, $lineItemId2],
          new DeliveryForecastOptions()
      );

      // Print out forecast results.
      foreach ($forecast->getLineItemDeliveryForecasts() as $lineItemForecast) {
          $unitType = strtolower($lineItemForecast->getUnitType());
          printf(
              "Forecast for line item ID %d:\n",
              $lineItemForecast->getLineItemId()
          );
          printf(
              "    %d %s matched\n",
              $lineItemForecast->getMatchedUnits(),
              $unitType
          );
          printf(
              "    %d %s delivered\n",
              $lineItemForecast->getDeliveredUnits(),
              $unitType
          );
          printf(
              "    %d %s predicted\n",
              $lineItemForecast->getPredictedDeliveryUnits(),
              $unitType
          );
      }
    

C#


  using (ForecastService forecastService =
      (ForecastService) user.GetService(DfpService.v201805.ForecastService)) {
    // Get a delivery forecast for the line items.
    DeliveryForecastOptions options = new DeliveryForecastOptions();
    options.ignoredLineItemIds = new long[] { };
    DeliveryForecast forecast = forecastService.getDeliveryForecastByIds(
        new long[] { lineItemId1, lineItemId2 }, options);

    // Display results.
    foreach (LineItemDeliveryForecast lineItemForecast in
        forecast.lineItemDeliveryForecasts) {
      String unitType = lineItemForecast.unitType.GetType().Name.ToLower();
      Console.WriteLine("Forecast for line item {0}:", lineItemForecast.lineItemId);
      Console.WriteLine("\t{0} {1} matched", lineItemForecast.matchedUnits, unitType);
      Console.WriteLine("\t{0} {1} delivered", lineItemForecast.deliveredUnits, unitType);
      Console.WriteLine("\t{0} {1} predicted", lineItemForecast.predictedDeliveryUnits,
          unitType);
    }
    

Ruby


  # Get the ForecastService.
  forecast_service = dfp.service(:ForecastService, API_VERSION)
  # Get forecast for the line item.
  forecast = forecast_service.get_delivery_forecast_by_ids(
      [line_item_id1, line_item_id2], nil)

  unless forecast.nil? || forecast[:line_item_delivery_forecasts].nil?
    forecast[:line_item_delivery_forecasts].each do |single_forecast|
      # Display results.
      unit_type = single_forecast[:unit_type]
      puts ('Forecast for line item %d:\n\t%d %s matched\n\t%d %s ' +
          'delivered\n\t%d %s predicted\n') % [single_forecast[:line_item_id],
          single_forecast[:matched_units], unit_type,
          single_forecast[:delivered_units], unit_type,
          single_forecast[:predicted_delivery_units], unit_type]
    end
  end
    

此示例的输出结果与以下结果类似:

Forecast for line item 14678:
    100 clicks matched
    0 clicks delivered
    98 clicks predicted

如果您想从投放模拟范围中排除订单项,可以通过在 DeliveryForecastOptions 中设置相应 ID 来实现此目的。

预测性订单项

与广告资源预测类似,您可以针对不进行保存的订单项运行投放预测。为此,请在 ForecastService.getDeliveryForecast 方法中使用 ProspectiveLineItem 对象。

常见问题解答

我想预测很多订单项的广告资源可用情况。我能否在一个请求中运行多个预测?

不能。您必须针对每个订单项或预测性订单项发出单独的广告资源预测请求。

我运行了多个预测,现在出现了 EXCEEDED_QUOTA 错误。这是怎么回事?

预测需消耗大量计算资源,而配额系统会确保相应服务的可靠性。您可以安心地等待片刻,然后再次尝试运行引起配额错误的预测。

导致 NO_FORECAST_YET 或 NOT_ENOUGH_INVENTORY 错误的原因是什么?

预测的运行依据是广告联盟的流量历史记录。不过,有时可能没有足够的历史数据用来运行预测。要详细了解这些错误,请参阅 ForecastError 文档。

什么是 AlternativeUnitTypeForecast?

有时,了解哪些其他广告资源可供使用会非常有用。例如,当针对 CPC 订单项运行预测时,其他单元类型的预测将会涵盖与展示次数相关的信息。

对于 DFP 预测,我还有其他一般性问题。

不妨看看产品常见问题解答中是否涵盖了这些问题;如果没有,请在我们的开发者论坛中提问。