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

时间:2017-09-03 01:54:12

标签: sql hash google-bigquery cross-validation

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

然而,该博客使用传统SQL,Google has now deprecated支持标准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

3 个答案:

答案 0 :(得分:1)

标准SQL会重写这样的查询:

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

具体来说,这是变化:

  • 将Google Cloud项目与表名分开的句号(非冒号)。
  • 反引号(不是方括号)以转义表名中的连字符。
  • MOD功能(不是%)。
  • FARM_FINGERPRINT(不是HASH)。这实际上是一种与遗留SQL HASH不同的散列函数,wasn't in fact consistent over time正如博客暗示的那样。

答案 1 :(得分:1)

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

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. 使用COUNT次重复数据删除表生成原始数据集中的数据。
  2. 对行进行散列后,增加基于COUNT来选择行的几率。
  3. 由于您不想使用所有COUNT个重复项,因此您可以再次进行哈希操作,以决定应将多大比例的重复项包含在样本集中。 (尽管在数学上一定有更好的方法)

答案 2 :(得分:0)

我在练习中使用的详细版本更少,而不是冗长的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