繁体   English   中英

如何在 BigQuery Standard SQL 中进行可重复采样?

[英]How to do repeatable sampling in BigQuery Standard SQL?

此博客中,一位 Google Cloud 员工解释了如何在 BigQuery 中为机器学习进行可重复的数据集采样。 这对于创建(和复制)数据的训练/验证/测试分区非常重要。

然而,该博客使用了 Legacy SQL, Google 现在已弃用它而支持标准 SQL。

您将如何使用标准 SQL 重新编写如下所示的博客示例代码?

#legacySQL
SELECT
  date,
  airline,
  departure_airport,
  departure_schedule,
  arrival_airport,
  arrival_delay
FROM
  [bigquery-samples:airline_ontime_data.flights]
WHERE
  ABS(HASH(date)) % 10 < 8

标准 SQL 会这样重写查询:

#standardSQL
SELECT
  date,
  airline,
  departure_airport,
  departure_schedule,
  arrival_airport,
  arrival_delay
FROM
  `bigquery-samples.airline_ontime_data.flights`
WHERE
  ABS(MOD(FARM_FINGERPRINT(date), 10)) < 8

具体变化如下:

  • 将 GCP 项目与表名分开的句点(不是冒号)。
  • 反引号(不是方括号)以转义表名中的连字符。
  • MOD函数(不是% )。
  • FARM_FINGERPRINT (不是HASH )。 这实际上是一个与 Legacy SQL 的HASH不同的散列函数,正如博客所暗示的那样, 随着时间的推移,它实际上并不一致

根据接受的答案,提供一种更通用的方法来为每一行生成唯一键:

TO_JSON_STRING(STRUCT(col1, col2, ..., colN))

#standardSQL
SELECT
  date,
  airline,
  departure_airport,
  departure_schedule,
  arrival_airport,
  arrival_delay
FROM
  `bigquery-samples.airline_ontime_data.flights`
WHERE
  ABS(MOD(FARM_FINGERPRINT(TO_JSON_STRING(STRUCT(date, airline, arrival_delay))), 10)) < 8

如果没有唯一键来标识每一行怎么办?

是的,您的数据集中可能存在设计重复的数据行,使用上述查询,样本集中包含所有重复数据或不包含任何重复数据行。

根据您的数据集有多大,您可以尝试对源数据集进行排序并使用窗口函数为每一行生成一个 row_number。 然后根据 row_number 进行采样。 此技巧将一直有效,直到您对数据集进行排序时遇到错误:

查询执行期间资源超出:无法在分配的内存中执行查询。

如果我确实遇到了上述错误怎么办

好吧,上面的方法实现起来更简单,但如果你达到了极限,请考虑做一些更复杂的事情:

  1. 生成一个重复数据删除表,其中包含它在原始数据集中出现的次数。
  2. 对行进行哈希处理后,根据 COUNT 增加一行被选中的几率。
  3. 由于您不想使用所有 COUNT 个重复项,您可以再次进行散列以决定样本集中应包含多少重复项。 (虽然必须有一些更好的数学方法)

我在实践中使用更TO_JSON_STRING(STRUCT(col1, col2, ..., colN))版本,而不是冗长的TO_JSON_STRING(STRUCT(col1, col2, ..., colN))

TO_JSON_STRING(t)

FORMAT('%t', t)   

如下例所示

#standardSQL
SELECT 
  date,
  airline,
  departure_airport,
  departure_schedule,
  arrival_airport,
  arrival_delay
FROM
  `bigquery-samples.airline_ontime_data.flights` t
WHERE
  MOD(ABS(FARM_FINGERPRINT(FORMAT('%t', t))), 10) < 8   

#standardSQL
SELECT 
  date,
  airline,
  departure_airport,
  departure_schedule,
  arrival_airport,
  arrival_delay
FROM
  `bigquery-samples.airline_ontime_data.flights` t
WHERE
  MOD(ABS(FARM_FINGERPRINT(TO_JSON_STRING(t))), 10) < 8   

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM