实时设备应用内购买优化 Codelab

1. 概览

1cbf855eda62c306.png

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

本教程介绍了如何构建用于个性化功能的机器学习模型,特别是根据当前用户所处的状态预测最佳的应用内购买 (IAP) 服务。这是一个情境老虎机问题示例,这是一种重要且广泛适用的机器学习问题,您将在此 Codelab 中了解详情

学习内容

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

所需条件

  • Android Studio 版本 3.4 及更高版本
  • 一台安装了 Android 2.3+ 和 Google Play 服务 9.8 或更高版本的实体测试设备,或者一台安装了 Google Play 服务 9.8 或更高版本的模拟器
  • 如果使用实体测试设备,还要有一根连接线
  • 初级机器学习知识

您将如何使用本教程?

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

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

新手 中等 熟练

2. 问题陈述

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

3. 获取示例代码

从命令行克隆 GitHub 代码库

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

此代码库包含:

  1. 一个 Jupyter 笔记本 (.ipynb),用于训练个性化模型并将其打包到 TFLite 模型中
  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 后,我们就可以开始记录训练模型所需的事件了。

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

MainActivity.kt

firebaseAnalytics.setUserId("player1")

接下来,我们可以记录玩家事件。对于 IAP 优化,我们希望记录向用户显示的每项 IAP 服务以及用户是否点击了该优惠。这将为我们提供两个分析事件: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 Extension。然后,在 BigQuery 中联接表,以将此数据与 Google Analytics(分析)中的数据合并,以便用于个性化模型以及此 Codelab 的其余部分。

在 BigQuery 中准备数据

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

为了让我们的模型了解根据用户和游戏状态提供哪些应用内购商品,我们需要整理以下相关数据:

  • 用户
  • 游戏状态
  • 所提供的优惠
  • 展示的产品是否获得点击

所有这些数据都需要整理到表中的一行,以便我们的模型进行处理。幸运的是,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

7. 训练优化模型

示例数据

使用上一步中的数据“在 BigQuery 中预处理数据”或此处提供的可下载示例数据,以遵循此 Codelab 的其余部分。

问题定义

在开始训练模型之前,我们先花一些时间定义上下文老虎机问题。

情境老虎机游戏说明

在《Flappy Sparky》中,每个关卡开始时,系统会向用户显示应用内购优惠,即可获得强化道具。我们每次只能展示一个 IAP 选项,并且我们不知道哪些选项的转化率最高。鉴于每位用户和每次会话都不同,我们该如何找到能带来最高预期奖励的应用内购商品?

在本例中,我们将如果用户不接受应用内购优惠,则将其奖励设为 0,如果接受,则将奖励设为 0。为了尽可能提高奖励,我们可以使用历史数据来训练一个模型,预测用户每次操作的预期奖励,并找出回报最高的操作。

e7d3264141498bff.jpeg

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

  • 状态:与用户及其当前会话相关的信息
  • 行动:我们可以选择展示的应用内购优惠
  • 奖励:应用内购商品的价值

利用与探索

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

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

训练模型

要开始使用,您可以使用此 Codelab 提供的训练脚本 (training.ipynb)。我们的目标是训练一个模型,预测每个动作在给定状态下的预期奖励,然后找到能为我们提供最高预期奖励的操作。

在本地训练

如需开始训练自己的模型,最简单的方法是在此 Codelab 的代码示例中创建该笔记本的副本。

此 Codelab 不需要 GPU,但如果您需要更强大的机器来探索自己的数据和训练自己的模型,可以获取 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 来跟踪模型预测的应用内购商品,以及是否获得了点击。您可以将此测试与 Firebase A/B Testing 结合使用,以衡量模型的实际性能。更进一步,您还可以对模型的不同迭代执行 A/B 测试。您可以参阅使用 A/B Testing 创建 Firebase Remote Config 实验文档,详细了解如何使用 Firebase 进行 A/B 测试。

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

如果您需要在有新数据传入时更新模型,可以设置流水线以定期重新训练模型。为此,您首先需要确保有新数据可用于训练,使用我们前面提到的 epsilon-greedy 策略。(例如,70% 的几率使用模型预测结果,30% 的几率使用随机结果)。

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

10. 恭喜!

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

如果您有任何疑问,欢迎在 Stack Overflow #firebase-machine-learning 上发帖咨询。

所学内容

  • TensorFlow Lite
  • Firebase ML
  • Firebase Analytics
  • BigQuery

后续步骤

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

了解详情