“实时设备端应用内购优化”Codelab

1. 概览

1cbf855eda62c306.png

欢迎参加“实时设备端应用内购优化”Codelab。在此 Codelab 中,您将学习如何使用 TensorFlow Lite 和 Firebase 训练自定义个性化模型并将其部署到您的应用中。

本教程介绍如何构建用于个性化的机器学习模型,特别是根据当前用户的状态预测最佳应用内购 (IAP) 优惠的模型。这是一个情境化多臂老虎机问题的示例,这类机器学习问题非常重要且应用广泛,您将在本 Codelab 中详细了解

学习内容

  • 通过 Firebase Analytics 收集分析数据
  • 使用 BigQuery 预处理分析数据
  • 训练一个简单的机器学习模型,用于在设备端优化应用内购 (IAP)
  • 将 TFLite 模型部署到 Firebase ML 并从应用中访问这些模型
  • 通过 Firebase A/B 测试衡量不同模型并进行实验
  • 以定期循环的方式使用最新数据训练和部署新模型

您需要满足的条件

  • Android Studio 3.4 及更高版本
  • 搭载 Android 2.3 及更高版本和 Google Play 服务 9.8 或更高版本的实体测试设备,或者搭载 Google Play 服务 9.8 或更高版本的模拟器
  • 如果使用实体测试设备,则需要连接线缆
  • 机器学习知识初学者

您打算如何使用本教程?

仅阅读教程内容 阅读并完成练习

您如何评价自己在构建 Android 应用方面的经验水平?

新手水平 中等水平 熟练水平

2. 问题陈述

假设您是一位游戏开发者,希望在每个关卡结束后显示个性化的应用内购 (IAP) 建议。您每次只能显示有限数量的 IAP 选项,并且不知道哪些选项的转化效果最好。鉴于每位用户和每个会话都各不相同,我们如何才能找到可带来最高预期奖励的 IAP 优惠?

3. 获取示例代码

从命令行克隆 GitHub 代码库

git clone https://github.com/googlecodelabs/firebase-iap-optimization.git

此代码库包含:

  1. 一个用于训练个性化模型并将其打包到 TFLite 模型中的 Jupyter 笔记本 (.ipynb)
  2. 一个使用 TFLite 模型在设备上进行预测的 Kotlin 示例应用

4. 通过 Firebase 运行应用

在此 Codelab 中,我们将优化虚构的游戏应用 Flappy Sparky 的 IAP。这是一款横向卷轴游戏,玩家在其中控制 Sparky 尝试在墙柱之间飞行,同时避免撞到墙柱。在关卡开始时,系统会向用户显示一项内购优惠,用户购买后可获得能量提升。在此 Codelab 中,我们将仅实现应用的 IAP 优化部分。

您将能够将在此处学到的知识应用到已关联到 Firebase 项目的自有应用中。或者,您也可以为此 Codelab 创建新的 Firebase 项目。如果您需要有关 Firebase 使用入门的帮助,请参阅我们关于此主题的教程(AndroidiOS)。

5. 在应用中收集分析事件

分析事件可帮助您深入了解用户行为,并用于训练机器学习模型。例如,模型可能会了解到,玩游戏时间较长的用户更有可能进行应用内购买,以获得额外的生命值。机器学习模型需要将分析事件作为输入来学习此信息。

我们可能需要记录的一些分析事件包括:

  • 用户玩游戏的时长
  • 用户达到的级别
  • 用户花费的币数
  • 用户购买的商品

下载示例数据(可选)

在以下步骤中,我们将使用 Firebase Analytics 记录分析事件,以便在模型中使用。如果您已有想要使用的分析数据,请跳至此 Codelab 的“训练优化模型”部分,并使用我们的示例数据继续操作。

使用 Firebase Analytics SDK 收集数据

我们将使用 Firebase Analytics 来帮助收集这些分析事件。Firebase Analytics SDK 会自动捕获大量事件和用户属性。您还可以定义自己的自定义事件,以衡量应用特有的事件。

安装 Firebase Analytics SDK

您可以按照 Google Analytics 入门文档中的说明,开始在应用中使用 Firebase Analytics。在本 Codelab 开始时克隆的 firebase-iap-optimization 代码库已包含 Firebase Analytics SDK。

记录自定义事件

设置 Firebase Analytics SDK 后,我们就可以开始记录训练模型所需的事件了。

在此之前,请务必在分析事件中设置用户 ID,以便将该用户的分析数据与其在应用中的现有数据相关联。

MainActivity.kt

firebaseAnalytics.setUserId("player1")

接下来,我们可以记录播放器事件。为了优化应用内购,我们需要记录向用户展示的每项应用内购优惠,以及用户是否点击了相应优惠。这样一来,我们将获得两个分析事件 - offer_iapoffer_accepted。我们还会跟踪唯一的 offer_id,以便稍后使用它来合并这些数据,从而了解用户是否接受了优惠。

MainActivity.kt

predictButton?.setOnClickListener {
  predictionResult = iapOptimizer.predict()

  firebaseAnalytics.logEvent("offer_iap"){
    param("offer_type", predictionResult)
    param("offer_id", sessionId)
  }
}

