BigQueryML 机器学习(二)
原文:
annas-archive.org/md5/129c41c69917f87275f2c178adc5dd48译者:飞龙
第六章:使用多类逻辑回归对树木进行分类
多类逻辑回归是用于将事件、实体和行为分类到固定数量类别的机器学习(ML)算法。当需要预测实体分类到多个组时,它可用于不同的行业和业务场景。一个典型的分类用例是,根据公司的盈利能力和偏好对公司客户群进行细分,以便针对最有效的营销活动定位正确的客户。
这种技术是二分类逻辑回归的扩展,使我们能够克服两个可能标签的限制,并使适用性扩展到其他可以找到多个类别进行识别的上下文中。
在本章中,我们将看到实现、评估和测试多类逻辑回归模型所需的所有阶段,利用 BigQuery ML。
在本章中,我们将讨论以下主题:
-
介绍业务场景
-
发现多类逻辑回归
-
探索和理解数据集
-
训练多类逻辑回归模型
-
评估多类逻辑回归模型
-
使用多类逻辑回归模型
-
提炼业务结论
技术要求
本章要求您访问网络浏览器,并具备利用以下功能的能力:
-
一个 GCP 账户以访问 Google Cloud 控制台
-
一个用于托管 BigQuery 数据集的 GCP 项目
现在我们已经准备好了技术要求,让我们深入分析和发展我们的 BigQuery ML 逻辑回归模型。
查看以下视频,了解代码的实际应用:bit.ly/3h4w7xG
介绍业务场景
对于这个业务场景,我们可以想象自己是一名纽约市的 ML 专家。在市应执行的所有活动中,对树木进行普查和验证其状况是最耗时的之一。
这些树木分布在新泽西市的不同区域,收集每棵树的信息是由志愿者或纽约市员工手动完成的。信息收集完成后,数据存储在数据库中,并通过 BigQuery 公共数据集公开,以便进行进一步分析(console.cloud.google.com/marketplace/details/city-of-new-york/nyc-tree-census)。
在以下图中,我们可以看到中央公园的一张照片,这是纽约市树木最多的区域之一:
图 6.1 – 纽约市中央公园的树木
为了支持和加速负责分类树木和评估其状况的人员的工作,你们的一位经理可能要求你构建一个机器学习模型。
机器学习模型的目标是根据树木的特征,如位置、大小和健康状况,自动将树木分类到不同的种类。
对于这个用例,我们只需关注城市中最常见的五种树木种类。
现在我们已经简要解释并理解了业务场景,让我们看看我们可以用来将对象或事件分类到多个类别的机器学习技术。
发现多类逻辑回归
在本节中,我们将学习多类逻辑回归的基础知识以及何时可以应用这项技术。
多类逻辑回归是一种分类技术,可以用来将事件、对象、客户或其他实体分类到多个类别。与二元逻辑回归不同,这个机器学习算法可以将输出值分类到超过两个离散类别。
为了预测多个标签中的一个,这个机器学习算法计算每个结果的概率,并选择概率最高的标签。
作为一种回归算法,标签的预测基于一组称为特征的独立变量,这些变量用于预测称为标签的因变量。
这种机器学习技术可以用来回答以下业务问题:
-
我的客户的评论是中性、正面还是负面?
-
我的客户属于金、银还是铜等级?
-
特定客户的流失概率是高、中还是低?
-
图像识别算法识别的是猫、狗、老鼠还是牛?
在我们的业务场景中,由于树木的种类有限,我们只关注五种,我们可以利用多类逻辑回归。具体来说,我们感兴趣的是根据树木的大小、位置和健康状况特征将其分类到五种种类之一。
训练多类逻辑回归模型意味着尝试找到可以用于输入变量(称为特征)和输出变量(称为标签)之间方程的系数值。
训练完成后,我们将利用混淆矩阵来评估我们的多类逻辑回归模型的表现。在多类逻辑回归中,混淆矩阵由多行和多列组成。
为了评估我们的机器学习模型的表现,我们还将使用曲线下面积(AUC)接收者操作特征(ROC)。
现在我们已经学习了多类逻辑回归的基础知识,是时候看看我们将用于构建机器学习模型的那个数据集了。
探索和理解数据集
正如我们在前面的用例中所做的那样,在深入开发机器学习模型之前,分析可用于解决我们用例的数据是必要的。
我们将首先分析表结构,以便清楚地了解可用于我们业务场景的数据。
理解数据
在本节中,我们将查看数据以了解其结构以及如何用它来构建我们的机器学习模型。
要开始探索数据,我们需要做以下几步:
-
登录 Google Cloud 控制台,并通过导航菜单访问BigQuery用户界面。
-
在我们创建的项目下创建一个新的数据集,该项目在第二章,设置您的 GCP 和 BigQuery 环境中提到。对于此用例,我们将使用默认选项创建数据集
06_nyc_trees。 -
打开 GCP 项目
new_york_trees。 -
如以下截图所示,BigQuery 公共数据集包含多个表,用于存储每 10 年收集的数据:
图 6.2 – 纽约市树木公共数据集包含了每 10 年收集的树木普查数据
-
我们将使用最新的一个:
tree_census_2015。这个表包含了 2015 年在纽约市种植并注册的所有树木信息。 -
让我们在 BigQuery 导航菜单中点击表名
tree_census_2015以访问表的架构:图 6.3 – tree_census_2015 表的结构列出了所有可以作为标签和特征的字段
-
每个字段都在描述列中有很好的描述。
表中包含表示每种树木物种的科学名称的spc_latin列,该列以STRING形式表示。这个字段将是我们的机器学习模型的标签。
为了对每棵树进行分类,我们可以利用其他字段中的信息。一些列描述了树木的大小。例如,tree_dbh测量树木的直径,stump_diam代表树桩的直径。我们还可以利用关于树木健康状况的信息。我们可以想象,一些物种比其他物种更健壮,更适合纽约市的天气。
其他字段与树木在城市中的位置以及其生活环境的背景关系更为密切。为了训练我们的机器学习模型,我们可以使用树木所在的邮编区域:zip_city。其他一些例子包括包含树木种植区域名称的boroname列,以及代表树木所属地区的nta_name。
我们还可以假设某些物种比其他物种更具侵入性——
sidewalk字段表示树木旁边的人行道是否因树木的根而受损、开裂或抬起。从架构的角度来看,此表包含大量可用于开发我们的分类模型的有用信息。让我们继续我们的分析,更深入地了解数据。
在本节中,我们已经分析了 tree_census_2015 表的元数据,现在是我们查看实际数据并开始查询的时候了。
检查数据质量
正如我们从之前的用例中已经理解的那样,数据质量对于构建有效的机器学习模型至关重要。在本节中,我们将应用一些数据质量检查,以确定应使用的正确记录:
-
首先,我们将检查表
tree_census_2015是否包含spc_latin等于 NULL 的记录。这是基本的,因为字段spc_latin将用作我们机器学习模型的标签:SELECT COUNT(*) total FROM `bigquery-public-data.new_york_trees.tree_census_2015` WHERE spc_latin is NULL;代码块将统计表
bigquery-public-data.new_york_trees.tree_census_2015中字段spc_latin为空的记录数量。在下面的屏幕截图中,您可以查看查询结果,其中我们得到了超过三千一的结果:
图 6.4 – 查询结果显示某些行包含空标签
因此,在接下来的查询中,我们将排除字段
spc_latin为空的记录。 -
仅关注字段
spc_latin为NOT NULL的行,我们可以检查所有其他潜在特征字段上空值的存在:SELECT COUNT(*) FROM `bigquery-public-data.new_york_trees.tree_census_2015` WHERE spc_latin is NOT NULL AND ( zip_city is NULL OR tree_dbh is NULL OR boroname is NULL OR nta_name is NULL OR nta_name is NULL OR health is NULL OR sidewalk is NULL) ;此外,在这种情况下,查询的结果不是零。事实上,我们可以轻松地识别出三个在
health和sidewalk字段中呈现NULL值的记录。我们将在机器学习模型生命周期的后续阶段过滤这些记录。
现在我们已经对我们的数据集进行了质量检查,并了解了哪些记录应该被过滤,让我们专注于分割我们的数据集,以便只针对树木的五种最频繁出现的物种创建我们的 BigQuery 机器学习模型。
数据集分割
在本节中,我们将准备我们将用于训练、评估和测试我们的机器学习模型的表。
为了我们的目的,我们将从数据集中提取出现频率最高的五种物种。之后,我们将创建用于训练、评估和测试我们的机器学习模型的 BigQuery 表:
-
首先,我们将使用以下查询仅识别
tree_census_2015表中的五种最频繁出现的物种:SELECT spc_latin, COUNT(*) total FROM `bigquery-public-data.new_york_trees.tree_census_2015` WHERE spc_latin is NOT NULL AND zip_city is NOT NULL AND tree_dbh is NOT NULL AND boroname is NOT NULL AND nta_name is NOT NULL AND health is NOT NULL AND sidewalk is NOT NULL GROUP BY spc_latin ORDER BY total desc LIMIT 5;SQL 语句使用
GROUP BY spc_latin子句和COUNT(*)操作符计算tree_census_2015表中每种物种出现的次数。查询按照
total字段(包含COUNT的结果)的值以降序排列记录,最后,查询的结果集通过查询末尾的LIMIT 5子句限制为结果集的前五条记录。SQL 语句基于 BigQuery 公共表
tree_census_2015,经过我们在前面的检查数据质量部分中确定的数据质量检查适当过滤。在下面的屏幕截图中,我们可以看到查询结果和我们的数据集中最常见的树木物种:
图 6.5 – 查询的结果显示了纽约市最常见的树木
从查询结果中,我们可以轻松地读取从最常见到最不常见的树木的拉丁学名。
-
由于我们将在接下来的 SQL 查询中使用这五种物种的子集,我们可以在我们的
SELECT语句的开头添加一个CREATE TABLE语句,以便将结果物化到top5_species表中:CREATE OR REPLACE TABLE `06_nyc_trees.top5_species` AS SELECT spc_latin, COUNT(*) total FROM `bigquery-public-data.new_york_trees.tree_census_2015` WHERE spc_latin is NOT NULL AND zip_city is NOT NULL AND tree_dbh is NOT NULL AND boroname is NOT NULL AND nta_name is NOT NULL AND health is NOT NULL AND sidewalk is NOT NULL GROUP BY spc_latin ORDER BY total desc LIMIT 5;通过执行查询,我们将得到创建一个新表的创建,该表仅包含两个字段和五条记录。
spc_latin代表树木的物种,而total计算每个物种在原始数据集中的出现次数。 -
现在,我们可以利用
top5_species表来过滤仅关注物种,并创建训练表:CREATE OR REPLACE TABLE `06_nyc_trees.training_table` AS SELECT * FROM `bigquery-public-data.new_york_trees.tree_census_2015` WHERE zip_city is NOT NULL AND tree_dbh is NOT NULL AND boroname is NOT NULL AND nta_name is NOT NULL AND health is NOT NULL AND sidewalk is NOT NULL AND spc_latin in (SELECT spc_latin from `06_nyc_trees.top5_species`) AND MOD(tree_id,11)<=8;查询通过
SELECT *语句创建一个包含原始数据集中所有列的表。它应用了所有必要的过滤器,以获取spc_latin标签的非空值以及所有其他潜在特征。使用
IN子句,training_table将只包含与数据集中最频繁的五种物种相关的记录。查询的最后一条语句,带有
MOD(tree_id,11)<=8子句,使我们能够只从整个记录集中选择 80%的记录。MOD代表模运算,返回tree_id除以 11 的余数。 -
使用类似的方法,我们可以创建用于评估我们的机器学习模型的表:
CREATE OR REPLACE TABLE `06_nyc_trees.evaluation_table` AS SELECT * FROM `bigquery-public-data.new_york_trees.tree_census_2015` WHERE zip_city is NOT NULL AND tree_dbh is NOT NULL AND boroname is NOT NULL AND nta_name is NOT NULL AND health is NOT NULL AND sidewalk is NOT NULL AND spc_latin in (SELECT spc_latin from `06_nyc_trees.top5_species`) AND MOD(tree_id,11)=9;对于
evaluation_table,我们将通过MOD(tree_id,11)=9过滤器选择仅 10%的记录。 -
最后,我们将执行以下 SQL 语句以创建用于应用我们的多类分类模型的表:
CREATE OR REPLACE TABLE `06_nyc_trees.classification_table` AS SELECT * FROM `bigquery-public-data.new_york_trees.tree_census_2015` WHERE zip_city is NOT NULL AND tree_dbh is NOT NULL AND boroname is NOT NULL AND nta_name is NOT NULL AND health is NOT NULL AND sidewalk is NOT NULL AND spc_latin in (SELECT spc_latin from `06_nyc_trees.top5_species`) AND MOD(tree_id,11)=10;classification_table与数据集的前几部分非常相似,但多亏了MOD函数,它将包含数据集剩余的 10%。
在本节中,我们分析了包含有关纽约市树木信息的new_york_trees数据集。我们对数据进行了一些数据质量检查,以排除空值。然后,我们分割了数据,重点关注表中出现的五种最常见的物种。现在我们已经完成了准备工作,是时候继续前进并开始训练我们的 BigQuery ML 模型了。
训练多类逻辑回归模型
现在我们已经清楚地理解了数据结构,并且将其分割成多个表格以支持 ML 模型生命周期的不同阶段,让我们专注于我们多类逻辑回归模型的训练。我们将执行 SQL 查询来创建我们的多类逻辑回归模型:
-
让我们开始创建我们 ML 模型的第一版本:
CREATE OR REPLACE MODEL `06_nyc_trees.classification_model_version_1` OPTIONS ( model_type='LOGISTIC_REG', auto_class_weights=TRUE ) AS SELECT zip_city, tree_dbh, spc_latin as label FROM `06_nyc_trees.training_table` ;创建
classification_model_version_1模型所使用的查询仅基于两个特征:邮编区域和树木直径。SQL 语句以关键字
CREATE OR REPLACE MODEL开始,用于运行训练,后面跟着OPTIONS子句。在选项中,我们可以指定模型类型等于LOGISTIC_REG和auto_class_weights=TRUE。这个选项在我们面对不平衡的训练数据集,某些标签出现频率高于其他标签时尤其有用。在我们的案例中,最常见的物种的出现次数是第五个物种的两倍以上。因此,我们应用了这种调整。重要提示
BigQuery ML 语法在二元逻辑回归和多类逻辑回归之间没有区别。在两种情况下,BigQuery ML 模型类型都是
LOGISTIC_REG。差异是由训练数据集列标签中出现的不同值的数量引起的。如果标签只包含两个值,BigQuery ML 将训练二元逻辑回归。如果标签包含超过两个不同值,模型将作为多类逻辑回归进行训练。 -
训练执行后,我们可以通过点击导航菜单中的classification_model_version_1并选择评估选项卡来访问我们第一个 ML 模型的信息。
以下截图展示了我们第一次尝试的关键性能指标:
![Figure 6.6 – The Evaluation tab shows the performance metrics related
到选定的 BigQuery ML 模型
![img/B16722_06_006.jpg]
Figure 6.6 – The Evaluation tab shows the performance metrics related to the selected BigQuery ML model
为了了解我们 ML 模型的有效性,我们可以查看ROC AUC值为0.7383。
通过在评估选项卡中用鼠标向下滚动,我们可以查看我们多类逻辑回归模型的混淆矩阵。
在以下图中,混淆矩阵显示了训练数据集中预测和实际标签的百分比:
图 6.7 – 评估选项卡显示了与所选 BigQuery ML 模型相关的混淆矩阵
通过查看混淆矩阵,我们可以直观地注意到,我们的机器学习模型在某些物种上表现相当好,但在其他物种上表现非常差。例如,当实际标签是Quercus palustris时,在 40%的情况下,机器学习模型建议的是不同的物种:Platanus x acerifolia。
-
让我们尝试通过以下 BigQuery ML SQL 语句添加新特征来改进我们的模型:
CREATE OR REPLACE MODEL `06_nyc_trees.classification_model_version_2` OPTIONS ( model_type='LOGISTIC_REG', auto_class_weights=TRUE ) AS SELECT zip_city, tree_dbh, boroname, nta_name, spc_latin as label FROM `06_nyc_trees.training_table` ;与第一次尝试相比,我们在模型的训练中加入了额外的特征。实际上,我们将
boroname字段和nta_name中包含的区名添加到了特征列表中。执行 SQL 语句后,让我们访问新模型的评估选项卡,看看我们是否提高了其性能。查看ROC AUC值为0.7667,我们可以看到我们模型性能的轻微提升。
-
作为最后的尝试,我们将通过添加额外的特征来丰富我们的机器学习模型。新字段与树木的健康状况和根的大小相关:
CREATE OR REPLACE MODEL `06_nyc_trees.classification_model_version_3` OPTIONS ( model_type='LOGISTIC_REG', auto_class_weights=TRUE ) AS SELECT zip_city, tree_dbh, boroname, nta_name, health, sidewalk, spc_latin as label FROM `06_nyc_trees.training_table`;与之前的机器学习模型相比,在
classification_model_version_3中,我们包括了health字段,它描述了我们的树木的健康状况,以及sidewalk字段,用于指定树木的根是否损坏了相邻的人行道。 -
查看我们最后一个机器学习模型在
0.7696的性能。小贴士
尽管使用更多特征可以增加 BigQuery ML 分类模型的 ROC AUC 值,但我们需要考虑性能提升和实现它所花费的资源之间的平衡。在现实场景中,尤其是在数据量真的很大时,我们需要选择那些可能对我们 BigQuery ML 模型性能产生最高影响的特征。
在本节中,我们创建了不同的机器学习模型,尝试在我们的数据集中使用不同的特征。在下一节中,我们将使用具有最高 ROC AUC 值的模型:classification_model_version_3。
接下来,让我们利用评估数据集评估我们的机器学习模型的表现。
评估多类逻辑回归模型
在本节中,我们将执行查询以检查多类逻辑回归模型的表现。
对于我们的 BigQuery ML 模型的评估阶段,我们将使用ML.EVALUATE函数和evaluation_table表,该表专门创建用于托管评估记录。
如我们所见,评估是在模型训练阶段使用的相同字段上进行的,但这些字段是从完全独立于训练数据集创建的evaluation_table表中提取的。
外部SELECT语句提取了ML.EVALUATE函数返回的roc_auc值。它还提供了一个从'POOR'开始,到'EXCELLENT'等级,经过一些中间阶段如'NEEDS IMPROVEMENTS'和'GOOD',的模型质量的描述。
让我们执行以下查询以提取我们 ML 模型的关键性能指标:
SELECT
roc_auc,
CASE
WHEN roc_auc > .9 THEN 'EXCELLENT'
WHEN roc_auc > .8 THEN 'VERY GOOD'
WHEN roc_auc > .7 THEN 'GOOD'
WHEN roc_auc > .6 THEN 'FINE'
WHEN roc_auc > .5 THEN 'NEEDS IMPROVEMENTS'
ELSE
'POOR'
END
AS model_quality
FROM
ML.EVALUATE(MODEL `06_nyc_trees.classification_model_version_3`,
(
SELECT
zip_city,
tree_dbh,
boroname,
nta_name,
health,
sidewalk,
spc_latin as label
FROM `06_nyc_trees.evaluation_table`));
从以下截图,我们可以看到查询结果——roc_auc值达到了 0.77 以上。我们的 BigQuery ML 模型的结果可以被认为是良好的:
图 6.8 – 查询提取 BigQuery ML 模型的 ROC AUC 值和模型质量的简短描述
现在我们已经验证了该机器学习模型在非重叠评估数据集上也能保持其性能,我们可以开始使用它来对classification_table表中的树木进行分类。
使用多类逻辑回归模型
在本节中,我们将测试我们的 ML 模型并分析结果。
要使用我们的 BigQuery ML 模型,我们将使用ML.PREDICT函数和classification_table表,该表存储了记录,以测试我们的模型,如下代码块所示:
SELECT
tree_id,
actual_label,
predicted_label_probs,
predicted_label
FROM
ML.PREDICT (MODEL `06_nyc_trees.classification_model_version_3`,
(
SELECT
tree_id,
zip_city,
tree_dbh,
boroname,
nta_name,
health,
sidewalk,
spc_latin as actual_label
FROM
`06_nyc_trees.classification_table`
));
查询语句由SELECT关键字组成,它提取了tree_id、字段中物种的实际值actual_label以及预测字段predicted_label_probs和predicted_label。
ML.PREDICT函数应用于SELECT语句,从classification_table中提取特征和实际物种。actual_label字段将仅作为预测的基准,而不是在预测阶段使用。
在以下截图中,我们可以看到之前查询执行得到的记录的结构:
图 6.9 – 分类模型生成的输出数据集的记录
在这种情况下,tree_id等于857,这棵树是Quercus palustris,并且被 BigQuery ML 模型正确分类,因为predicted_label与实际值完全相同。predicted_label_probs表示最高分类标签的置信度为 45%。所有其他可能的物种都由较低的几率来表征。
现在我们已经应用了我们的模型,让我们对分类用例的一些最终考虑进行阐述。
提出业务结论
使用上一节中得到的多类逻辑回归模型的结果,我们将对 ML 模型的有效性得出一些结论。
在之前的查询中添加一个父SELECT COUNT语句,我们可以计算与总记录数相比有多少预测是正确的。
让我们执行以下查询来计算我们的 BigQuery ML 模型在classification_table表中正确分类树木的频率:
SELECT COUNT(*)
FROM (
SELECT
tree_id,
actual_label,
predicted_label_probs,
predicted_label
FROM
ML.PREDICT (MODEL `06_nyc_trees.classification_model_version_3`,
(
SELECT
tree_id,
zip_city,
tree_dbh,
boroname,
nta_name,
health,
sidewalk,
spc_latin as actual_label
FROM
`06_nyc_trees.classification_table`
)
)
)
WHERE
actual_label = predicted_label;
SELECT COUNT查询的结果返回了 13,323 个预测值,其中正确预测的标签值为 13,323。
考虑到classification_table表的总大小为 27,182,我们可以声明在 49%的情况下,我们的 ML 模型能够根据其特征和位置预测正确的树种。
这可能看起来是一个不好的结果,但我们需要考虑多分类逻辑回归比二分类更复杂,因为存在多个选项可能会误导我们模型的结果。
摘要
在本章中,我们构建了我们的第一个多分类模型。在简要介绍用例之后,我们发现了多分类逻辑回归是什么以及它是如何根据特征将事件、行为和对象分类到两个以上类别的。
在深入开发 ML 模型之前,我们分析了与纽约市树木相关的数据集模式,并应用了一些必要的质量检查,以构建一个有效的 ML 模型。
在训练阶段,我们使用不同的特征训练了三个不同的 ML 模型,以逐步提高 BigQuery ML 模型的表现。
然后,我们选择了第三个 ML 模型,并对其进行了评估。在这个阶段,我们注意到 ML 模型能够在新记录上保持其性能,并准备进入下一阶段。
在最后一步,我们使用我们的 ML 模型将纽约市的树木分类为五个不同的类别,并利用它们的特征,如大小、健康状况和在城市中的位置。
我们还计算出我们的分类模型在 49%的情况下能够正确分类树种。
在下一章中,我们将介绍无监督 ML 和 K-Means 聚类技术。
进一步资源
-
纽约市树木普查公共数据集:
console.cloud.google.com/marketplace/product/city-of-new-york/nyc-tree-census -
BigQuery ML 创建模型:
cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-create -
BigQuery ML 评估模型:
cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-evaluate -
BigQuery ML 预测:
cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-predict -
BigQuery ML 多类逻辑回归示例:
cloud.google.com/bigquery-ml/docs/logistic-regression-prediction
第三部分:使用 BigQuery ML 的高级模型
在本节中,将解释和展示一些额外的和高级的机器学习模型,并使用 BigQuery ML 提供实际动手操作的示例。
本节包括以下章节:
-
第七章, 使用 K-Means 算法进行聚类
-
第八章, 使用时间序列进行预测
-
第九章, 通过矩阵分解推荐合适的产品
-
第十章, 使用 XGBoost 预测布尔值
-
第十一章, 实现深度神经网络
第七章:使用 K-Means 算法进行聚类
在本章中,我们将介绍无监督机器学习,并学习如何使用 BigQuery ML 构建 K-Means 算法将相似数据聚类到多个类别中。
当我们拥有没有任何标签的数据集,并且需要在没有初始知识的情况下推断数据结构时,无监督机器学习特别有用。
在不同的行业中,根据一组特定的特征识别相似的事件、对象和人物非常有价值。K-Means 聚类通常用于根据一组特定的特征识别相似的客户、文档、产品、事件或物品。
在本章中,我们将重点关注广泛用于揭示结构化和非结构化数据相似性的 K-Means 聚类算法。我们将通过构建 K-Means 聚类模型所需的所有步骤,利用 BigQuery ML 进行操作。
采用增量方法,我们将探讨以下主题:
-
介绍业务场景
-
发现 K-Means 聚类
-
探索和理解数据集
-
训练 K-Means 聚类模型
-
评估 K-Means 聚类模型
-
使用 K-Means 聚类模型
-
提炼业务结论
技术要求
本章要求您能够访问网络浏览器,并能够利用以下内容:
-
一个用于访问 GCP 控制台的 Google Cloud Platform (GCP) 账户
-
一个用于托管 BigQuery 数据集的 GCP 项目
现在我们已经准备好了技术要求,让我们深入分析和发展我们的 BigQuery ML 聚类模型。
查看以下视频以查看代码的实际应用:bit.ly/2Rx2Uk5
介绍业务场景
想象一下,你是一名为芝加哥大型出租车公司工作的商业分析师。这些出租车公司每天要完成数千次行程,以满足整个城市的公共交通需求。出租车司机的工作和行为对于为公司创造收入和为所有客户提供有效服务至关重要。
对于我们的业务场景,让我们想象所有出租车公司都想给表现最好的司机额外奖励。公司的目标是根据生成的收入和驾驶速度将司机分为三个不同的类别。这三个群体可以描述如下:
-
顶级司机是全年收入和效率最佳的员工。这个群体将获得巨大的额外奖励。
-
优秀司机是表现良好但并不突出的司机。这个群体将不会获得任何奖励。
-
中性司机是在收入和效率方面结果中性或负面的司机。
识别聚类参数不是事先已知的,因为它们可以根据不同的因素(如盈利能力、速度和交通状况)而变化。有些年份比其他年份更有利可图,而且驾驶速度可能会受到特定交通状况的影响。
作为一名商业分析师,你的任务是找到最佳的算法,根据描述的分类将芝加哥出租车司机聚类,以便根据他们的表现将司机分为三个类别。
既然我们已经解释并理解了问题陈述,让我们看看我们可以用来预测数值(如行程持续时间)的机器学习技术。
发现 K-Means 聚类
在本节中,我们将了解什么是无监督学习,并学习K-Means聚类技术的基础知识。
K-Means是一种无监督学习算法,用于解决聚类问题。这种技术用于将数据分类到一组类别中。字母k代表事先固定的聚类数量。在我们的业务场景中,我们将使用三个不同的聚类。
重要提示
虽然监督学习基于对训练数据集中标签输出值事先的知识,但无监督学习并不利用标记数据集。其目标是推断训练数据集中的数据结构,而不需要任何先验知识。
每个数据簇都由一个质心来表征。质心代表簇的中点,在训练阶段根据模型特征被识别。
在 K-Means 聚类模型训练之后,每个实体都可以与最近的质心关联,并包含在其中一个k个聚类中。
在下面的图中,你可以查看基于两个特征和一个k等于3的值的简单聚类模型的图形表示:
![图 7.1 – K-Means 聚类的图形表示
图 7.1 – K-Means 聚类的图形表示
在前面的笛卡尔图中,你可以看到一些由点表示的观测值。该图由两个轴组成,这两个轴对应于用于训练 K-Means 聚类机器学习模型的特征。
根据两个特征值的差异,一些观测值比其他观测值更接近。假设我们需要将观测值聚类成三个不同的类别,K-Means 模型被训练出来以找到将观测值划分为不同类别的三个区域。
我们不会在本书中详细介绍 K-Means 聚类算法的所有细节,但我们可以提到一些此类算法适用的用例示例。在现实生活中,我们可以找到许多可以用聚类模型解决的问题,例如以下情况:
-
客户细分:在公司的客户基础上找到相似的客户,以提高营销活动和促销活动的有效性
-
员工细分:识别表现最佳的员工
-
文档分类:根据标签、主题、作者和发布日期将文档聚类到多个类别中
在我们的业务场景中,我们将基于三个不同的聚类:顶级、良好和中性驾驶员,训练一个 K-Means 聚类模型。为了实现我们的目标,我们将使用有关每位出租车驾驶员产生的收入和驾驶速度的信息,驾驶速度是行驶英里数与每次行程花费时间的比率。
我们已经学习了 K-Means 聚类的基础知识,现在是时候看看我们将用于构建机器学习模型的数据集了。
探索和理解数据集
在深入到机器学习实现之前,我们将开始分析用于训练我们的机器学习模型的数据集。
对于这个用例,我们将使用我们在第五章中已经使用过的 BigQuery 公共数据集,使用二元逻辑回归预测布尔值。这个数据集包含了由芝加哥市收集的出租车行程信息,您可以通过以下链接找到:console.cloud.google.com/marketplace/details/city-of-chicago-public-data/chicago-taxi-trips。
让我们先清楚地了解我们数据集中所拥有的信息,以便构建我们的 K-Means 聚类模型。
理解数据
在本节中,我们将探索我们将用于开发我们的 BigQuery ML 模型的数据结构。
要开始探索数据,我们需要做以下几步:
-
登录 GCP,并通过导航菜单访问BigQuery用户界面。
-
在第二章中创建的项目下创建一个新的数据集,设置您的 GCP 和 BigQuery 环境。对于这个用例,我们将创建一个带有默认选项的
07_chicago_taxi_drivers数据集。 -
打开
bigquery-public-dataGCP 项目,该项目托管所有 BigQuery 公共数据集,浏览项目直到找到chicago_taxi_trips数据集。在这个公共数据集中,我们可以看到只有一个 BigQuery 表:taxi_trips。这个表包含了关于在芝加哥市发生的所有出租车行程的信息,我们将使用它来训练和测试我们的 K-Means 聚类模型。
我们已经在第五章中使用了相同的数据,使用二元逻辑回归预测布尔值。因此,我们已经了解了taxi_trips表及其字段的总体架构。
在下面的屏幕截图中,您可以查看属于taxi_trips表的完整字段列表:
图 7.2 – 属于 taxi_trips 表的字段列表
对于此用例,我们关注以下字段,这些字段将用于创建我们的机器学习模型:
-
trip_miles:包含出租车司机在特定行程中行驶的英里数。 -
trip_seconds:表示每次出租车行程的持续时间,以秒为单位。 -
fare:这是乘客支付给出租车司机的费用,代表司机的收入。 -
提示:此列包含出租车司机从乘客那里收到的小费金额。
我们故意忽略与出租车行程成本相关的其他列,例如tolls和extras,因为这些值不会直接受到出租车司机活动的影响。
在本节中,我们已选择了用于训练我们的机器学习模型的表和列。现在,是时候查看数据,以便我们了解如何使用它。
检查数据质量
在本节中,我们在开发我们的机器学习模型之前将应用一些数据质量检查。
数据质量对于构建有效的 K-Means 聚类模型至关重要。由于目标是将观测值聚类到多个类别中,数据中的异常值可以基于数据中的错误值创建不平衡的聚类。
让我们开始分析用于构建我们的机器学习模型的数据集,如下所示:
-
为了确定我们数据集的时间范围,让我们提取
trip_start_timestamp字段的最低值和最高值,如下所示:SELECT MAX(trip_start_timestamp), MIN(trip_start_timestamp) FROM `bigquery-public-data.chicago_taxi_trips.taxi_trips`;在执行此
2013到2020。查询结果如下所示:
图 7.3 – 查询结果显示了数据集的时间范围
为了解决我们的业务场景,我们可以关注发生在
2020年的出租车行程。 -
在第二步中,我们将检查速度(以每小时英里为单位)和出租车司机收入的最高值。让我们执行以下查询:
SELECT MAX (speed_mph), MAX (tot_income) FROM ( SELECT taxi_id, AVG(trip_miles/(trip_seconds/60/60)) AS speed_mph, SUM (fare+tips) AS tot_income FROM `bigquery-public-data.chicago_taxi_trips.taxi_trips` WHERE EXTRACT(YEAR from trip_start_timestamp) = 2020 AND trip_seconds > 0 AND trip_miles >0 AND fare > 0 GROUP BY taxi_id);内部
SELECT语句通过将trip_miles字段的值除以以小时表示的行程持续时间(trip_seconds/60/60)来计算平均速度。计算出的值存储在speed_mph列中。它还创建了tot_income字段,该字段将每个taxi_id字段的fare和tips值相加。使用EXTRACT(YEAR from trip_start_timestamp) = 2020过滤器,我们只选择发生在2020年的出租车行程。在trip_seconds、trip_miles和fare字段上添加过滤器,我们还排除了数据集中可能出现的所有空值和NULL值。最外层的SELECT语句使用MAX (speed_mph), MAX (tot_income)关键字确定平均速度和收入的最高值。查询的结果在以下屏幕截图中进行展示:
图 7.4 – 查询结果显示了速度和收入方面的异常值
从结果来看,很明显,数据集中包含一些与实际用例不兼容的异常值。事实上,最大平均速度约为 667 英里/小时,出租车司机的最高收入超过 100 万美元(USD)。
我们刚刚执行的查询指出,我们的数据集中存在一些不切实际的数据值,需要在接下来的步骤中过滤掉。
现在我们已经对我们的数据集进行了一些质量检查,让我们专注于创建我们的训练数据集。
创建训练数据集
对于 K-Means 聚类,我们只需要创建一个用于训练和测试机器学习模型的训练数据集。
让我们开始创建将用于训练两个不同的 K-Means 聚类模型的训练数据集,如下所示:
-
首先,让我们通过运行以下代码创建一个只包含
speed_mph字段作为 K-Means 聚类模型输入特征的表格:CREATE OR REPLACE TABLE `07_chicago_taxi_drivers.taxi_miles_per_minute` AS SELECT * FROM ( SELECT taxi_id, AVG(trip_miles/(trip_seconds/60/60)) AS speed_mph FROM `bigquery-public-data.chicago_taxi_trips.taxi_trips` WHERE EXTRACT(YEAR from trip_start_timestamp) = 2020 AND trip_seconds > 0 AND trip_miles >0 GROUP BY taxi_id ) WHERE speed_mph BETWEEN 0 AND 50;查询在
07_chicago_taxi_drivers数据集中创建了taxi_miles_per_minute表格。表格包含两个不同的字段:
taxi_id列中的出租车标识符,以及speed_mph字段中的平均速度(以英里/小时表示)。平均速度是使用GROUP BY taxi_id子句为taxi_trips表中的每个taxi_id字段计算的。新表格仅包括 2020 年发生的出租车行程。查询的最后两行包含用于过滤异常值的
WHERE子句。我们假设最大合理的平均速度是50英里/小时。 -
在第二步中,我们将创建另一个表格来存储额外的特征(即
tot_income),如下所示:CREATE OR REPLACE TABLE `07_chicago_taxi_drivers.taxi_speed_and_income` AS SELECT * FROM ( SELECT taxi_id, AVG(trip_miles/(trip_seconds/60/60)) AS speed_mph, SUM (fare+tips) AS tot_income FROM `bigquery-public-data.chicago_taxi_trips.taxi_trips` WHERE EXTRACT(YEAR from trip_start_timestamp) = 2020 AND trip_seconds > 0 AND trip_miles >0 AND fare > 0 GROUP BY taxi_id ) WHERE speed_mph BETWEEN 0 AND 50 AND tot_income BETWEEN 0 AND 150000;查询的执行生成了
taxi_speed_and_income表格。此表格包括使用与步骤 1相同的规则计算的speed_mph字段。表格还包括tot_income字段。此值是每个taxi_id字段和 2020 年整个期间的fare和tips的SUM。与步骤 1中创建的表格相比,我们添加了一个额外的过滤器,将年度
tot_income值限制在 150,000。此第二个表格将用于创建另一个基于两个
speed_mph和tot_income特征的 K-Means 聚类机器学习模型。
现在我们已经创建了我们的 BigQuery ML 模型将要训练的表格,让我们深入到机器学习模型的创建中。
训练 K-Means 聚类模型
在本节中,我们将创建两个不同的 K-Means 机器学习模型。第一个模型将使用 taxi_miles_per_minute 作为训练数据集,而第二个模型将包括 tot_income 作为特征,并利用 taxi_speed_and_income。让我们按以下步骤进行:
-
作为第一步,让我们通过运行以下代码开始训练一个名为
clustering_by_speed的机器学习模型:CREATE OR REPLACE MODEL `07_chicago_taxi_drivers.clustering_by_speed` OPTIONS(model_type='kmeans', num_clusters=3, kmeans_init_method = 'KMEANS++') AS SELECT * EXCEPT (taxi_id) FROM `07_chicago_taxi_drivers.taxi_miles_per_minute`;SQL 语句的前几行由
CREATE OR REPLACE MODEL关键字组成,后跟07_chicago_taxi_drivers.clustering_by_speed机器学习模型的标识符和OPTIONS子句。现在,让我们看看我们用来训练机器学习模型的选项。选定的模型类型是
'kmeans'。此选项描述了我们用于训练模型的技术。num_clusters选项的值为3,因为我们试图将观测值分类到三个不同的簇中:Top、Good 和 Neutral。默认情况下,BigQuery ML 使用随机起点开始训练 K-Means 聚类算法。机器学习模型的质量也取决于这一点,这一点是由 BigQuery 随机选择的。通过使用
kmeans_init_method = 'KMEANS++'选项,该点利用taxi_miles_per_minute表初始化,除了taxi_id列,该列仅在预测阶段使用。 -
在第一个机器学习模型训练完成后,让我们再训练第二个模型,该模型还包括出租车司机在该年的
tot_income值,如下面的代码片段所示:CREATE OR REPLACE MODEL `07_chicago_taxi_drivers.clustering_by_speed_and_income` OPTIONS(model_type='kmeans', num_clusters=3, standardize_features = true, kmeans_init_method = 'KMEANS++') AS SELECT * EXCEPT (taxi_id) FROM `07_chicago_taxi_drivers.taxi_speed_and_income`;这个查询与用于创建先前 K-Means 聚类模型的 SQL 语句非常相似,但我们立即可以注意到一个相关的差异。
clustering_by_speed_and_income模型是使用一个额外的选项standardize_features = true训练的。当您有不同数量级的数值特征时,此选项特别有用。在这种情况下,模型正在使用speed_mph字段(从 0 到 50)和tot_income字段,其值可以达到 150,000。
现在我们已经基于 K-Means 聚类算法训练了两个不同的机器学习模型,让我们看看如何利用 BigQuery ML SQL 语法和 BigQuery 用户界面(UI)来评估它们。
评估 K-Means 聚类模型
在本节中,我们将学习如何评估我们的 K-Means 聚类模型性能。
K-Means 聚类模型的评估阶段与我们之前章节中执行的监督机器学习模型不同。让我们看看评估我们的机器学习模型需要采取的步骤,如下所示:
-
让我们通过运行以下代码提取上一节中训练的第一个机器学习模型的质心:
SELECT * FROM ML.CENTROIDS (MODEL `07_chicago_taxi_drivers.clustering_by_speed`) ORDER BY centroid_id;ML.CENTROIDS函数返回 K-Means 模型质心的信息。它接受模型名称作为输入,放在圆括号内,前面是MODEL关键字。重要提示
质心代表 K-Means 聚类模型中一个集群的中心。在机器学习模型的训练阶段,质心会迭代优化以最小化质心与训练数据集中观测值之间的距离。当训练阶段结束时,质心会稳定下来。BigQuery ML 在相对损失改进小于
MIN_REL_PROGRESS参数指定的值时停止迭代。查询的执行返回三个质心,如下截图所示:
图 7.5 – 查询结果显示机器学习模型识别的质心
在这种情况下,每个质心仅用代表出租车驾驶员平均速度的
speed_mph特征的数值来表示。 -
可以通过 BigQuery UI 获取相同的信息。从 BigQuery 导航菜单中选择
clustering_by_speed模型,访问1属于第一个集群,代表平均速度最佳的出租车驾驶员:顶级驾驶员。从 BigQuery UI,我们还可以注意到 869 名出租车驾驶员属于这个集群。第二个质心包括大部分人口,
speed_mph值为 14.3222。这个质心是良好驾驶员集群的中心。最后一个质心是速度最慢的驾驶员所在集群的中心,包含 425 个观测值,属于中性驾驶员集群。
-
如果我们选择从 BigQuery UI 的评估标签页分析
clustering_by_speed_and_income模型,我们将看到以下信息:
图 7.7 – 基于速度和收入的聚类 BigQuery ML 模型的评估标签页
观察由第二个模型识别的集群和质心,我们可以立即注意到集群基于两个不同的特征:speed_mph和tot_income。
第一个集群,编号为1,包括速度和年收入最佳的 466 名驾驶员:顶级驾驶员。第二个集群包含表现最差的 417 名中性驾驶员。最后一个质心包括大多数驾驶员,是良好驾驶员集群。
小贴士
训练不同迭代的 K-Means 聚类可以生成不同的值,这取决于 BigQuery ML 使用的初始化种子。可能发生的情况是质心的位置与本节中显示的值不同。
现在我们已经查看了 K-Means 聚类模型训练产生的结果,让我们开始使用它们将出租车司机分类到不同的聚类中。
使用 K-Means 聚类模型
在本节中,我们将了解如何在新数据上使用我们的 K-Means 聚类模型。
要使用我们的 BigQuery ML 模型,我们将在创建用于训练机器学习模型的同一张表上使用ML.PREDICT函数。
在这种情况下,我们还将包括taxi_id列,该列标识每个出租车司机。以下查询将根据speed_mph和tot_income字段的值将每个taxi_id字段分类到最近的聚类:
SELECT
* EXCEPT(nearest_centroids_distance)
FROM
ML.PREDICT( MODEL `07_chicago_taxi_drivers.clustering_by_speed_and_income`,
(
SELECT *
FROM
`07_chicago_taxi_drivers.taxi_speed_and_income`
));
查询语句由一个SELECT关键字组成,该关键字提取了ML.PREDICT函数返回的所有列,除了nearest_centroids_distance字段。
查询的执行生成了以下屏幕截图所示的结果:
![图 7.8 – 查询结果展示了 K-Means 聚类模型的应用
![img/B16722_07_009.jpg]
图 7.8 – 查询结果展示了 K-Means 聚类模型的应用
每个taxi_id字段被分配到一个特定的质心及其对应的聚类。分配从第一列CENTROID_ID中可见。
现在我们已经应用了我们的模型,让我们制定一些最终考虑事项,并提供一份可以奖励的出租车司机名单,因为他们属于顶级司机聚类。
提炼业务结论
在本节中,我们将使用我们机器学习模型应用的结果制定一些最终考虑事项。
使用使用 K-Means 聚类模型部分中执行的查询,我们可以创建一个包含由clustering_by_speed_and_income K-Means 机器学习模型识别的顶级司机的表,如下所示:
CREATE OR REPLACE TABLE `07_chicago_taxi_drivers.top_taxi_drivers_by_speed_and_income` AS
SELECT
* EXCEPT(nearest_centroids_distance)
FROM
ML.PREDICT( MODEL `07_chicago_taxi_drivers.clustering_by_speed_and_income`,
(
SELECT *
FROM
`07_chicago_taxi_drivers.taxi_speed_and_income`
))
WHERE CENTROID_ID=1;
查询的执行生成一个包含所有被分类到CENTROID_ID=1聚类并对应于顶级司机聚类的司机的top_taxi_drivers_by_speed_and_income表。请注意,K-Means 聚类算法并不总是返回相同的分割。因此,CENTROID_ID=1的子句可以根据每个训练阶段生成的结果而变化。
此结果集包括应奖励其表现的出租车司机的标识符。
摘要
在本章中,我们构建了我们的无监督机器学习模型。在简要介绍业务场景后,我们发现了无监督机器学习是什么,并使用 K-Means 聚类算法将相似观察结果分组到同一聚类中。
在深入开发机器学习模型之前,我们对数据集进行了数据质量检查,并选择了用作机器学习模型特征的字段。
在训练阶段,我们训练了两个不同的机器学习模型,以学习如何创建 K-Means 聚类模型。
然后,我们评估了两个模型,利用 BigQuery ML SQL 语法和 BigQuery UI 中可用的功能。
在最后一步,我们测试了我们的机器学习模型,根据数据集中的特征将可用的出租车驾驶员聚类到由 K-Means 模型生成的聚类中。
最后,我们还创建了一个属于 Top Drivers 聚类的驾驶员列表,这些驾驶员可以受到奖励,因为他们可以被认为是与其他驾驶员平均水平的顶尖表现者。
在下一章中,我们将介绍使用时间序列数据进行预测。
更多资源
-
芝加哥出租车行程公共数据集:
console.cloud.google.com/marketplace/details/city-of-chicago-public-data/chicago-taxi-trips -
芝加哥开放数据:
data.cityofchicago.org/ -
CREATE MODEL语句:cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-create -
ML.EVALUATE函数:cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-evaluate -
ML.PREDICT函数:cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-predict -
BigQuery ML K-Means 聚类示例:
cloud.google.com/bigquery-ml/docs/kmeans-tutorial
第八章:使用时间序列进行预测
使用历史数据预测未来趋势是我们可以用机器学习做的最迷人的活动之一。
基于历史数据点和时间序列进行预测特别有趣,并且可以在不同行业中非常有用。预测可以帮助我们预测未来,也可以帮助我们识别不遵守预期模式的数据异常。
在本章中,我们将通过使用 ARIMA Plus 算法来专注于时间序列预测。这项技术可以用于预测不同领域的数值,例如公司的销售额、餐厅的顾客数量、股票价格和建筑的电力消耗。
要了解我们如何使用 BigQuery ML 来预测趋势以及有效地展示我们的结果,我们将讨论以下主题:
-
介绍业务场景
-
发现时间序列预测
-
探索和理解数据集
-
训练时间序列预测模型
-
评估时间序列预测模型
-
使用时间序列预测模型
-
展示预测结果
技术要求
本章要求你访问网络浏览器,并能够利用以下功能:
-
一个 GCP 账户以访问 Google Cloud Console
-
一个 GCP 项目来托管 BigQuery 数据集
现在,我们已经准备好了技术要求,让我们深入分析和开发我们的 BigQuery ML 预测模型。
查看以下视频以查看代码的实际应用:bit.ly/2QY0Qlp
介绍业务场景
想象一下你是一名为爱荷华州工作的商业分析师。该州通过收集领土内每个商店的数据来监控酒类和烈酒的零售分销。控制酒类销售对于监控公民健康和检查税收收入尤为重要。
在下面的屏幕截图中,你可以看到一家商店中典型的酒类和烈酒货架的图片:
图 8.1 – 酒店货架
对于我们的业务场景,我们可以想象爱荷华州想要利用前几年收集的历史数据来预测 2020 年前 30 天将售出的升数。
你的经理可能会要求你利用数据库中已经收集的时间序列数据来预测该州所有商店将售出的升数。
作为一名商业分析师,你的任务是找到最佳的算法来预测销售量,并以图形方式向州长的工作人员展示结果。
现在我们已经解释并理解了问题陈述,让我们看看我们可以用来使用历史数据预测销售的机器学习技术。
发现时间序列预测
时间序列是一系列按一定时间频率映射的数据点。例如,它可以包含定期收集的股票价格,特定时间段内每天的销售量,或物联网(IoT)传感器在白天测量的温度。
在以下图中,您可以看到 2020 年前 15 天由温度传感器收集的数据的时间序列图:
图 8.2 – 温度传感器生成的时间序列示例
使用时间序列分析进行预测包括使用机器学习模型通过利用已知的历史数据来预测特定测量的未来值。
BigQuery ML 提供了一种特定的机器学习算法,用于使用时间序列数据预测数值。该算法旨在执行以下操作:
-
自动清理和调整训练数据以克服数据质量问题,例如缺失或重复的值和峰值。
-
补偿由特定时期(如节假日)引起的变异。
-
使用季节性和趋势分解 Loess 算法分解趋势。
-
从数据中推断季节性。
-
最后,应用自回归积分移动平均(ARIMA)模型的趋势建模,使用历史数据预测未来的数值。
您可以使用 ARIMA 模型来发现时间序列数据中的隐藏模式或预测特定测量的未来值。
在本节中,我们学习了时间序列预测的基础知识。现在让我们看看我们将用于构建 BigQuery ML 模型的数据集。
探索和理解数据集
在开始开发机器学习模型之前,我们将开始查看数据集及其结构。
让我们从对 BigQuery 公共数据集中我们拥有的时间序列数据进行清晰理解开始,以便在下一节构建我们的预测模型。
理解数据
在本节中,我们将分析数据的结构以确定用于创建机器学习模型的字段。
要开始探索数据,我们需要做以下几步:
-
登录我们的 Google Cloud 控制台,并通过导航菜单访问BigQuery用户界面。
-
在我们创建的第二章,“设置您的 GCP 和 BigQuery 环境”中创建一个新的数据集。对于此用例,我们将使用默认选项创建名为
08_sales_forecasting的数据集。 -
打开 GCP 项目
iowa_liquor_sales。如以下截图所示,BigQuery 公共数据集仅包含一个表,该表托管了爱荷华州酒类商店收集的数据:
图 8.3 – 爱荷华州酒类销售公共数据集包含爱荷华州所有酒类商店的销售数据
我们将使用sales表来构建我们的预测模型。这个表包含了自 2012 年以来爱荷华州州内所有酒类销售的信息。
-
让我们点击 BigQuery 导航菜单中的表名sales以访问表的模式:
图 8.4 – 表的结构列出了表中收集的所有信息
-
每个字段都在描述列中有很好的描述。
表包含date列,它代表销售的日子。为了我们的目的,我们将尝试预测特定一天销售的总体积。因此,我们可以注意到volume_sold_liters字段的 presence。这个数值字段表示每次交易中销售的酒类数量。
在本节中,我们已经分析了sales表的元数据,并了解了哪些字段对我们构建预测模型感兴趣。接下来,是时候查看实际数据并开始查询了。
检查数据质量
在本节中,我们将应用一些数据质量检查来分析我们的训练数据集的完整性。
让我们开始分析将要用于构建我们的 BigQuery ML 模型的表格:
-
为了确定数据集的时间范围,让我们从
bigquery-public-data.iowa_liquor_sales.sales表提取date字段的最低值和最高值:SELECT min(date), max(date) FROM `bigquery-public-data.iowa_liquor_sales.sales`;通过执行这个 SQL 语句,我们可以注意到数据从 2012 年开始,到 2020 年 11 月底结束。
查询结果如下所示:
图 8.5 – 查询结果显示数据集的时间范围
为了我们的目的,我们可以专注于 2018 年和 2019 年的销售,以预测 2020 年最初的 30 天。
-
在第二步中,我们将分析在选定时间段内可以找到的唯一日期数量:
SELECT COUNT(DISTINCT date) FROM `bigquery-public-data.iowa_liquor_sales.sales` WHERE EXTRACT (year from date) = 2019 OR EXTRACT (year from date) = 2018;查询
COUNT和字段date中可用的DISTINCT值。使用表达式EXTRACT (year from date),SQL 语句仅考虑发生在2018年和2019年的销售。查询结果如下所示:
图 8.6 – 查询结果显示数据集中的唯一日期
从结果来看,数据集不包含两年中每一天的信息。这可能是由于公共假日和商店关闭导致的缺失值造成的。这不是一个大问题,因为 BigQuery ML 将在训练阶段自动管理缺失值。
现在我们已经执行了一些 SQL 查询以更好地了解我们的数据集,让我们专注于创建我们的训练数据集。
创建训练数据集
在本节中,我们将创建一个表格来存储将在下一节中用于训练预测模型的数据点。在训练模型之前,我们还将使用数据工作室来图形化分析时间序列。
为了训练我们的模型,我们将创建一个特定的表格,该表格将托管我们时间序列的历史数据点:
-
让我们创建一个只包含两个字段的表格。第一个是
date,第二个是total_sold_liters:CREATE OR REPLACE TABLE `08_sales_forecasting.iowa_liquor_sales` AS SELECT date, SUM(volume_sold_liters) total_sold_liters FROM `bigquery-public-data.iowa_liquor_sales.sales` WHERE EXTRACT (year from date) = 2019 OR EXTRACT (year from date) = 2018 GROUP BY date;该查询在数据集
08_sales_forecasting中创建表iowa_liquor_sales。该表包含两个不同的字段:
date列表示交易发生的时间,第二个字段是计算一天内销售的酒类数量的SUM。total_sold_liters是一个基于GROUP BY date子句的聚合值,并且对于2018年和2019年的每一天。 -
第二步将是图形化分析存储在
iowa_liquor_sales表中的数据。如以下截图所示,从左侧的大查询导航菜单中,让我们选择数据集
08_sales_forecasting然后选择表iowa_liquor_sales:![图 8.7 – 训练表 iowa_liquor_sales 在 BigQuery 导航菜单中可见
![img/B16722_08_007.jpg]
图 8.7 – 训练表 iowa_liquor_sales 在 BigQuery 导航菜单中可见
-
之后,让我们点击导出然后点击使用数据工作室探索,如下截图所示:![图 8.8 – 从 BigQuery 中,可以打开数据工作室
![img/B16722_08_008.jpg]
图 8.8 – 从 BigQuery 中,可以打开数据工作室
数据工作室是由 Google 提供的一个免费数据可视化工具,与 BigQuery 原生集成,可以轻松用于在报告和图表中绘制数据。
-
在数据工作室中,我们可以选择时间序列图表作为图表类型,如下截图所示:![图 8.9 – 在数据工作室中,可以选择时间序列图表来可视化数据
![img/B16722_08_009.jpg]
图 8.9 – 在数据工作室中,可以选择时间序列图表来可视化数据
-
然后,我们可以选择日期字段作为维度,以及总销售升数作为度量,如下截图所示:![图 8.10 – 在数据工作室中,可以选择维度和度量设置来绘制图表
![img/B16722_08_010.jpg]
图 8.10 – 在数据工作室中,可以选择维度和度量设置来绘制图表
-
之后,我们可以转到样式选项卡,并在缺失数据组合框中选择线性插值:![图 8.11 – 线性插值选项允许改善可视化
的图表在缺失值的情况下
![img/B16722_08_011.jpg]
图 8.11 – 线性插值选项允许在存在缺失值的情况下改善图表的可视化
-
在这些配置之后,我们可以可视化 Data Studio 绘制的图表,该图表表示所选期间销售的酒类数量的趋势线:
图 8.12 – 时间序列以图表上的蓝色线条在 Data Studio 中显示
现在我们已经创建了我们的预测模型将进行训练和可视化的表,并在图表中显示了数据,让我们深入了解机器学习模型的创建。
训练时间序列预测模型
在本节中,我们将训练 BigQuery ML 时间序列预测模型。
让我们开始训练机器学习模型 liquor_forecasting,执行以下 SQL 语句:
CREATE OR REPLACE MODEL `08_sales_forecasting.liquor_forecasting`
OPTIONS
(model_type = 'ARIMA',
time_series_timestamp_col = 'date',
time_series_data_col = 'total_sold_liters',
auto_arima = TRUE,
data_frequency = 'AUTO_FREQUENCY'
) AS
SELECT *
FROM
`08_sales_forecasting.iowa_liquor_sales`;
SQL 语句由以下部分组成:
-
查询的前几行以关键字
CREATE OR REPLACE MODEL开头,后面跟着机器学习模型的标识符`08_sales_forecasting.liquor_forecasting`,以及OPTIONS。 -
现在,让我们专注于我们用来训练机器学习模型的选项。选定的模型类型是
'ARIMA'。此选项描述了我们用来训练 BigQuery ML 预测模型的算法。 -
time_series_timestamp_col = 'date'指定了用于在时间序列中存储数据点时间的列。 -
下一个选项选择
total_sold_liters列作为存储每个数据点值的列,并由子句time_series_data_col = 'total_sold_liters'表示。 -
属性
auto_arima设置为TRUE,允许 BigQuery ML 自动识别模型的参数p、d和q。 -
最后一个参数
'AUTO_FREQUENCY',BigQuery 自动推断时间序列的频率。在这种情况下,频率是每日的。其他选项有'HOURLY'、'DAILY'、'WEEKLY'、'MONTHLY'、'QUARTERLY'和'YEARLY'。 -
SQL 语句的最后部分由对训练表
iowa_liquor_sales应用SELECT语句组成。
现在我们已经基于 ARIMA 算法训练了时间序列预测模型,让我们看看如何使用 BigQuery ML 语法和 BigQuery UI 来评估它。
评估时间序列预测模型
在本节中,我们将评估我们在前一节中训练的机器学习模型的性能。
时间序列模型的评估阶段可以通过使用 ML.EVALUATE BigQuery ML 函数来完成。
让我们执行以下查询以提取所有表征 ARIMA 模型的评估参数:
SELECT *
FROM
ML.EVALUATE(MODEL `08_sales_forecasting.liquor_forecasting`);
查询的结果在以下屏幕截图中进行了可视化:
图 8.13 – 从时间序列预测模型评估中提取的记录
每一行定义了一个被分类为 ARIMA(p,d,q) 模型的非季节性 ARIMA 模型。对于每一行,我们可以注意到以下内容:
-
字段 non_seasonal_p 代表 ARIMA 模型的参数 p。行值是用于预测的自回归项的数量。它表示用于预测时间序列下一个值的观测值数量。
-
字段 non_seasonal_d 代表 ARIMA 模型的参数 d。行值表示需要将一个数据点与前一个数据点之间的差值应用多少次,以减轻数据集的季节性。
-
non_seasonal_q 代表 ARIMA 模型的参数 q。它表示用于预测时间序列下一个值的移动平均数所计算的观测值数量。
-
has_drift 显示是否对模型应用了漂移常数。
-
log_likelihood 是一个参数,用于衡量统计模型与特定数据集的拟合程度。
-
AIC 代表 Akaike 信息准则。此值用于评估模型的好坏。AIC 的值越低,通常越好。因此,我们可以认为第一个模型是最好的。
-
variance 衡量数据点与序列平均值之间的距离。
-
seasonal_periods 列表示我们数据中的季节性模式。在这种情况下,BigQuery ML 已经在销售时间序列中识别出 WEEKLY 和 YEARLY 模式。
现在我们已经介绍了我们时间序列预测模型的性能指标,让我们尝试使用它来预测 2020 年前 30 天的数据。
使用时间序列预测模型
要使用我们的 BigQuery ML 模型,我们将使用 ML.FORECAST 函数来指定预测的参数。
查询将提取由接受以下参数的预测函数生成的所有字段:
-
模型名称
08_sales_forecasting.liquor_forecasting,前面有MODEL关键字。 -
一个包含预测的
horizon:30天和选择的confidence_level– 在这种情况下,80% 的STRUCT:SELECT * FROM ML.FORECAST(MODEL `08_sales_forecasting.liquor_forecasting`, STRUCT(30 AS horizon, 0.8 AS confidence_level));
查询的执行将生成以下屏幕截图所示的记录:
图 8.14 – 预测函数生成的结果
我们可以在 图 8.14 中注意到,预测是按照 confidence_level 字段中的日期按时间顺序排列的。值为 0.8 表示 80% 的预测值应落在由字段 prediction_interval_lower_bound 和 prediction_interval_upper_bound 确定的预测区间内。
现在我们已经应用了我们的模型,让我们了解如何有效地使用 Data Studio 展示结果。
展示预测结果
在本节中,我们将使用数据工作室创建一个时间序列图,以便图形化地展示预测结果。
使用以下查询,我们可以创建一个包含历史值和预测值的表格:
CREATE OR REPLACE TABLE `08_sales_forecasting.iowa_liquor_sales_forecast` AS
SELECT
history_date AS date,
history_value,
NULL AS forecast_value,
NULL AS prediction_interval_lower_bound,
NULL AS prediction_interval_upper_bound
FROM
(
SELECT
date AS history_date,
total_sold_liters AS history_value
FROM
`08_sales_forecasting.iowa_liquor_sales`
)
UNION ALL
SELECT
CAST(forecast_timestamp AS DATE) AS date,
NULL AS history_value,
forecast_value,
prediction_interval_lower_bound,
prediction_interval_upper_bound
FROM
ML.FORECAST(MODEL `08_sales_forecasting.liquor_forecasting`,
STRUCT(30 AS horizon, 0.8 AS confidence_level));
执行 SQL 语句生成iowa_liquor_sales_forecast表,该表由以下内容组成:
-
所有记录都来自训练表
iowa_liquor_sales,我们从其中提取了时间序列的history_date和history_value。我们还添加了一些NULL字段,以通过查询的第二部分与UNION ALL分隔的标准模式。 -
由
ML.FORECAST函数生成的所有预测记录已在上一节使用时间序列预测模型中应用。特别值得注意的是,我们不仅提取了forecast_value,还提取了预测的下限和上限,分别由字段prediction_interval_lower_bound和prediction_interval_upper_bound表示。 -
存在
CAST函数,应用于forecast_timestamp列,这是必要的,以便根据训练表的模式将数据类型从TIMESTAMP更改为DATE。
正如我们在创建训练数据集部分所做的那样,我们现在可以执行以下操作:
-
从 BigQuery 导航菜单中选择我们刚刚创建的
iowa_liquor_sales_forecast表。 -
点击导出然后使用数据工作室探索以访问报告工具。
-
从图表面板中选择时间序列图表。
-
按照以下截图所示,将历史值、预测值、预测区间下限和预测区间上限拖放到指标面板中:
图 8.15 – 数据面板允许我们自定义图表的指标
-
移动到样式面板,向下滚动直到找到缺失数据部分。在这里,我们选择线性插值。
-
然后,在屏幕顶部,我们可以对日期列应用过滤器,以便我们的图表仅关注从 2019 年 12 月 1 日到 2020 年 1 月 30 日的期间:
图 8.16 – 在日期列上应用过滤器
-
点击应用,图表最终将如图所示可视化:![图 8.15 – 数据面板允许我们自定义图表的指标
图 8.17 – 数据工作室中的时间序列图表
观察图表的图例,我们可以通过不同的颜色可视化历史值和预测值。我们还可以注意到,预测值线始终包含在预测区间内。
摘要
在本章中,我们构建了我们的时间序列预测机器学习模型。在介绍业务场景之后,我们发现了时间序列预测是什么,特别是用于从历史数据点预测值的 ARIMA 算法。
在深入开发 BigQuery ML 模型之前,我们对爱荷华州收集的与该地区商店酒类销售相关的数据进行了分析。为此,我们引入了报告工具 Data Studio 的使用,它可以通过 BigQuery UI 容易地访问,并利用它绘制时间序列图表。
然后,我们创建了我们的训练表,其中包含历史数据的时间序列,并在其上训练了我们的 BigQuery ML 模型。然后,我们通过利用 BigQuery ML SQL 语法评估了时间序列预测模型。
在最后一步,我们使用 30 天的预测范围预测了爱荷华州销售的酒类数量,并在 Data Studio 仪表板上绘制了结果,该仪表板可以向非技术人员展示。
在下一章中,我们将介绍矩阵分解算法来构建推荐引擎。
进一步资源
-
爱荷华州酒类零售销售公共数据集:
console.cloud.google.com/marketplace/product/iowa-department-of-commerce/iowa-liquor-sales -
BigQuery ML 创建模型:
cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-create -
BigQuery ML 评估模型:
cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-evaluate -
BigQuery ML 预测:
cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-forecast -
BigQuery ML 时间序列预测示例:
cloud.google.com/bigquery-ml/docs/arima-single-timeseries-forecasting-tutorial
第九章:通过矩阵分解建议合适的产品
建议合适的产品是机器学习(ML)最常见应用之一。每天,产品推荐系统影响着我们在互联网上的选择。新闻通讯、电子商务网站、视频流媒体公司以及许多其他服务利用这种强大的 ML 技术,为我们提供有关可能购买或喜欢的产品的有意义建议。
在本章中,我们将以实际操作和实用性的方法,执行构建新推荐引擎的主要实现步骤,该引擎使用矩阵分解算法。
通过逐步和增量方法,利用 BigQuery ML,我们将涵盖以下主题:
-
介绍业务场景
-
发现矩阵分解
-
配置 BigQuery Flex Slots
-
探索和准备数据集
-
训练矩阵分解模型
-
评估矩阵分解模型
-
使用矩阵分解模型
-
提出业务结论
技术要求
本章要求您能够访问网络浏览器,并利用以下资源:
-
一个 GCP 账户来访问 Google Cloud 控制台。
-
一个 GCP 项目来托管 BigQuery 数据集。
-
BigQuery Flex slots 用于在 BigQuery ML 中训练矩阵分解模型。这类算法的训练仅适用于固定价格客户或预留客户。如果您使用的是按需定价的 BigQuery,我们将向您展示如何使用 BigQuery Flex Slots。
现在技术要求已经明确,让我们看看关于 BigQuery ML 矩阵分解模型的使用案例。
介绍业务场景
想象一下,你是一名为 Google 商品电子商务店工作的商业分析师。该网站向不同用户销售不同的谷歌品牌产品。一些用户已注册并有自己的标识符,他们的点击流活动收集在特定的数据集中。
重要提示
点击流数据是用户在特定网站上导航时留下的数字足迹。这些数据通常包括他们访问的网页、在每个页面上花费的时间、使用的设备、流量来源以及其他相关信息。
在这个场景中,数据是通过 Google 从 Google 商品电子商务门户使用Google Analytics 360收集的。这个工具可以集成到任何网站,并允许我们收集有关门户中每个页面上用户行为的详细信息,以便进行进一步分析和分析。
以下截图是 Google 商品店,该店销售谷歌品牌的设备:
图 9.1 – Google 商品店的截图
对于我们的业务场景,我们将设想我们的经理要求我们构建一个新的推荐引擎,以提高客户的使用体验以及他们的电子商务销售额。
我们的目标是开发一个机器学习模型,为在网站上注册的每位客户推荐合适的产品。为了实现这一目标,我们将使用已经收集并发布在 BigQuery 公共数据集中的 Google 商品店点击流数据。
作为业务分析师,我们的工作是分析数据,构建一个有效的推荐引擎,并使用现有数据向营销团队提供有意义的见解。
现在我们已经解释并理解了业务场景,让我们来看看我们将用于构建电子商务门户推荐引擎的机器学习技术。
发现矩阵分解
在本节中,我们将学习什么是矩阵分解,以及它是如何被用来构建推荐引擎的。
矩阵分解代表了一类通常用于构建推荐引擎的算法。这些算法建立在表示用户和项目之间交互的矩阵上。在这些类型的矩阵中,以下情况会发生:
-
每个用户或客户都由一行表示。
-
每个项目或产品对应于矩阵的一列。
-
矩阵的每个单元格都填充了一个数值:反馈。
这种反馈代表了一个特定用户对特定项目的评分。
在下面的屏幕截图中,我们可以看到一个矩阵的例子,其中行是视频流服务的客户,列是平台提供的电影。一些单元格包含一个从1到5的评分:
![图 9.2 – 推荐矩阵的表示
![img/B16722_09_002.jpg]
图 9.2 – 推荐矩阵的表示
在这个例子中,我们可以说用户 1对电影闪灵给出了平均评分,但对泰坦尼克号不喜欢。另一方面,用户 4对泰坦尼克号给出了最高评分,但没有对其他电影进行评分。
根据不同的业务场景,这种反馈可以被考虑为明确的或隐式的:
-
当用户自愿对特定项目进行评分时,例如在评论网站上,就有明确的反馈。
-
如果没有明确的反馈,推荐系统的开发者可以通过隐式反馈进行计算和推断。例如,如果客户购买了一个产品,我们可以假设他们会为该商品给出积极的反馈。
在电子商务数据中,用户往往不会明确给出反馈,但可以从收集过程中的其他信息中提取,例如点击次数、在特定页面上的时间或用户购买特定产品的数量。
矩阵分解算法在现实场景中得到广泛应用。以下是一些例子:
-
在在线书店中看到的推荐书籍。
-
我们可以在视频流服务中看到的推荐电视剧。
-
在我们的社交媒体动态中突出显示的帖子。
-
互联网广告系统推荐的商品。
在本节中,我们学习了矩阵分解的基础知识。现在,让我们配置 BigQuery Flex 槽位。
配置 BigQuery Flex 槽位
在本章中,我们将了解如何配置 BigQuery Flex 槽位以训练我们的机器学习模型。
BigQuery 槽位是 BigQuery 分析能力的单位,用于执行 SQL 查询和训练 BigQuery ML 模型。一个 BigQuery 槽位代表一个虚拟计算处理单元(VCPU)的计算能力。
Flex 槽位允许我们在短时间内购买 BigQuery 分析能力。它们通常用于快速满足至少持续 60 秒的资源突发需求。
启用 Flex 槽位是训练矩阵分解模型所必需的;否则,BigQuery 将在训练阶段返回错误。
让我们看看如果我们使用按需计划,我们如何启用 BigQuery Flex 槽位:
-
如果您尚未启用 BigQuery 预订,我们需要从左侧的 BigQuery 菜单访问预订:
图 9.3 – 从 BigQuery 导航菜单访问预订
-
点击购买槽位按钮以初始化 BigQuery Flex 槽位的购买过程:
图 9.4 – 预订页面截图
-
选择要购买的 Flex 槽位的最小数量;即100。然后,点击下一步按钮:
图 9.5 – BigQuery 购买槽位过程
-
在确认文本框中写下CONFIRM并点击蓝色购买按钮来确认您的选择:
图 9.6 – 确认您的 BigQuery 槽位购买
-
一旦确认购买,您就可以切换到分配选项卡来分配您刚刚购买的预订。
-
在分配选项卡上,在第一个下拉菜单中选择您的 GCP 项目,在第二个下拉菜单中选择 Flex 槽位的预订。然后,点击创建按钮以完成您的配置:
图 9.7 – 分配 BigQuery 槽位
-
当分配完成时,我们可以返回 BigQuery 主页。
重要提示
警告:请记住在本用例结束时禁用 BigQuery 槽位的预订。每个 BigQuery 槽位每小时收费 0.04 美元。忘记禁用此预订将为您的 GCP 项目产生意外的账单。
在本节中,我们学习了如何购买 BigQuery Flex Slots 以便我们可以使用矩阵分解。现在,我们将专注于数据探索和准备步骤。
探索和准备数据集
在本节中,我们将分析我们将用于训练 BigQuery ML 模型的数据,并应用数据准备步骤。
让我们先清楚地了解 BigQuery 公共数据集中可用的 Google Analytics 数据,以便我们可以构建我们的推荐系统。
理解数据
在本节中,我们将导入必要的数据,然后理解数据集中将用于训练 BigQuery ML 模型的最相关字段。
在我们开始开发机器学习模型之前,我们将查看数据集及其模式。要开始探索数据集,我们需要执行以下操作:
-
登录我们的 Google Cloud Console,并通过导航菜单访问 BigQuery 用户界面。
-
在我们创建的项目下创建一个新的数据集,该项目位于 第二章,设置您的 GCP 和 BigQuery 环境。对于此用例,我们将使用默认选项创建
09_recommendation_engine数据集。 -
之后,我们需要打开托管 BigQuery 公共数据集的
bigquery-public-dataGCP 项目,并浏览数据集,直到我们找到google_analytics_sample。 -
BigQuery 公共数据集包含多个表,这些表托管着 Google Analytics 示例数据。每个表根据它所引用的年份和月份展示不同的后缀:![图 9.8 – 包含 ga_sessions 表的 Google Analytics 示例数据集
图 9.8 – 包含 ga_sessions 表的 Google Analytics 示例数据集
我们将使用 ga_sessions 表来构建我们的矩阵分解模型。
小贴士
ga_sessions 表没有很好地描述,但如果我们需要关于这个数据集的更多信息,我们可以利用 BigQuery 文档中提供的示例,文档链接为
support.google.com/analytics/answer/4419694?hl=en。 -
为了简化数据访问过程,让我们创建一个统一的单一表,将所有具有不同后缀的表合并在一起。让我们执行以下 SQL 语句:
CREATE OR REPLACE TABLE `09_recommendation_engine.all_ga_sessions` AS SELECT * FROM `bigquery-public-data.google_analytics_sample.ga_sessions_*`;查询创建了一个名为
all_ga_sessions的新表,位于我们的09_recommendation_engine数据集中。此表将来自不同ga_sessions表的所有数据存储到一个独特的结构中。为了统一所有记录,我们使用了通配符字符,*。小贴士
将
ga_sessions_*表放入我们的新结构all_ga_sessions中。 -
现在,我们可以简单地查询
all_ga_sessions以预览其架构:SELECT * FROM `09_recommendation_engine.all_ga_sessions` TABLESAMPLE SYSTEM (10 PERCENT);查询结果指出,表的架构相当复杂,包含多个嵌套字段。幸运的是,为了我们的目的,我们只需关注其中的一些:
fullVisitorID代表每个浏览谷歌网站的注册用户的标识符。productSku是识别 Google 目录中特定产品的产品代码。一些产品的示例包括杯子、T 恤、包和袜子。action_type列表示用户在网页会话期间执行的操作。如果此字段等于6,则该行表示客户购买的具体产品。
既然我们已经确定了哪些列将用于我们的 ML 模型,现在是时候准备我们的训练数据集了。
创建训练数据集
在本节中,我们将创建将托管我们 BigQuery ML 模型训练数据的表。
为了训练我们的模型,我们将创建一个表,该表将托管网站上注册客户所进行的所有购买。
让我们创建包含三个字段的 product_purchases 表:
-
每个用户的代码:
fullVisitorId -
购买产品的标识符:
purchased_product_id -
quantity字段,指定客户购买的产品数量
执行以下 SQL 语句以创建表:
CREATE OR REPLACE TABLE `09_recommendation_engine.product_purchases` AS
SELECT fullVisitorId,
hits_product.productSKU AS purchased_product_id,
COUNT(hits_product.productSKU) AS quantity
FROM
`09_recommendation_engine.all_ga_sessions`,
UNNEST(hits) AS hits,
UNNEST(hits.product) AS hits_product
WHERE fullVisitorId IN (
SELECT fullVisitorId
FROM
`09_recommendation_engine.all_ga_sessions`,
UNNEST(hits) AS hits
WHERE
hits.eCommerceAction.action_type = '6'
GROUP BY fullVisitorId
)
GROUP BY fullVisitorId, purchased_product_id;
最内层的查询从 all_ga_sessions 表中提取所有通过 fullVisitorId 识别的顾客,这些顾客至少在电子商务门户上购买过产品。为了识别这些购买,我们在 WHERE 子句中添加了 hits.eCommerceAction.action_type = '6'。为了获取 fullVisitorId 的唯一值,查询利用了 GROUP BY fullVisitorId 子句。
在嵌套查询的 FROM 子句中,我们使用 UNNEST 函数提取原始表中存在的嵌套字段并访问它们。
重要提示
UNNEST 是一个用于将数组转换为多行集合的函数。它接受一个数组作为输入,并返回一个表,其中每行对应数组中的一个项目。
在最外层的查询中,我们仅提取与我们用例相关的三个字段:fullVisitorId、purchased_product_id 和我们的总 quantity。此最后指标是通过使用 SUM 操作符在特定用户购买特定产品时进行的所有交易获得的。
既然我们已经创建了推荐引擎将训练的表,让我们创建 BigQuery ML 模型。
训练矩阵分解模型
在本节中,我们将训练 BigQuery ML 矩阵分解模型,以便使用我们已准备好的电子商务数据构建推荐系统。
让我们从执行以下 SQL 语句开始训练 purchase_recommender ML 模型:
CREATE OR REPLACE MODEL `09_recommendation_engine.purchase_recommender`
OPTIONS(model_type='matrix_factorization',
user_col='fullVisitorID',
item_col='purchased_product_id',
rating_col='quantity',
feedback_type='implicit'
)
AS
SELECT fullVisitorID, purchased_product_id, quantity
FROM `09_recommendation_engine.product_purchases`;
查询的前几行由 CREATE OR REPLACE MODEL 关键字组成,后面跟着新 ML 模型的标识符 `09_recommendation_engine.purchase_recommender` 和 OPTIONS。
现在,让我们关注我们用于训练 BigQuery ML 模型的 OPTIONS 值:
-
模型类型是
'matrix_factorization'。此选项描述了我们用于训练推荐模型的算法。 -
user_col='fullVisitorID'选项指定哪个列代表推荐引擎的用户。在我们的案例中,我们使用fullVisitorID字段,该字段分配给电子商务门户的注册客户。 -
使用
item_col='purchased_product_id'选项时,我们使用客户购买的产品代码来识别模型中的每个项目。 -
由于我们没有产品的明确评分,我们将选择
feedback_type='implicit'并使用购买的quantity值作为推荐引擎的评分。在这种情况下,我们假设如果用户购买了大量的产品,他们对产品感兴趣并且对产品满意。
大约 7 分钟后,矩阵分解模型将被训练,我们可以进入下一个阶段:评估阶段。
评估矩阵分解模型
在本节中,我们将评估我们在上一节中训练的矩阵分解模型的性能。
矩阵分解模型的评估阶段可以使用 ML.EVALUATE BigQuery ML 函数或通过 BigQuery UI 进行。
让我们执行以下查询以提取表征我们刚刚训练的推荐模型的全部评估参数:
SELECT
*
FROM
ML.EVALUATE(MODEL `09_recommendation_engine.recommender`,
(
SELECT * FROM `09_recommendation_engine.product_visits`));
此查询的结果显示在下图中:
图 9.9 – 从矩阵分解模型评估中提取的记录
可以通过从 BigQuery 导航菜单中选择 ML 模型,然后访问评估选项卡来获取相同的信息。
在下图中,您可以查看 BigQuery ML 模型的评估指标:
图 9.10 – 矩阵分解模型的评估选项卡
由于均方误差的值非常低,我们可以对我们的矩阵分解模型所取得的结果感到满意。
在本节中,我们学习了如何访问我们推荐模型的性能指标。现在,让我们使用推荐模型来找到最佳产品,向我们的客户推荐。
使用矩阵分解模型
在本节中,我们将测试矩阵分解模型,以获取我们网站用户的推荐产品。
要使用我们的 BigQuery ML 模型,我们将使用 ML.RECOMMEND 函数,同时指定预测的参数。
推荐引擎除了模型本身外,不需要任何额外的输入参数。如果模型有一个输入列,则模型将只返回输入行中的推荐。如果没有提供输入值,则模型将对原始数据集中用户和项目的每个组合应用预测。
ML.RECOMMEND 返回三列:
-
代表用户的列。在我们的实现中,这由
fullVisitorID列标识。 -
专门针对推荐给特定用户的项目的领域。在我们的案例中,这由
purchased_product_id列表示。 -
第三列代表在显式矩阵分解模型中的预测评分。如果模型是隐式的,就像在我们的案例中一样,该字段存储了推荐的预测置信度。
让我们执行以下查询,以实现一个包含由我们的矩阵分解模型生成的所有推荐的表:
CREATE OR REPLACE TABLE `09_recommendation_engine.product_recommendations` AS
SELECT
DISTINCT fullVisitorID, purchased_product_id, predicted_quantity_confidence
FROM
ML.RECOMMEND(MODEL`09_recommendation_engine.purchase_recommender`,
(
SELECT
fullVisitorID
FROM
`09_recommendation_engine.product_purchases` ));
该查询创建了一个名为product_recommendations的新表,该表存储了用户和项目的DISTINCT对。在我们的案例中,这些对由fullVisitorID和purchased_product_id列组成。
对于每一对,ML.RECOMMEND函数还返回一个预测置信度,表示特定用户对电子商务目录中的产品感兴趣的概率。
现在我们已经得到了推荐引擎的输出,让我们学习如何从业务角度使用这些数据。
提取业务结论
现在我们已经应用了 BigQuery ML 模型,让我们学习如何从业务角度使用生成的结果来提高我们的销售策略的有效性。
从product_recommendations表中,我们可以提取相关信息,我们可以使用这些信息来改进我们的营销活动或广告策略,然后针对更有可能购买特定产品的用户进行定位。
例如,通过执行以下查询,我们可以从我们的电子商务门户中提取出前100个最有可能购买特定产品的用户:
SELECT *
FROM
`09_recommendation_engine.product_recommendations`
ORDER BY predicted_quantity_confidence DESC
LIMIT 100;
执行此 SQL 语句返回以下结果:
![图 9.11 – 最有可能购买特定产品的客户
图 9.11 – 最有可能购买特定产品的客户
我们刚刚提取的列表可以发送到我们的营销办公室,以创建定制营销活动。或者,它也可以用于我们的电子商务门户,为特定注册客户推荐最有趣的产品。
摘要
在本章中,我们基于矩阵分解算法构建了一个推荐引擎。在介绍了业务场景之后,我们发现了矩阵分解是什么以及显式模型和隐式模型之间的区别。在深入数据探索之前,我们启用了 BigQuery Flex Slots,这对于训练这类机器学习算法是必要的。
然后,我们对 Google 从 Google Merchandise 电子商务门户收集的样本数据进行了分析和数据准备步骤。在这里,我们专注于构建我们的 BigQuery ML 模型所必需的字段。
接下来,我们创建了我们的训练表,其中包括每个用户所做的购买,以及每个产品的相关数量。
之后,我们在准备好的数据上训练了我们的矩阵分解模型。当模型训练完成后,我们使用 SQL 代码和 BigQuery UI 评估了其关键性能指标。
最后,我们使用我们新的矩阵分解模型生成了一些推荐,并提取了一份 100 名客户的清单,这些客户有很高的购买产品组合的倾向。
在下一章中,我们将介绍用于预测二元值的 XGBoost 算法。
进一步资源
-
Google Analytics 360 公共数据集:
console.cloud.google.com/marketplace/product/obfuscated-ga360-data/obfuscated-ga360-data -
BigQuery ML 创建模型:
cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-create -
BigQuery ML 评估模型:
cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-evaluate -
BigQuery ML 推荐:
cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-recommend -
BigQuery ML 显式矩阵分解示例:
cloud.google.com/bigquery-ml/docs/bigqueryml-mf-explicit-tutorial -
BigQuery ML 隐式矩阵分解示例:
cloud.google.com/bigquery-ml/docs/bigqueryml-mf-implicit-tutorial#implicit-model
第十章:使用 XGBoost 预测布尔值
极端梯度提升(XGBoost)是数据科学家可以利用来解决复杂用例的最强大的机器学习(ML)库之一。它最初是一个研究项目,第一个版本于 2014 年发布。由于其功能和可移植性,这个机器学习库的受欢迎程度迅速增长。实际上,它被用于重要的 Kaggle 机器学习竞赛,并且现在可用于不同的编程语言和不同的操作系统。
这个库可以用来解决不同的机器学习(ML)问题,并且专门为结构化数据设计。XGBoost 也最近被发布用于 BigQuery ML。多亏了这项技术,BigQuery 用户现在可以使用这个库实现分类和回归机器学习模型。
在本章中,我们将看到实现 XGBoost 分类模型的所有必要阶段,以便根据其特征将纽约市的树木分类到不同的物种。
使用 BigQuery ML SQL 语法,我们将探讨以下主题:
-
介绍业务场景
-
发现 XGBoost 增强树分类模型
-
探索和理解数据集
-
训练 XGBoost 分类模型
-
评估 XGBoost 分类模型
-
使用 XGBoost 分类模型
-
绘制商业结论
技术要求
本章要求您能够访问网络浏览器,并能够利用以下资源:
-
一个 Google Cloud Platform(GCP)账户以访问 Google Cloud 控制台
-
一个 GCP 项目来托管 BigQuery 数据集
现在我们已经满足了技术要求,让我们深入分析和开发我们的 BigQuery ML XGBoost 分类模型。
查看以下视频以查看代码的实际应用:bit.ly/3ujnzH3
介绍业务场景
在本节中,我们将介绍将使用 XGBoost 分类算法解决的业务场景。
业务场景与在第六章中介绍和使用的用例非常相似,使用多类逻辑回归对树木进行分类。在本章中,我们将使用相同的数据集,但将应用更先进的机器学习算法。
我们可以总结并记住,机器学习模型的目标是自动根据纽约市树木的特征,如位置、大小和健康状况,将它们分类到不同的物种。
正如我们在第九章中做的,通过矩阵分解建议合适的产品,我们可以只关注城市中存在的五种最常见的树木物种。
现在我们已经解释并理解了业务场景,让我们看看我们可以用来根据特征自动分类树木的机器学习技术。
发现 XGBoost 提升树分类模型
在本节中,我们将了解 XGBoost 提升树分类模型是什么,以及我们将理解哪些分类用例可以使用这个机器学习算法来解决。
XGBoost 是一个开源库,为不同的语言提供了一个可移植的梯度提升框架。XGBoost 库适用于不同的编程语言,如 C++、Java、Python、R 和 Scala,并且可以在不同的操作系统上运行。XGBoost 用于处理监督学习用例,其中我们使用标记的训练数据来预测目标变量。
XGBoost 在机器学习社区中的普及度逐年增长,因为它经常是许多在机器学习竞赛中获胜团队的选项,例如 2016 年的Kaggle - 高能物理与机器学习奖。
XGBoost 提升树的分类能力基于使用多个决策树来分类数据,从而实现预测。
在以下图表中,你可以看到一个简单的表示用于分类动物的决策树:
图 10.1 – 决策树的表示
XGBoost 分类模型可以回答与多类逻辑回归相同的问题,例如以下问题:
-
我的客户的评论是中立、正面还是负面?
-
我的客户属于金、银还是铜级别?
-
特定客户的流失概率是高、中还是低?
-
图像识别算法识别的是猫、狗、老鼠还是牛?
在我们的业务场景中,我们可以利用 XGBoost 提升树分类模型将纽约市的树木分为五种不同的物种。实际上,我们对根据每棵树的特征预测物种感兴趣。
在 XGBoost 算法的训练阶段,机器学习模型试图找到为每棵树分配的最佳值,以最小化最终的误差指标。
训练完成后,我们将比较这个模型的结果与我们之前在第六章,“使用多类逻辑回归分类树木”中得到的成果。
现在我们已经学习了 XGBoost 提升树算法的基础知识,是时候看看我们将用于构建我们的机器学习模型的数据集了。
探索和理解数据集
在本节中,我们将分析和准备用于我们用例的数据集。我们将从一些数据质量检查开始,然后我们将数据分割成训练、评估和测试表。
由于数据集已经在第六章,使用多类逻辑回归对树木进行分类中使用过,因此我们不会从开始分析。相反,我们将专注于我们业务场景中最相关的查询。
检查数据质量
为了开始我们的数据探索并进行数据质量检查,我们需要执行以下操作:
-
登录我们的 Google Cloud 控制台,并通过导航菜单访问BigQuery 用户界面(UI)。
-
在第二章,设置您的 GCP 和 BigQuery 环境中创建的项目下创建一个新的数据集。对于此用例,我们将创建一个名为
10_nyc_trees_xgboost的数据集,并使用默认选项。 -
首先,让我们通过执行以下查询来检查所有记录在
spc_latin字段中是否包含有效的值:SELECT COUNT(*) FROM `bigquery-public-data.new_york_trees.tree_census_2015` WHERE spc_latin is NULL;如以下屏幕截图所示,存在
spc_latin列。这些记录将在训练阶段被过滤掉:![图 10.2 – 查询结果显示应过滤掉一些记录
图 10.2 – 查询结果显示应过滤掉一些记录
-
在此第一次检查之后,我们需要验证是否有任何潜在的特征由
NULL值表示。由于sidewalk和health字段中存在NULL值,我们将运行以下COUNT查询以检查三条记录。尽管数量很少,我们将在以下查询中过滤掉这些记录,以仅使用有意义的记录。 -
然后,我们可以从 BigQuery 公共数据集中提取最常见的五种树种。让我们执行以下查询:
SELECT spc_latin, COUNT(*) total FROM `bigquery-public-data.new_york_trees.tree_census_2015` WHERE spc_latin is NOT NULL AND zip_city is NOT NULL AND tree_dbh is NOT NULL AND boroname is NOT NULL AND nta_name is NOT NULL AND health is NOT NULL AND sidewalk is NOT NULL GROUP BY spc_latin ORDER BY total desc LIMIT 5;查询将
total计算为每个spc_latin字段记录的数量。使用ORDER BY子句按total字段从大到小的值排序结果。然后,使用LIMIT 5子句仅返回前五条记录。在以下屏幕截图中,您可以查看查询结果,该结果显示了数据集中最常见的五种树种:
![图 10.3 – 数据集中最常见的树种
图 10.3 – 数据集中最常见的树种
-
为了将这些五种树种实体化到表中,让我们执行以下代码来创建一个名为
10_nyc_trees_xgboost.top5_species的表:CREATE OR REPLACE TABLE `10_nyc_trees_xgboost.top5_species` AS SELECT spc_latin, COUNT(*) total FROM `bigquery-public-data.new_york_trees.tree_census_2015` WHERE spc_latin is NOT NULL AND zip_city is NOT NULL AND tree_dbh is NOT NULL AND boroname is NOT NULL AND nta_name is NOT NULL AND health is NOT NULL AND sidewalk is NOT NULL GROUP BY spc_latin ORDER BY total desc LIMIT 5;与之前第 5 步中执行的查询的唯一区别在于使用了
CREATE OR REPLACE TABLE关键字,这些关键字被用来将查询的结果实体化到新表中。
在本节中,我们已经分析了 BigQuery 公共数据集的数据质量。现在,让我们开始将其分割成三个不同的表,用于训练、评估和分类阶段。
分割数据集
在实现我们的 XGBoost 分类模型之前,让我们根据机器学习开发生命周期的主要阶段来分割我们的数据集:训练、评估和使用。为了将记录随机分成三个不同的表格,我们将在tree_id数值字段上使用MOD函数。按照以下步骤操作:
-
首先,让我们创建一个包含训练数据集的表格。为此,我们执行以下 SQL 语句:
CREATE OR REPLACE TABLE `10_nyc_trees_xgboost.training_table` AS SELECT * FROM `bigquery-public-data.new_york_trees.tree_census_2015` WHERE zip_city is NOT NULL AND tree_dbh is NOT NULL AND boroname is NOT NULL AND nta_name is NOT NULL AND health is NOT NULL AND sidewalk is NOT NULL AND spc_latin in (SELECT spc_latin from `10_nyc_trees_xgboost.top5_species`) AND MOD(tree_id,11)<=8;查询创建了一个包含原始数据集中所有列的
10_nyc_trees_xgboost.training_table表格,通过SELECT *语句应用了所有必要的过滤器,以获取spc_latin标签和所有其他特征的空值。使用
IN子句,training_table将只包含与数据集中我们已识别的前五种最常见的物种相关的记录。查询的最后一条语句,带有
MOD(tree_id,11)<=8子句,使我们能够从整个数据集中仅选择 80%的记录。MOD代表模,返回tree_id除以 11 的余数。通过使用小于或等于运算符(<=),我们大约提取了整个数据集的 80%。 -
采用类似的方法,我们可以创建一个名为
10_nyc_trees_xgboost.evaluation_table的表格,该表格将用于评估我们的机器学习模型。让我们执行以下CREATE TABLE语句:CREATE OR REPLACE TABLE `10_nyc_trees_xgboost.evaluation_table` AS SELECT * FROM `bigquery-public-data.new_york_trees.tree_census_2015` WHERE zip_city is NOT NULL AND tree_dbh is NOT NULL AND boroname is NOT NULL AND nta_name is NOT NULL AND health is NOT NULL AND sidewalk is NOT NULL AND spc_latin in (SELECT spc_latin from `06_nyc_trees.top5_species`) AND MOD(tree_id,11)=9;与我们创建训练表时的情况相反,对于
evaluation_table表,我们通过应用MOD(tree_id,11)=9过滤器,仅从整个数据集中选择 10%的记录。 -
最后,我们将执行以下 SQL 语句以创建一个名为
10_nyc_trees_xgboost.classification_table的表格,该表格将用于应用我们的 XGBoost 分类模型:CREATE OR REPLACE TABLE `10_nyc_trees_xgboost.classification_table` AS SELECT * FROM `bigquery-public-data.new_york_trees.tree_census_2015` WHERE zip_city is NOT NULL AND tree_dbh is NOT NULL AND boroname is NOT NULL AND nta_name is NOT NULL AND health is NOT NULL AND sidewalk is NOT NULL AND spc_latin in (SELECT spc_latin from `10_nyc_trees_xgboost.top5_species`) AND MOD(tree_id,11)=10;这个新表格与之前的表格非常相似,但多亏了
MOD函数,它将包含数据集剩余的 10%。
在本节中,我们分析了包含纽约市树木信息的数据集,对数据进行了一些数据质量检查以排除空值,并分割了数据集,重点关注最常见的五种物种。现在我们已经完成了准备工作,是时候继续前进并开始训练我们的 BigQuery ML 模型了。
训练 XGBoost 分类模型
现在我们已经将数据集分割成多个表格以支持机器学习模型生命周期的不同阶段,让我们专注于训练我们的 XGBoost 分类模型。按照以下步骤操作:
-
让我们从训练我们的第一个机器学习模型
xgboost_classification_model_version_1开始,如下所示:CREATE OR REPLACE MODEL `10_nyc_trees_xgboost.xgboost_classification_model_version_1` OPTIONS ( MODEL_TYPE='BOOSTED_TREE_CLASSIFIER', BOOSTER_TYPE = 'GBTREE', NUM_PARALLEL_TREE = 1, MAX_ITERATIONS = 50, TREE_METHOD = 'HIST', EARLY_STOP = FALSE, AUTO_CLASS_WEIGHTS=TRUE ) AS SELECT zip_city, tree_dbh, spc_latin as label FROM `10_nyc_trees_xgboost.training_table` ;在这个 BigQuery ML 语句中,我们可以看到使用
CREATE OR REPLACE MODEL关键字来启动模型的训练。这些关键字后面跟着机器学习模型的标识符。在标识符之后,我们可以注意到一个
OPTIONS子句。对于MODEL_TYPE,我们选择了BOOSTED_TREE_CLASSIFIER选项,这允许我们构建 XGBoost 分类模型。BOOSTER_TYPE = 'GBTREE'子句被认为是训练 XGBoost 提升树模型的默认选项。为了限制训练的复杂性和资源消耗,我们选择仅通过
NUM_PARALLEL_TREE = 1子句并行训练一棵树,并使用MAX_ITERATIONS在50次迭代后停止训练。XGBoost 文档中建议对于大型数据集使用
HIST参数,并使用EARLY_STOP = FALSE子句来防止在第一次迭代后停止训练阶段。最后一个选项,
AUTO_CLASS_WEIGHTS=TRUE,用于平衡权重——在数据集不平衡的情况下——以及一些可能比其他树种更频繁出现的树种。这个模型的第一版本试图预测每棵树的物种,仅利用树木种植地的
zip_city代码和树木的直径tree_dbh。 -
训练结束后,我们可以从 BigQuery 导航菜单中访问机器学习模型,查看模型的性能。选择评估选项卡,我们可以看到ROC AUC值。在这种情况下,该值为0.7775,如下面的截图所示:
图 10.4 – XGBoost 分类模型的评估指标
在相同的评估选项卡中,我们还可以可视化混淆矩阵,该矩阵显示了预测值与实际值相等多少次,如下面的截图所示:
图 10.5 – 评估选项卡显示了 XGBoost 分类模型的混淆矩阵
-
让我们尝试通过添加有助于将树木分类为不同物种的特征来改进我们的机器学习模型。让我们通过运行以下代码来训练我们 BigQuery 机器学习模型的第二个版本:
CREATE OR REPLACE MODEL `10_nyc_trees_xgboost.xgboost_classification_model_version_2` OPTIONS ( MODEL_TYPE='BOOSTED_TREE_CLASSIFIER', BOOSTER_TYPE = 'GBTREE', NUM_PARALLEL_TREE = 1, MAX_ITERATIONS = 50, TREE_METHOD = 'HIST', EARLY_STOP = FALSE, AUTO_CLASS_WEIGHTS=TRUE ) AS SELECT zip_city, tree_dbh, boroname, nta_name, spc_latin as label FROM `10_nyc_trees_xgboost.training_table` ;与之前的步骤 1的第一次尝试相比,我们包括了额外的特征。事实上,我们将包含在
boroname字段和nta_name字段中的区名添加到特征中,这些字段提供了与树木在城市中位置相关的更具体信息。执行 SQL 语句后,让我们访问新模型的评估选项卡,看看我们是否提高了其性能。查看ROC AUC值为0.80,我们可以看到与第一个版本相比,我们模型的性能略有提高。
-
然后,我们将尝试向我们的机器学习模型添加与树木健康和其根系侵入性相关的其他特征,这些侵入性可能会损坏相邻的人行道,如下所示:
CREATE OR REPLACE MODEL `10_nyc_trees_xgboost.xgboost_classification_model_version_3` OPTIONS ( MODEL_TYPE='BOOSTED_TREE_CLASSIFIER', BOOSTER_TYPE = 'GBTREE', NUM_PARALLEL_TREE = 5, MAX_ITERATIONS = 50, TREE_METHOD = 'HIST', EARLY_STOP = FALSE, AUTO_CLASS_WEIGHTS=TRUE ) AS SELECT zip_city, tree_dbh, boroname, nta_name, health, sidewalk, spc_latin as label FROM `10_nyc_trees_xgboost.training_table`;与之前的 ML 模型相比,
xgboost_classification_model_version_3模型包含一个health字段,用于描述我们树木的健康状况,以及一个sidewalk字段,用于指定树木的根是否损坏相邻的人行道。 -
在 BigQuery UI 的 评估 选项卡中查看我们最后 ML 模型的性能,我们可以注意到我们在 ROC AUC 方面又取得了提高,值为 0.8121。
在本节中,我们通过尝试在我们的数据集中使用不同的特征创建了不同的 ML 模型。在接下来的步骤中,我们将使用具有最高 xgboost_classification_model_version_3 的模型。
现在,让我们开始在评估数据集上对 XGBoost 分类模型进行评估阶段。
评估 XGBoost 分类模型
为了评估我们的 BigQuery ML 模型,我们将使用 ML.EVALUATE 函数以及我们专门创建的作为评估数据集的表格。
以下查询将告诉我们模型是否过度拟合,或者是否也能在新数据上表现良好:
SELECT
roc_auc,
CASE
WHEN roc_auc > .9 THEN 'EXCELLENT'
WHEN roc_auc > .8 THEN 'VERY GOOD'
WHEN roc_auc > .7 THEN 'GOOD'
WHEN roc_auc > .6 THEN 'FINE'
WHEN roc_auc > .5 THEN 'NEEDS IMPROVEMENTS'
ELSE
'POOR'
END
AS model_quality
FROM
ML.EVALUATE(MODEL `10_nyc_trees_xgboost.xgboost_classification_model_version_3`,
(
SELECT
zip_city,
tree_dbh,
boroname,
nta_name,
health,
sidewalk,
spc_latin as label
FROM `10_nyc_trees_xgboost.evaluation_table`));
SELECT 语句提取了 ML.EVALUATE 函数返回的 roc_auc 值,并提供了对模型质量的清晰描述,从 'POOR' 开始,可以达到 'EXCELLENT' 等级,经过一些中间阶段,如 'NEEDS IMPROVEMENTS' 和 'GOOD'。
执行查询,我们可以看到分数是 非常好,如下面的截图所示:
![图 10.6 – 评估阶段为我们的 BigQuery ML 模型的质量返回了“非常好”]
图 10.6 – 评估阶段为我们的 BigQuery ML 模型的质量返回了“非常好”
现在我们已经评估了我们的 ML 模型,让我们看看我们如何将其应用于其他记录以获得树木的分类。
使用 XGBoost 分类模型
在本节中,我们将使用 ML 模型根据树木的特征将树木分类到五种不同的物种。
为了测试我们的 BigQuery ML 模型,我们将在 classification_table 表上使用 ML.PREDICT 函数,如下所示:
SELECT
tree_id,
actual_label,
predicted_label_probs,
predicted_label
FROM
ML.PREDICT (MODEL `10_nyc_trees_xgboost.xgboost_classification_model_version_3`,
(
SELECT
tree_id,
zip_city,
tree_dbh,
boroname,
nta_name,
health,
sidewalk,
spc_latin as actual_label
FROM
`10_nyc_trees_xgboost.classification_table`
)
);
查询由一个 SELECT 语句组成,该语句提取 tree_id 值、树木的实际物种、每个预测物种的概率以及预测物种。
在下面的截图中,你可以看到查询执行的结果:
![图 10.7 – 查询输出显示了实际标签和预测标签]
与相关的概率
图 10.7 – 查询输出显示了实际标签和预测标签以及相关的概率
在前面截图显示的两行中,标识为 283502 和 226929 的树木被很好地分类到 Acer platanoides 物种,置信度为 61%。
现在我们已经测试了我们的 BigQuery ML 模型,让我们通过比较 XGBoost 分类模型与在第六章中使用的逻辑回归的结果来做出一些最终考虑。
绘制业务结论
在本节中,我们将使用我们的 ML 模型,并了解 BigQuery ML 模型在classification_table表中能够将树木正确分类的次数。
让我们执行以下查询来计算预测物种与实际物种一致性的次数:
SELECT COUNT(*)
FROM (
SELECT
tree_id,
actual_label,
predicted_label_probs,
predicted_label
FROM
ML.PREDICT (MODEL `10_nyc_trees_xgboost.xgboost_classification_model_version_3`,
(
SELECT
tree_id,
zip_city,
tree_dbh,
boroname,
nta_name,
health,
sidewalk,
spc_latin as actual_label
FROM
`10_nyc_trees_xgboost.classification_table`
)
)
)
WHERE
actual_label = predicted_label;
为了计算这个值,我们通过仅过滤预测值等于实际值的行,引入了一个WHERE子句。
如以下截图所示,SELECT COUNT返回了14277条记录:
图 10.8 – 查询输出显示了分类模型预测正确物种的次数
在classification_table表中存储的 27,182 行数据中,我们可以说我们的模型在 52.52%的情况下将树木正确分类。
在以下表中,XGBoost 分类模型的结果与在第六章中应用的多元逻辑回归的结果进行了比较,使用多元逻辑回归对树木进行分类:
图 10.9 – XGBoost 分类模型和多类逻辑回归的比较
观察前面的表格,我们可以得出结论,为了将纽约市的树木分类到最常见的五种物种,与多元逻辑回归模型相比,XGBoost 分类模型能够实现更好的结果。
摘要
在本章中,我们实现了一个 XGBoost 分类模型。我们回忆了在第六章中已经使用的业务场景,使用多元逻辑回归对树木进行分类,基于自动分类纽约市树木的需求。之后,我们学习了 XGBoost 提升树分类模型的基础知识。
为了构建一个有效的模型,我们进行了数据质量检查,然后根据我们的需求将数据集分割成三个表:一个用于存放训练数据,第二个用于评估阶段,最后一个用于应用我们的分类模型。
在 BigQuery ML 模型的训练阶段,我们不断改进了 ML 模型的性能,使用 ROC AUC 作为关键性能指标(KPI)。
之后,我们评估了最佳 ML 模型在新的记录集上的表现,以避免任何过拟合,从而对我们 XGBoost 分类模型的高质量更加有信心。
最后,我们将我们的 BigQuery ML 模型应用于最后一批记录,根据它们的特征将树木分类到物种中。我们发现我们的 ML 模型在 52.52% 的情况下能够正确分类树木。然后,我们还比较了 XGBoost 模型的性能与我们在 第六章 中进行的多元逻辑回归训练,即 使用多元逻辑回归分类树木,并注意到 XGBoost 的性能超过了多元逻辑回归训练。
在下一章中,我们将学习关于高级 深度神经网络(DNNs),利用 BigQuery SQL 语法。
进一步资源
-
纽约市街道树木普查公共数据集:
console.cloud.google.com/marketplace/product/city-of-new-york/nyc-tree-census -
XGBoost 主页:
xgboost.ai/ -
XGBoost 文档:
xgboost.readthedocs.io/en/latest/index.html -
CREATE MODEL语句用于提升树模型:cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-create-boosted-tree -
ML.EVALUATE函数:cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-evaluate -
ML.PREDICT函数:cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-predict
第十一章:实现深度神经网络
深度神经网络(DNNs)是实现机器学习算法的最先进技术之一。它们在多种用例中广泛使用,并且可以被认为是日常生活中无处不在的。
当我们与虚拟助手互动,或使用移动应用程序进行自动翻译和图像识别时,我们正在利用使用大量音频和图像数据集训练的深度神经网络(DNNs)的能力。
在阅读本章后,您将能够使用 BigQuery ML 开发、评估和测试一个 DNN。在本章中,我们将看到使用 BigQuery ML 通过预测与纽约市自行车共享服务相关的租赁时长来实施 DNN 的所有必要阶段。
使用 BigQuery ML,我们将探讨以下主题:
-
介绍商业场景
-
发现 DNNs
-
准备数据集
-
训练 DNN 模型
-
评估 DNN 模型
-
使用 DNN 模型
-
提取业务结论
技术要求
本章要求您能够访问网络浏览器,并能够利用以下内容:
-
一个 GCP 账户以访问 Google Cloud Console
-
一个 GCP 项目来托管 BigQuery 数据集
现在我们已经准备好了技术要求,让我们深入分析和发展我们的 BigQuery ML DNN 模型。
查看以下视频以查看代码的实际应用:bit.ly/33lbq8A
介绍商业场景
在本节中,您将了解到将使用 DNN 技术处理的商业场景。
商业场景与在第四章中介绍和使用的用例非常相似,即使用线性回归预测数值。在这一章中,我们将使用与纽约市自行车共享服务相关的相同数据集,但我们将应用更先进的机器学习算法。
我们可以记住,机器学习模型的假设目标是预测自行车租赁的行程时间。预测值可以用于通过新的移动应用程序为自行车共享服务的客户提供更好的体验。利用预测的骑行时长,客户将得到到达特定目的地所需时间的明确指示,以及骑行成本的估计。
既然我们已经解释并理解了商业场景,让我们来看看我们可以使用的机器学习技术,以自动根据特征对树木进行分类。
发现 DNNs
在本节中,我们将学习什么是DNNs,并了解哪些回归和分类用例可以使用高级机器学习算法来管理。
人工神经网络(ANNs)是试图复制人脑的人工系统。它们受到生物神经网络的启发,由神经元和连接神经元的突触组成。人工网络中的每个神经元都是一个组件,它对输入应用特定的数学激活函数,并返回一个通过突触传递给下一个神经元的输出。在 ANNs 中,神经元通常组织在输入和输出之间的层中。
与线性模型不同,ANNs 旨在模拟输入和输出变量之间的非线性关系。
DNNs是由多个层组成的 ANNs,这些层位于输入和输出之间,通常是两层或更多。每个神经元的层被称为隐藏层,其功能是接受一系列输入信号,并将一系列输出信号返回给下一层。
在以下图中,我们可以看到 DNN 由三个输入变量、两个隐藏层和一个输出变量组成:
![图 11.1 – DNN 的示意图
![img/B16722_11_001.jpg]
图 11.1 – DNN 的示意图
网络中的每个神经元都对输入信号应用特定的函数,并将该函数的输出作为神经元的输出。训练 DNN 是一项专注于找到网络中每个神经元之间每个突触的正确权重的活动。
尽管如此,为了实现 DNNs 的潜力,我们需要重要的硬件资源,但使用这种技术实现的机器学习模型可以在典型的人脑任务中实现最佳结果。以下是一些例子:
-
语音识别:处理音频文件以识别语音中的单词,使其可读的能力。这种能力在智能手机的虚拟助手或接触中心应用程序中得到广泛应用。
-
图像和面部识别:在图片和视频中识别不同实体、动物或人物的可能性。这项技术特别有用,可以自动从图像和视频中提取见解,避免任何人工努力。
-
自然语言处理:广泛用于分析和检索自由文本中的信息,以及分析消息的情感。例如,这类算法被用于自动识别社交网络中的政策违规,或在产品评论中评估情感。
既然我们已经了解了 DNNs 是什么,让我们关注 BigQuery ML 如何提供这些强大的算法。
BigQuery ML 中的 DNNs
在本节中,我们将学习 BigQuery ML 提供的创建 DNN 模型模型类型选项。
BigQuery ML 允许您创建两种不同类型的深度神经网络(DNNs):
-
DNNClassifier:此算法可用于将事件、对象或实体分类到有限数量的离散类别中。
-
DNNRegressor:这种模型与之前的模型类似,区别在于它返回一个连续的结果。因此,它可以用来预测数值。
对于我们的业务场景,我们将使用DNNRegressor,因为我们的目标是预测一个连续值:自行车租赁的骑行时间。
根据我们的用例选择了要使用的 DNN 类型后,下一个选择将集中在每个神经元将应用于输入信号的功能。BigQuery ML 允许我们选择以下函数之一:
-
Rectified Linear Function (ReLU):这是一个线性函数,如果输入值是正的,则返回输入值本身,否则返回零。
-
ReLU6:这与之前的函数类似,但最大输出值被限制为 6。这只是一个从不同函数的经验测试中得出的任意值。
-
Concatenated Rectified Linear Units (CReLU):与之前的函数不同,它保留了负值。
-
Exponential Linear Unit (ELU):这是一个指数函数,它倾向于更快地收敛到结果并产生更精确的输出。
-
Scaled Exponential Linear Unit (SELU):这是 ELU 的演变,它添加了数学函数的自我归一化。
-
SIGMOID:这与一个阶梯函数类似,始终输出介于 0 和 1 之间的值。这个函数将非线性引入 DNN。
-
TANH:这与 sigmoid 函数类似,但返回的值介于-1 和 1 之间。
每个函数都有一些优点和缺点,并且应根据用例和训练数据集来选择,以实现最佳结果。对于我们的业务场景,我们将尝试使用这些函数中的一些来训练 DNN,并选择产生最佳结果的函数。
现在我们已经学习了 DNN 的基础知识和 BigQuery ML 通过其 SQL 界面提供的主要选项,让我们开始准备创建我们的机器学习模型所需的数据。
准备数据集
在开始 ML 实现之前,有必要分析和准备我们用例的数据。由于数据集已经在第四章中使用了,使用线性回归预测数值,我们将不会从头开始分析,但我们将专注于与我们用例相关的查询。
开始准备我们的数据,我们需要做以下事情:
-
登录 Google Cloud 控制台,并通过导航菜单访问BigQuery用户界面。
-
在第二章中创建的项目下创建一个新的数据集,设置您的 GCP 和 BigQuery 环境。对于这个用例,我们将使用默认选项创建数据集
11_nyc_bike_sharing_dnn。 -
现在我们已经准备好创建包含训练数据集的表。让我们执行以下 SQL 语句:
CREATE OR REPLACE TABLE `11_nyc_bike_sharing_dnn.training_table` AS SELECT tripduration/60 tripduration, start_station_name, end_station_name, IF (EXTRACT(DAYOFWEEK FROM starttime)=1 OR EXTRACT(DAYOFWEEK FROM starttime)=7, true, false) is_weekend, EXTRACT(YEAR FROM starttime)-birth_year as age FROM `bigquery-public-data.new_york_citibike.citibike_trips` WHERE ( (EXTRACT (YEAR FROM starttime)=2017 AND (EXTRACT (MONTH FROM starttime)>=04 OR EXTRACT (MONTH FROM starttime)<=10)) OR (EXTRACT (YEAR FROM starttime)=2018 AND (EXTRACT (MONTH FROM starttime)>=01 OR EXTRACT (MONTH FROM starttime)<=02)) ) AND (tripduration>=3*60 AND tripduration<=3*60*60) AND birth_year is not NULL AND birth_year < 2007;查询结果存储在新创建的表中,名为
`11_nyc_bike_sharing_dnn.training_table`,我们创建此表是为了支持我们用例的以下步骤。SELECT语句从citibike_trips表中提取字段并应用一些转换。tripduration从秒转换为分钟。start_station_name和end_station_name字段直接提取。使用starttime,查询计算租赁是否发生在工作日或周末。最后,使用starttime和birth_year之间的差值计算顾客在骑行时的年龄。正如我们在 第四章 中所做的那样,使用线性回归预测数值值,
WHERE子句允许我们仅考虑我们想要用于训练阶段的月份。对于训练数据集,时间范围从 2017 年 4 月到 2018 年 2 月。在相同的WHERE子句中,我们还应用了来自数据质量检查的过滤器。 -
在创建训练表之后,我们可以创建第二个表,专门用于记录将用于评估我们的机器学习模型的:
CREATE OR REPLACE TABLE `11_nyc_bike_sharing_dnn.evaluation_table` AS SELECT tripduration/60 tripduration, start_station_name, end_station_name, IF (EXTRACT(DAYOFWEEK FROM starttime)=1 OR EXTRACT(DAYOFWEEK FROM starttime)=7, true, false) is_weekend, EXTRACT(YEAR FROM starttime)-birth_year as age FROM `bigquery-public-data.new_york_citibike.citibike_trips` WHERE (EXTRACT (YEAR FROM starttime)=2018 AND (EXTRACT (MONTH FROM starttime)=03 OR EXTRACT (MONTH FROM starttime)=04)) AND (tripduration>=3*60 AND tripduration<=3*60*60) AND birth_year is not NULL AND birth_year < 2007;查询与用于创建训练表的语句非常相似。唯一的区别是
WHERE子句中选择的时期。对于`11_nyc_bike_sharing_dnn.evaluation_table`表,我们专注于之前从训练表中排除的 2018 年 3 月和 4 月的记录。 -
采用相同的方法,我们也可以创建用于测试我们的机器学习模型的表:
CREATE OR REPLACE TABLE `11_nyc_bike_sharing_dnn.prediction_table` AS SELECT tripduration/60 tripduration, start_station_name, end_station_name, IF (EXTRACT(DAYOFWEEK FROM starttime)=1 OR EXTRACT(DAYOFWEEK FROM starttime)=7, true, false) is_weekend, EXTRACT(YEAR FROM starttime)-birth_year as age FROM `bigquery-public-data.new_york_citibike.citibike_trips` WHERE EXTRACT (YEAR FROM starttime)=2018 AND EXTRACT (MONTH FROM starttime)=05 AND (tripduration>=3*60 AND tripduration<=3*60*60) AND birth_year is not NULL AND birth_year < 2007;查询应用了创建训练和评估表时使用的相同逻辑,但仅考虑了 2018 年 5 月的月份。
现在我们已经分割了数据集,并且明确了用于训练、评估和测试阶段的记录,让我们使用 BigQuery ML 训练我们的 DNN 模型。
训练 DNN 模型
既然我们已经将数据集分割成多个表以支持机器学习模型生命周期的不同阶段,让我们使用不同的激活函数来训练我们的深度神经网络(DNN)回归模型:
-
首先,我们可以通过使用
RELU函数开始训练一个 DNN 模型。让我们执行以下 SQL 语句来创建机器学习模型`11_nyc_bike_sharing_dnn.trip_duration_by_stations_day_age_relu`:CREATE OR REPLACE MODEL `11_nyc_bike_sharing_dnn.trip_duration_by_stations_day_age_relu` OPTIONS (model_type='DNN_REGRESSOR', ACTIVATION_FN = 'RELU') AS SELECT start_station_name, end_station_name, is_weekend, age, tripduration as label FROM `11_nyc_bike_sharing_dnn.training_table`;在 SQL 语句中,我们可以注意到用于创建新模型的
CREATE OR REPLACE MODEL关键字。这些关键字后面跟着由数据集和机器学习模型名称连接而成的模型标识符。在这些第一行之后,我们发现
OPTIONS关键字,其中指定了机器学习模型类型。由于我们试图预测连续字段tripduration,我们选择了使用DNN_REGRESSOR作为model_type。在训练深度神经网络(DNN)期间,另一个重要的选项是应用于网络神经元的激活函数。对于这次尝试,我们使用最常见的一种函数:
RELU。这个选择通过ACTIVATION_FN = 'RELU'子句来指定。在
OPTIONS之后,我们需要指定机器学习模型将要训练的记录集。由于我们已经在第四章中识别了相关字段,即使用线性回归预测数值,查询使用start_station_name、end_station_name、is_weekend和age作为 DNN 模型的特征。使用关键词
as label,我们指示 BigQuery ML 将tripduration作为我们机器学习模型的标签。作为替代,我们可以在包含关键词INPUT_LABEL_COLS的OPTIONS列表中包含标签。由于 DNN 是高级且复杂的模型,在收敛到解决方案并生成机器学习模型之前可能需要几分钟。
-
在 SQL 查询执行结束时,我们可以在 BigQuery 导航菜单中选择
trip_duration_by_stations_day_age_reluDNN 模型,并点击tripduration。如以下截图所示,平均绝对误差非常接近 4 分钟:
图 11.2 – 评估选项卡显示了 DNN 模型的一些关键性能指标
-
作为第二次尝试,我们可以尝试更改神经网络中的激活函数,看看是否可以进一步提高第一个模型的表现。让我们使用
CRELU激活函数运行以下 SQL 语句:CREATE OR REPLACE MODEL `11_nyc_bike_sharing_dnn.trip_duration_by_stations_day_age_crelu` OPTIONS (model_type='DNN_REGRESSOR', ACTIVATION_FN = 'CRELU') AS SELECT start_station_name, end_station_name, is_weekend, age, tripduration as label FROM `11_nyc_bike_sharing_dnn.training_table`;训练 DNN 的查询
11_nyc_bike_sharing_dnn.trip_duration_by_stations_day_age_crelu与我们第一次尝试中使用的 SQL 语句非常相似。唯一的区别在于OPTIONS中指定的不同激活函数。使用ACTIVATION_FN = 'CRELU'子句,我们在网络神经元中使用CRELU函数。训练查询的执行将需要几分钟才能完成。
-
在 SQL 查询执行结束时,我们可以在 BigQuery 导航菜单中选择
trip_duration_by_stations_day_age_creluDNN 模型,并在评估选项卡中可视化性能。如以下截图所示,平均绝对误差几乎接近 4 分钟:
图 11.3 – 评估选项卡显示了 DNN 模型的一些关键性能指标
现在,让我们开始评估在本节中训练的 DNN。
评估 DNN 模型
为了评估我们的 BigQuery ML DNNs,我们将使用 ML.EVALUATE 函数以及我们专门创建的作为评估数据集的表格:
-
首先,我们可以开始评估模型
`11_nyc_bike_sharing_dnn.trip_duration_by_stations_day_age_relu`。让我们运行以下查询:SELECT * FROM ML.EVALUATE(MODEL `11_nyc_bike_sharing_dnn.trip_duration_by_stations_day_age_relu`, ( SELECT start_station_name, end_station_name, is_weekend, age, tripduration as label FROM `11_nyc_bike_sharing_dnn.evaluation_table` ));在 SQL 语句中,我们可以注意到使用了关键字
ML.EVALUATE来评估 DNN。评估函数后面跟着 BigQuery ML 模型的标识符:`11_nyc_bike_sharing_dnn.trip_duration_by_stations_day_age_relu`。评估函数应用于提取表
`11_nyc_bike_sharing_dnn.evaluation_table`中所有字段的SELECT语句。几秒钟后,我们可以看到以下截图所示的评估阶段的结果:
图 11.4 – 评估 SQL 语句的结果
我们可以注意到 平均绝对误差 值与我们训练阶段达到的值并没有太大的不同。我们可以说,我们的模型没有受到过拟合的影响,并且在评估数据集的新记录上表现良好。
-
让我们在第二个模型
`11_nyc_bike_sharing_dnn.trip_duration_by_stations_day_age_crelu`上应用相同的评估逻辑。为了评估这个 BigQuery ML 模型的性能,我们运行以下 SQL 语句:SELECT * FROM ML.EVALUATE(MODEL `11_nyc_bike_sharing_dnn.trip_duration_by_stations_day_age_crelu`, ( SELECT start_station_name, end_station_name, is_weekend, age, tripduration as label FROM `11_nyc_bike_sharing_dnn.evaluation_table` ));最后一个查询与上一个查询的唯一区别在于受评估的 DNN 的名称:
`11_nyc_bike_sharing_dnn.trip_duration_by_stations_day_age_crelu`。几秒钟后,我们将看到以下截图所示的评估结果:
图 11.5 – 评估 SQL 语句的结果
此外,在这种情况下,平均绝对误差 值与我们训练阶段达到的 4 分钟值相差不远。这个模型没有受到过拟合的影响,并且与之前的模型相似。
现在我们已经评估了我们的 BigQuery ML 模型,让我们看看如何使用基于 ReLU 激活函数的 DNN 来预测自行车租赁的持续时间。
使用 DNN 模型
在本节中,我们将使用基于 ReLU 函数的 DNN 模型,并训练它利用 BigQuery ML 功能来预测纽约市自行车共享公司的骑行持续时间。
为了测试我们的 DNN,我们将在 prediction_table 表上使用 ML.PREDICT 函数。让我们运行以下 SQL 语句:
SELECT
tripduration as actual_duration,
predicted_label as predicted_duration,
ABS(tripduration - predicted_label) difference_in_min
FROM
ML.PREDICT(MODEL `11_nyc_bike_sharing_dnn.trip_duration_by_stations_day_age_relu`,
(
SELECT
start_station_name,
end_station_name,
is_weekend,
age,
tripduration
FROM
`11_nyc_bike_sharing_dnn.prediction_table`
))
order by difference_in_min asc;
查询语句由一个 SELECT 关键字组成,它提取了租赁的实际和预测持续时间。它计算了分钟数的差异,并按分钟数的最小差异到最大差异排序。为了计算差异,我们使用了 ABS 函数,该函数提取了数字的绝对值。
ML.PREDICT 函数应用于 SELECT 语句,该语句从 prediction_table 中提取特征和实际持续时间。这个最后字段仅用于与预测值进行比较,并且不用于 DNN 返回预测。
在以下屏幕截图,你可以看到查询执行的结果:
图 11.6 – 查询输出显示了实际和预测标签,差异以分钟表示
现在我们已经测试了我们的 BigQuery ML 模型,让我们来看看一些最终的考虑因素,比较基于 CReLU 激活函数的 DNN 结果与我们在 第四章 中使用线性回归所取得的结果,使用线性回归预测数值值。
提炼商业结论
在本节中,我们将应用我们的 DNN 模型,并了解 BigQuery ML 模型能够预测接近实际租赁持续时间的次数。
我们将在之前的查询中添加一个父 SELECT COUNT 语句,以计算实际持续时间与预测值之间的差异小于 15 分钟的次数。
让我们执行以下查询来计算预测的行程持续时间与实际值相差较远的情况发生的频率:
SELECT COUNT (*)
FROM (
SELECT
tripduration as actual_duration,
predicted_label as predicted_duration,
ABS(tripduration - predicted_label) difference_in_min
FROM
ML.PREDICT(MODEL `11_nyc_bike_sharing_dnn.trip_duration_by_stations_day_age_relu`,
(
SELECT
start_station_name,
end_station_name,
is_weekend,
age,
tripduration
FROM
`11_nyc_bike_sharing_dnn.prediction_table`
))
order by difference_in_min asc) where difference_in_min<=15 ;
SELECT COUNT 查询的结果返回了 1,640,446 个预测值,预测值与实际值之间的差异小于 15 分钟。
考虑到 prediction_table 表的总大小为 1,728,078,我们可以说在 94.92% 的情况下,我们的 DNN 能够预测行程持续时间,差异小于 15 分钟。
现在,我们可以将我们用 DNN 达到的最佳结果与我们在 第四章 中使用线性回归模型所达到的性能进行比较,使用线性回归预测数值值。
深度神经网络与线性模型
在以下表格中,基于 CReLU 激活函数的 DNN 模型的结果与线性回归模型进行了比较:
图 11.7 – DNN 模型与线性回归模型的比较
通过查看前面的表格,我们可以得出结论,为了预测纽约市自行车共享服务的行程持续时间,使用 DNN 模型可以获得最佳结果。因此,我们可以建议使用 DNN 模型向公司的客户提供行程持续时间建议。使用 DNN,我们可以将平均绝对误差降低超过 43%。在某些行业中,这样的改进可能为公司带来巨大的竞争优势。
摘要
在本章中,我们实现了两个 DNN。我们回顾了在第四章中已经介绍过的业务场景,即使用线性回归预测数值。用例基于预测纽约市自行车共享服务的租赁时间的需求。之后,我们学习了 DNN 的基础知识以及可以用于实现网络中神经元的各种激活函数。
我们将 BigQuery 公共数据集分割成三个不同的表:一个用于存放训练数据,第二个用于评估阶段,最后一个用于测试我们的 DNN 模型。
在 BigQuery ML 模型的训练阶段,我们测试了两种不同的激活函数,ReLU和CReLU,通过比较平均绝对误差来找到最佳的一个。
之后,我们在一组新的记录上评估了我们的深度神经网络(DNN)模型,以防止过拟合,并对我们 BigQuery ML 模型的高质量更有信心。
最后,我们将基于ReLU函数的模型应用于最后一批记录,以预测每辆自行车租赁的行程时长。我们发现我们的 BigQuery ML 模型能够预测超过 94%的租赁的行程时长,其预测值与实际行程时长相差不超过 15 分钟。
最后,我们还比较了 DNN 模型与在第四章中实现的线性回归结果。我们注意到 DNN 优于线性回归,将平均绝对误差降低了 43%,并且能够为我们业务场景实现更好的结果。
在下一章中,我们将学习如何使用 BigQuery ML 与 GCP AI 笔记本结合使用。
进一步资源
-
纽约市自行车共享公共数据集:
console.cloud.google.com/marketplace/product/city-of-new-york/nyc-citi-bike -
BigQuery ML 创建模型:
cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-create-dnn-models -
BigQuery ML 评估模型:
cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-evaluate -
BigQuery ML 预测:
cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-predict