Google bigquery BigQuery:计算列的熵

Google bigquery BigQuery:计算列的熵,google-bigquery,entropy,Google Bigquery,Entropy,我有一个建议给BQ的人:我认为如果有一个内置函数可以返回一个列的熵,这将是非常有用的。一列离散的类别或值相对容易。思想?这是否已经存在,但我没有找到它?下面是简单的解决方案-它计算列中不同值的数量,然后以2为底取对数-这给出了编码所有不同值所需的位数,即列熵 SELECT LOG2(COUNT(DISTINCT column)) FROM Table 然而,这并没有考虑到不同的值具有不同的概率这一事实。Shannon熵公式是p(Xi)*log(p(席)),其中p(席)是值席的概率。这里是一个例

我有一个建议给BQ的人:我认为如果有一个内置函数可以返回一个列的熵,这将是非常有用的。一列离散的类别或值相对容易。思想?这是否已经存在,但我没有找到它?

下面是简单的解决方案-它计算列中不同值的数量,然后以2为底取对数-这给出了编码所有不同值所需的位数,即列熵

SELECT LOG2(COUNT(DISTINCT column)) FROM Table
然而,这并没有考虑到不同的值具有不同的概率这一事实。Shannon熵公式是p(Xi)*log(p(席)),其中p(席)是值席的概率。这里是一个例子,在BigQuy中如何计算,Shannon熵在列<代码>年>代码> <代码>出生> <代码>席:< /P>
select -sum(p*log2(p)) from (
select ratio_to_report(c) over() p from (
select year, count(*) c from publicdata:samples.natality group by 1))
更新如果列变量不是离散类型(即浮点),则可以离散值。下面的示例显示了一种方法-首先找到最大值和最小值,计算范围,然后将所有浮点值放入natality表中的weight_pound列)分为100个桶。然后-问题被简化为整数值的熵

select discrete_weight, count(*) from (
select 
  cast((weight_pounds - min_weight) * 100 / range_weight as integer)
    as discrete_weight 
from [publicdata:samples.natality] a cross join 
(select 
  min(weight_pounds) as min_weight, 
  max(weight_pounds) - min(weight_pounds) as range_weight 
from [publicdata:samples.natality]) b) group by 1

非常感谢你,Mosha,这非常有帮助。它工作起来很有魅力,在这个过程中我学到了很多关于BQ的知识!我还没有尝试自己解决这个问题,但是这个想法似乎可以扩展到连续值列,也许可以使用像NTILE()或RANK()这样的东西如果有人已经解决了这个问题,这将节省我的精力;-)再次感谢,摩莎,非常有帮助和启发性。