Javascript 如何使用BigQuery查找置信区间?
我有两个JavaScript函数通过二项测试计算置信区间。当我将其作为任何js代码运行时,这两种方法都能很好地工作。 当我将其集成到查询第二个函数中以查找置信区间上限时,返回NaN。我不明白为什么它在BigQuery中不起作用Javascript 如何使用BigQuery查找置信区间?,javascript,google-bigquery,Javascript,Google Bigquery,我有两个JavaScript函数通过二项测试计算置信区间。当我将其作为任何js代码运行时,这两种方法都能很好地工作。 当我将其集成到查询第二个函数中以查找置信区间上限时,返回NaN。我不明白为什么它在BigQuery中不起作用 CREATE TEMP FUNCTION findConfidenceIntervalFloor(C INT64, L INT64, p FLOAT64) RETURNS FLOAT64 LANGUAGE js AS """ functi
CREATE TEMP FUNCTION findConfidenceIntervalFloor(C INT64, L INT64, p FLOAT64)
RETURNS FLOAT64
LANGUAGE js AS """
function binomial_test(k, n, p){
if(k < 0 || k > n || n <= 0 || p < 0 || p > 1) return NaN;
// i = 0 term
var logcoef = 0;
var pvalue = Math.pow(Math.E, n*Math.log(1-p)); // Math.exp is not available
// i > 0 terms
for(var i = 1; i <= k; i++) {
logcoef = logcoef + Math.log(n-i+1) - Math.log(i);
pvalue = pvalue + Math.pow(Math.E, logcoef + i*Math.log(p) + (n-i)*Math.log(1-p));
}
return pvalue;
}
let CR = L/C
let x1 = 0
let x2 = L
while ((x2 - x1) > 1) {
let x = Math.ceil((x2 - x1) / 2 + x1)
if (binomial_test(x, C, CR) < p/2) {
x1 = x
} else {
x2 = x
}
}
return x2;
""";
CREATE TEMP FUNCTION findConfidenceIntervalCeil(C INT64, L INT64, p FLOAT64)
RETURNS FLOAT64
LANGUAGE js AS """
function binomial_test(k, n, p){
if(k < 0 || k > n || n <= 0 || p < 0 || p > 1) return NaN;
var logcoef = 0;
var pvalue = Math.pow(Math.E, n*Math.log(1-p));
for(var i = 1; i <= k; i++) {
logcoef = logcoef + Math.log(n-i+1) - Math.log(i);
pvalue = pvalue + Math.pow(Math.E, logcoef + i*Math.log(p) + (n-i)*Math.log(1-p));
}
return pvalue;
}
let CR = L/C;
let x1 = L;
let x2 = C;
while ((x2 - x1) > 1) {
let x = Math.ceil((x2 - x1) / 2 + x1);
if (binomial_test(x, C, CR) < (1 - p/2)) {
x1 = x;
} else {
x2 = x;
}
}
return x1;
""";
WITH t0 as (SELECT 'site1' as name, 97000 as clicks, 3784 as leads
UNION ALL
SELECT 'site2', 68099, 2342)
select *,
findConfidenceIntervalFloor(clicks, leads, 0.005) as bot_interval_del,
findConfidenceIntervalCeil(clicks, leads, 0.005) as top_interval_del,
findConfidenceIntervalFloor(clicks, leads, 0.05) as bot_interval_add,
findConfidenceIntervalCeil(clicks, leads, 0.05) as top_interval_add
from t0
现在我用强力除以2。我认为这不是计算它的最佳方法,所以有没有关于如何改进这一点的建议,至少让它在BigQuery中可行
CREATE TEMP FUNCTION findConfidenceIntervalFloor(C INT64, L INT64, p FLOAT64)
RETURNS FLOAT64
LANGUAGE js AS """
function binomial_test(k, n, p){
if(k < 0 || k > n || n <= 0 || p < 0 || p > 1) return NaN;
// i = 0 term
var logcoef = 0;
var pvalue = Math.pow(Math.E, n*Math.log(1-p)); // Math.exp is not available
// i > 0 terms
for(var i = 1; i <= k; i++) {
logcoef = logcoef + Math.log(n-i+1) - Math.log(i);
pvalue = pvalue + Math.pow(Math.E, logcoef + i*Math.log(p) + (n-i)*Math.log(1-p));
}
return pvalue;
}
let CR = L/C
let x1 = 0
let x2 = L
while ((x2 - x1) > 1) {
let x = Math.ceil((x2 - x1) / 2 + x1)
if (binomial_test(x, C, CR) < p/2) {
x1 = x
} else {
x2 = x
}
}
return x2;
""";
CREATE TEMP FUNCTION findConfidenceIntervalCeil(C INT64, L INT64, p FLOAT64)
RETURNS FLOAT64
LANGUAGE js AS """
function binomial_test(k, n, p){
if(k < 0 || k > n || n <= 0 || p < 0 || p > 1) return NaN;
var logcoef = 0;
var pvalue = Math.pow(Math.E, n*Math.log(1-p));
for(var i = 1; i <= k; i++) {
logcoef = logcoef + Math.log(n-i+1) - Math.log(i);
pvalue = pvalue + Math.pow(Math.E, logcoef + i*Math.log(p) + (n-i)*Math.log(1-p));
}
return pvalue;
}
let CR = L/C;
let x1 = L;
let x2 = C;
while ((x2 - x1) > 1) {
let x = Math.ceil((x2 - x1) / 2 + x1);
if (binomial_test(x, C, CR) < (1 - p/2)) {
x1 = x;
} else {
x2 = x;
}
}
return x1;
""";
WITH t0 as (SELECT 'site1' as name, 97000 as clicks, 3784 as leads
UNION ALL
SELECT 'site2', 68099, 2342)
select *,
findConfidenceIntervalFloor(clicks, leads, 0.005) as bot_interval_del,
findConfidenceIntervalCeil(clicks, leads, 0.005) as top_interval_del,
findConfidenceIntervalFloor(clicks, leads, 0.05) as bot_interval_add,
findConfidenceIntervalCeil(clicks, leads, 0.05) as top_interval_add
from t0
当我将其集成到查询第二个函数中以查找置信区间上限时,返回NaN。
我不明白为什么它在BigQuery中不起作用
CREATE TEMP FUNCTION findConfidenceIntervalFloor(C INT64, L INT64, p FLOAT64)
RETURNS FLOAT64
LANGUAGE js AS """
function binomial_test(k, n, p){
if(k < 0 || k > n || n <= 0 || p < 0 || p > 1) return NaN;
// i = 0 term
var logcoef = 0;
var pvalue = Math.pow(Math.E, n*Math.log(1-p)); // Math.exp is not available
// i > 0 terms
for(var i = 1; i <= k; i++) {
logcoef = logcoef + Math.log(n-i+1) - Math.log(i);
pvalue = pvalue + Math.pow(Math.E, logcoef + i*Math.log(p) + (n-i)*Math.log(1-p));
}
return pvalue;
}
let CR = L/C
let x1 = 0
let x2 = L
while ((x2 - x1) > 1) {
let x = Math.ceil((x2 - x1) / 2 + x1)
if (binomial_test(x, C, CR) < p/2) {
x1 = x
} else {
x2 = x
}
}
return x2;
""";
CREATE TEMP FUNCTION findConfidenceIntervalCeil(C INT64, L INT64, p FLOAT64)
RETURNS FLOAT64
LANGUAGE js AS """
function binomial_test(k, n, p){
if(k < 0 || k > n || n <= 0 || p < 0 || p > 1) return NaN;
var logcoef = 0;
var pvalue = Math.pow(Math.E, n*Math.log(1-p));
for(var i = 1; i <= k; i++) {
logcoef = logcoef + Math.log(n-i+1) - Math.log(i);
pvalue = pvalue + Math.pow(Math.E, logcoef + i*Math.log(p) + (n-i)*Math.log(1-p));
}
return pvalue;
}
let CR = L/C;
let x1 = L;
let x2 = C;
while ((x2 - x1) > 1) {
let x = Math.ceil((x2 - x1) / 2 + x1);
if (binomial_test(x, C, CR) < (1 - p/2)) {
x1 = x;
} else {
x2 = x;
}
}
return x1;
""";
WITH t0 as (SELECT 'site1' as name, 97000 as clicks, 3784 as leads
UNION ALL
SELECT 'site2', 68099, 2342)
select *,
findConfidenceIntervalFloor(clicks, leads, 0.005) as bot_interval_del,
findConfidenceIntervalCeil(clicks, leads, 0.005) as top_interval_del,
findConfidenceIntervalFloor(clicks, leads, 0.05) as bot_interval_add,
findConfidenceIntervalCeil(clicks, leads, 0.05) as top_interval_add
from t0
我认为您应该简单地修复函数的签名,以使用FLOAT64而不是INT64,如下所示
CREATE TEMP FUNCTION findConfidenceIntervalFloor(C FLOAT64, L FLOAT64, p FLOAT64)
CREATE TEMP FUNCTION findConfidenceIntervalCeil(C FLOAT64, L FLOAT64, p FLOAT64)
如果您这样做,您将得到输出
Row name clicks leads bot_interval_del top_interval_del bot_interval_add top_interval_add
1 site1 97000 3784 3616.0 3953.0 3666.0 3902.0
2 site2 68099 2342 2210.0 2476.0 2249.0 2435.0
有关更多详细信息,请参阅