acceptButton?.setOnClickListener {
  firebaseAnalytics.logEvent("offer_accepted") {
    param("offer_type", predictionResult)
    param("offer_id", sessionId)
  }
}

如需详细了解如何记录自定义事件,请访问 Firebase Analytics 记录事件文档

6. 在 BigQuery 中预处理数据

在最后一步中,我们收集了以下事件:向用户展示了哪些 IAP 优惠,以及用户点击了哪些 IAP 优惠。在此步骤中,我们将此事件数据与用户数据相结合,以便模型能够从完整的数据中学习。

为此,我们需要先将分析事件导出到 BigQuery。

要将 Firebase 项目及其应用与 BigQuery 相关联,请执行以下操作:

  1. 登录 Firebase。
  2. 点击 “设置”图标,然后选择“项目设置”。
  3. 在“项目设置”页面上,点击“集成”标签页。
  4. 在 BigQuery 卡片中,点击“关联”。

(可选)将 Firestore 集合导出到 BigQuery

在此步骤中,您可以选择将其他用户数据从 Firestore 导出到 BigQuery,以用于帮助训练模型。如果您想暂时跳过此步骤,请跳至此 Codelab 的“在 BigQuery 中准备数据”部分,然后您可以按照上一步中记录的 Firebase Analytics 事件进行操作。

您可能已在 Firestore 中存储了用户的注册日期、应用内购买交易、游戏中的等级、余额中的币数,或可能有助于训练模型的任何其他属性。

如需将 Firestore 集合导出到 BigQuery,您可以安装 Firestore BigQuery Export 扩展程序。然后,在 BigQuery 中联接表,将这些数据与 Google Analytics 中的数据合并,以便在个性化模型和本 Codelab 的其余部分中使用。

在 BigQuery 中准备数据

在接下来的几个步骤中,我们将使用 BigQuery 将原始 Analytics 数据转换为可用于训练模型的数据。

为了让模型能够根据用户和游戏状态了解要展示哪个 IAP 优惠,我们需要整理以下方面的数据:

  • 用户
  • 游戏状态
  • 所提供的优惠
  • 所展示的优惠是否被点击

所有这些数据都需要整理到表格中的一行,以便我们的模型进行处理。幸运的是,BigQuery 的设置正是为了帮助我们实现这一目标。

BigQuery 允许创建“视图”来整理查询。视图是由 SQL 查询定义的虚拟表。创建视图时,您可以按照与查询表相同的方式查询视图。我们可以先使用此功能清理分析数据。

为了了解每项应用内购优惠是否被点击,我们需要联接在上一步中记录的 offer_iapoffer_accepted 事件。

all_offers_joined - BigQuery 视图

SELECT
  iap_offers.*,
  CASE
    WHEN accepted_offers.accepted IS NULL THEN FALSE ELSE TRUE
  END
  is_clicked,
FROM
  `iap-optimization.ml_sample.accepted_offers` AS accepted_offers
RIGHT JOIN
  `iap-optimization.ml_sample.iap_offers` AS iap_offers
ON
 accepted_offers.offer_id =iap_offers.offer_id;

all_offers_with_user_data - BigQuery 视图

SELECT
  offers.is_clicked,
  offers.presented_powerup,
  offers.last_run_end_reason,
  offers.event_timestamp,
  users.*
FROM
  `iap-optimization.ml_sample.all_offers_joined` AS offers
LEFT JOIN
  `iap-optimization.ml_sample.all_users` AS users
ON
  users.user_id = offers.user_id;

将 BigQuery 数据集导出到 Google Cloud Storage

最后,我们可以将 BigQuery 数据集导出到 GCS,以便在模型训练中使用它。

888daa7ba4db8e44.png

14d22bf474fae455.png

7. 训练优化模型

示例数据

您可以使用上一步“在 BigQuery 中预处理数据”中的数据,也可以使用此处提供的可下载的示例数据,继续完成本 Codelab 的其余部分。

问题定义

在开始训练模型之前,我们先花一些时间来定义情境化多臂老虎机问题。

情境化 Bandit 算法说明

在 Flappy Sparky 中,用户在每个关卡开始时都会看到一个 IAP 优惠,其中包含一个能量提升道具。我们每次只能展示一个 IAP 选项,并且不知道哪个选项的转化效果最好。鉴于每位用户和每个会话都各不相同,我们如何才能找到可带来最高预期奖励的 IAP 优惠?

在这种情况下,如果用户不接受 IAP 优惠,奖励为 0;如果接受,奖励为 IAP 值。为了尽可能提高奖励,我们可以使用历史数据训练一个模型,该模型可以预测给定用户的每项操作的预期奖励,并找到奖励最高的操作。

e7d3264141498bff.jpeg

以下是我们在预测中使用的内容:

  • 状态:有关用户及其当前会话的信息
  • 操作:我们可以选择展示的应用内购优惠
  • 奖励:应用内购优惠的价值

利用与探索

对于所有多臂老虎机问题,算法都需要在探索(获取更多数据以了解哪种操作可带来最佳结果)和利用(使用最佳结果来获得最高奖励)之间取得平衡。

