1. 概览
欢迎学习设备端实时应用内购买优化 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 或更高版本的实体测试设备,或者一个搭载 Android 2.3 或更高版本且安装了 Google Play 服务 9.8 或更高版本的模拟器
- 如果使用实体测试设备,还需要一根连接电缆
- 初级机器学习知识
您打算如何使用本教程?
您如何评价自己在构建 Android 应用方面的经验水平?
2. 问题陈述
假设您是一名游戏开发者,希望在每个关卡结束时显示个性化的应用内购买 (IAP) 建议。每次只能展示有限数量的应用内购选项,而且您并不知道哪些选项的转化率最高。考虑到每个用户和每次会话的情况不尽相同,我们该如何找到预期奖励最高的 IAP 优惠?
3. 获取示例代码
从命令行克隆 GitHub 代码库。
git clone https://github.com/googlecodelabs/firebase-iap-optimization.git
此代码库包含:
- 用于训练个性化模型并将其打包为 TFLite 模型的 Jupyter 笔记本 (.ipynb)
- 使用 TFLite 模型在设备上进行预测的 Kotlin 示例应用
4. 使用 Firebase 运行应用
在此 Codelab 中,我们将优化虚构游戏应用 Flappy Sparky 的 IAP。这款游戏是横向卷轴游戏,玩家控制着 Sparky,试图在两列墙壁之间飞行,而不撞到墙壁。在关卡开始时,用户会看到一项应用内购优惠,从而获得能力提升道具。在此 Codelab 中,我们将仅实现应用的 IAP 优化部分。
您可以将在这里学到的知识应用到与 Firebase 项目相关联的您自己的应用中。或者,您也可以为本 Codelab 创建一个新的 Firebase 项目。如果您需要 Firebase 使用入门方面的帮助,请参阅有关此主题的教程(Android 和 iOS)。
5. 在您的应用中收集分析事件
分析事件可让您深入了解用户行为,还可用于训练机器学习模型。例如,模型可能会了解到,玩游戏时间更长的用户更有可能通过应用内购买来获得额外的生命。机器学习模型需要以 Google Analytics 事件作为输入来学习此信息。
我们可能要记录的一些分析事件包括:
- 用户玩游戏的时长
- 用户达到的等级
- 用户花费了多少金币
- 用户购买了哪些商品
下载示例数据(可选)
在后续步骤中,我们将使用 Firebase Analytics 记录要在模型中使用的分析事件。如果您已经拥有要使用的分析数据,请跳转到“训练优化模型”部分,您可以按照我们的示例数据进行操作。
使用 Firebase Analytics SDK 收集数据
我们将使用 Firebase Analytics 来帮助收集这些分析事件。Firebase Analytics SDK 会自动捕获大量事件和用户属性。您还可以定义自己的自定义事件,以衡量应用特有的事件。
安装 Firebase Analytics SDK
若要开始在您的应用中使用 Firebase Analytics,请参阅 Google Analytics 使用入门文档。在本 Codelab 开头克隆的 firebase-iap-optimization
代码库已包含 Firebase Analytics SDK。
记录自定义事件
设置 Firebase Analytics SDK 后,我们就可以开始记录训练模型所需的事件了。
在此之前,请务必在分析事件中设置 User-ID,以便我们可以将该用户的分析数据与其应用中的现有数据相关联。
MainActivity.kt
firebaseAnalytics.setUserId("player1")
接下来,我们可以记录玩家事件。为了优化应用内购,我们希望记录向用户显示的每个应用内购商品,以及用户是否点击了该商品。这样一来,我们将获得两个 Google Analytics 事件:offer_iap
和 offer_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 优惠的事件。在此步骤中,我们会将此事件数据与用户数据结合起来,以便模型能够从全面的信息中学习。
为此,我们需要先将 Google Analytics 事件导出到 BigQuery。
将您的 Firebase 项目链接到 BigQuery
要将 Firebase 项目及其应用与 BigQuery 相关联,请执行以下操作:
- 登录 Firebase。
- 点击 ,然后选择“项目设置”。
- 在“项目设置”页面上,点击“集成”标签页。
- 在 BigQuery 卡片中,点击“关联”。
(可选)将 Firestore 集合导出到 BigQuery
在此步骤中,您可以选择将其他用户数据从 Firestore 导出到 BigQuery,以便帮助训练模型。如果您暂时想跳过此步骤,请跳转到本 Codelab 的“在 BigQuery 中准备数据”部分,然后按照上一步中记录的 Firebase Analytics 事件操作。
Firestore 可能存储了用户的注册日期、所进行的应用内购买交易、游戏中的关卡、余额中的金币或在训练模型时可能有用的任何其他属性。
如需将 Firestore 集合导出到 BigQuery,您可以安装 Firestore BigQuery Export 扩展程序。然后,在 BigQuery 中联接表,将这些数据与 Google Analytics 中的数据相结合,以便在个性化模型中使用以及此 Codelab 的其余部分。
在 BigQuery 中准备数据
在接下来的几个步骤中,我们将使用 BigQuery 将原始 Google Analytics 数据转换为可用于训练模型的数据。
为了让模型能够根据用户和游戏状态了解要展示哪些 IAP 商品,我们需要整理以下方面的数据:
- 用户
- 游戏状态
- 提供的优惠
- 用户是否点击了所展示的优惠
所有这些数据都需要整理成表格中的一行,以便我们的模型进行处理。幸运的是,BigQuery 可以帮助我们实现这一目标。
BigQuery 允许创建“视图”,以便井然有序地管理查询。视图是由 SQL 查询定义的虚拟表。创建视图时,您可以按照与查询表相同的方式查询视图。我们可以先使用此方法来清理分析数据。
要查看是否点击每个应用内购商品,我们需要联接上一步中记录的 offer_iap
和 offer_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,以便在模型训练中使用。
7. 训练优化模型
示例数据
使用上一步“在 BigQuery 中预处理数据”中的数据,或此处提供的可下载的示例数据,以便了解此 Codelab 的其余部分。
问题定义
在开始训练模型之前,让我们花一些时间来定义上下文老虎机问题。
上下文老虎机解析
在 Flappy Sparky 的每个关卡开始时,用户都会获得一项内购优惠,从而获得能力提升道具。我们每次只能显示一个 IAP 选项,并且不知道哪些选项的转化效果最好。考虑到每个用户和每次会话的情况不尽相同,我们该如何找到预期奖励最高的 IAP 优惠?
在本例中,如果用户不接受 IAP 优惠,则将奖励设为 0;如果用户接受,则将奖励设为 IAP 价值。为了尽可能提高奖励金额,我们可以使用历史数据训练一个模型,该模型可预测用户执行每项操作的预期奖励,并找出奖励金额最高的操作。
我们将在预测中使用以下内容:
- 状态:与用户及其当前会话相关的信息
- 操作:我们可以选择显示的应用内购优惠
- 奖励:应用内购优惠的价值
利用与探索
对于所有多臂式强盗问题,算法需要在探索(获取更多数据以了解哪个操作可带来最佳结果)和利用(使用最佳结果获得最高奖励)之间取得平衡。
在我们的版本中,我们将简化此问题,只在云端定期训练模型,并仅在用户设备上使用模型时进行预测(而不是在用户设备上进行训练)。为确保在使用模型后获得足够的训练数据,我们有时需要向应用用户显示随机结果(例如 30%)。这种平衡探索和利用的策略称为ε-贪心。
训练模型
您可以使用 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 托管您的模型(可选)。这非常有用,主要有两个原因:
- 我们可以将应用安装大小保持在较小范围内,并仅在需要时下载模型
- 模型可以定期更新,并且发布周期与整个应用不同
如需了解如何将模型部署到 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
是此特定用户的最佳应用内购功能。
衡量模型准确率
如需衡量模型的准确性,我们只需使用 Firebase Analytics 跟踪模型预测的应用内商品以及用户是否点击了这些商品即可。您可以将其与 Firebase A/B Testing 结合使用,以衡量模型的实际性能。更进一步,您还可以对模型的不同迭代进行 A/B 测试。如需详细了解如何使用 Firebase 进行 A/B 测试,请参阅使用 A/B Testing 创建 Firebase Remote Config 实验文档。
9. (可选)使用新数据定期更新模型
如果您需要在有新数据到来时更新模型,可以设置流水线以定期重新训练模型。为此,您需要先确保有新数据可用于采用我们上面提到的 epsilon-greedy 策略进行训练。(例如,70% 的时间使用模型预测结果,30% 的时间使用随机结果)。
配置流水线以使用新数据进行训练和部署不在此 Codelab 的范围内,您可以先查看 Google Cloud AI Platform 和 TFX。
10. 恭喜!
在此 Codelab 中,您学习了如何使用 Firebase 训练和部署设备端 TFLite 模型,以优化应用内购买。如需详细了解 TFLite 和 Firebase,请查看其他 TFLite 示例和 Firebase 使用入门指南。
如果您有任何疑问,可以在 Stack Overflow #firebase-machine-learning 上提问。
所学内容
- TensorFlow Lite
- Firebase ML
- Firebase Analytics
- BigQuery
后续步骤
- 为您的应用训练和部署优化器模型。