在我们的问题版本中,我们将对此进行简化,仅在云端定期训练模型,并且仅在用户设备上使用模型时进行预测(而不是在用户设备上进行训练)。为了确保在使用模型后有足够的训练数据,我们需要有时向应用用户显示随机结果(例如 30% 的时间)。这种平衡探索与利用的策略称为 Epsilon-greedy

训练模型

您可以使用 Codelab 随附的训练脚本 (training.ipynb) 开始操作。我们的目标是训练一个模型,该模型可以根据给定的状态预测每项行动的预期奖励,然后找到可带来最高预期奖励的行动。

在本地训练

开始训练您自己的模型的最简单方法是复制此 Codelab 的代码示例中的笔记本。

您无需使用 GPU 即可完成此 Codelab,但如果您需要更强大的机器来探索自己的数据并训练自己的模型,可以获取 AI Platform Notebook 实例来加快训练速度。

在提供的训练脚本中,我们创建了一个迭代器,用于从我们从 BigQuery 导出的 CSV 文件生成训练数据。然后,我们使用这些数据开始使用 Keras 训练模型。有关如何训练模型的详细信息,请参阅 Python 笔记本的注释。

衡量模型性能

在训练模型时,我们会将其与随机选择 IAP 优惠的随机代理进行比较,以查看模型是否在实际学习。此逻辑位于 ValidationCallback.

在训练结束时,我们会使用 test.csv 中的数据再次测试模型。模型之前从未见过这些数据,因此我们可以确信结果不是由过拟合造成的。在这种情况下,模型的表现比随机代理好 28%。

导出 TFLite 模型

现在,我们有了一个训练好的模型,可以随时使用,但目前该模型采用的是 TensorFlow 格式。我们需要将模型导出为 TFLite 格式,以便在移动设备上运行该模型。

train.ipynb

converter = tflite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()

with tf.io.gfile.GFile('iap-optimizer.tflite', 'wb') as f:
  f.write(tflite_model)

您可以在此处下载模型,并将其与您的应用捆绑在一起。

对于正式版应用,我们建议您将模型部署到 Firebase ML 并让 Firebase 托管您的模型。这很有用,主要有两个原因:

  1. 我们可以将应用安装大小保持在较小范围内,并且仅在需要时下载模型
  2. 模型可以定期更新,并且更新周期可以与整个应用不同

如需了解如何将模型部署到 Firebase ML,您可以按照 将 Firebase 添加到由 TFLite 提供支持的 Android 应用 Codelab 中的说明操作。您可以选择使用 Firebase 控制台或 Python API 进行部署。

8. 在设备上进行预测

下一步是使用设备端模型进行预测。您可以在下载的示例代码的 app 文件夹中找到一个从 Firebase ML 下载模型的示例应用,并使用该应用通过一些客户端数据执行推理。

由于我们在模型训练期间应用了一些预处理,因此在设备端运行时,我们需要对模型输入应用相同的预处理。一种简单的方法是使用与平台和语言无关的格式,例如包含每个特征到有关预处理如何完成的元数据的映射的 JSON 文件。您可以在示例应用中详细了解如何执行此操作。

接下来,我们为模型提供如下测试输入:

IapOptimzer.kt

  val testInput = mapOf(
    "coins_spent" to                       2048f,
    "distance_avg" to                      1234f,
    "device_os" to                         "ANDROID",
    "game_day" to                          10f,
    "geo_country" to                       "Canada",
    "last_run_end_reason" to               "laser"
  )

该模型建议 sparky_armor 是最适合此特定用户的应用内购道具。

a3381dbcdbdf811e.png

衡量模型准确率

为了衡量模型的准确性,我们可以使用 Firebase Analytics 简单地跟踪模型预测的 IAP 优惠以及这些优惠是否被点击。您可以将此功能与 Firebase A/B 测试搭配使用,以衡量模型的实际效果。更进一步,您还可以对模型的不同迭代版本执行 A/B 测试。如需详细了解如何使用 Firebase 进行 A/B 测试,请参阅使用 A/B Testing 创建 Firebase Remote Config 实验文档。

9. (可选):定期使用新数据更新模型

如果您需要随着新数据的到来更新模型,可以设置流水线以定期重新训练模型。为此,您需要先确保有新数据可用于训练,方法是使用上文提到的 epsilon-greedy 策略。(例如,70% 的时间使用模型预测结果,30% 的时间使用随机结果)。

配置流水线以使用新数据进行训练和部署不在本 Codelab 的讨论范围内,您可以查看 Google Cloud AI PlatformTFX 以开始使用。

10. 恭喜!

在此 Codelab 中,您学习了如何训练和部署设备端 TFLite 模型,以使用 Firebase 优化应用内购。如需详细了解 TFLite 和 Firebase,请查看其他 TFLite 示例和 Firebase 使用入门指南。

如果您有任何疑问,可以在 Stack Overflow #firebase-machine-learning 上提问。

所学内容

  • TensorFlow Lite
  • Firebase ML
  • Firebase Analytics
  • BigQuery

后续步骤

  • 为应用训练和部署优化器模型。

了解详情