Вычислить интервал очков Уилсона

15

Уилсон оценка интервал является доверительным интервалом вероятности успеха, основываясь на доле успехов в наборе испытаний Бернулли (испытание Бернулли является исследованием , в котором ровно два результата возможен: успех или неудача ). Интервал задается следующей формулой:

Интервал Уилсона

Два значения, заданные формулой, являются верхней и нижней границами интервала. n S и n F - количество успехов и неудач соответственно, а n - общее количество испытаний (эквивалентно n S + n F ). z - параметр, зависящий от желаемого уровня достоверности. Для целей этой задачи будет использоваться z = 1,96 (что соответствует доверительному интервалу 95%) 1 .

Учитывая неотрицательные целые числа n S и n F , выведите границы интервала оценки Вильсона.

правила

  • Выходные данные должны быть максимально точными к истинным значениям в пределах реализации вашего языка с плавающей запятой, игнорируя любые потенциальные проблемы из-за арифметических неточностей с плавающей запятой. Если ваш язык допускает арифметику с произвольной точностью, он должен быть как минимум настолько же точным, как арифметика двойной точности IEEE 754.
  • Входные данные будут в пределах представимого диапазона для родного целочисленного типа вашего языка, а выходные данные будут в пределах представимого диапазона для родного типа с плавающей запятой вашего языка.
  • n всегда будет позитивным.
  • Порядок выводов не имеет значения.

Тестовые случаи

Формат: n_s, n_f => lower, upper

0, 1 => 0.0, 0.7934567085261071
1, 0 => 0.20654329147389294, 1.0
1, 1 => 0.09452865480086611, 0.905471345199134
1, 10 => 0.016231752262825982, 0.3773646254862038
10, 1 => 0.6226353745137962, 0.9837682477371741
10, 90 => 0.05522854161313612, 0.1743673043676654
90, 10 => 0.8256326956323345, 0.9447714583868639
25, 75 => 0.17545094003724265, 0.3430464637007583
75, 25 => 0.6569535362992417, 0.8245490599627573
50, 50 => 0.40382982859014716, 0.5961701714098528
0, 100 => 0.0, 0.03699480747600191
100, 0 => 0.9630051925239981, 1.0

  1. zЗначение является 1-α/2й квантиль стандартного нормального распределения, где αнаходится уровень значимости. Если вы хотите 95% доверительного интервала, ваш уровень значимости является α=0.05и zзначение 1.96.
Mego
источник
Связанный: проблема самого быстрого оружия на Западе . Я собирался сделать это вызов, но я думаю, что вы победили меня в этом. : /
mbomb007

Ответы:

6

Mathematica, 48 байт (кодировка UTF-8)

({-1,1}√((s=1.4^4)##/+##+s^2/4)+#+s/2)/(s+##)&

Безымянная функция, принимающая два аргумента в порядке n_s, n_fи возвращающая упорядоченную пару действительных чисел. Трехбайтовый символ , представляющий функцию квадратного корня, является U-221A.

Использует тот факт, что предшествующее ##число приводит к произведению двух аргументов, а +##приводит к их сумме. Также используется тот факт, что продукты и суммы автоматически пронизывают списки, что {-1,1}√(...)реализует ± в формуле. Определение константы s = z^2вместо zнее также позволило сэкономить пару байтов. (В основном я просто горжусь тем, что сохранил байт, заметив, что 1.4^4это точно 1.96^2!)

Грег Мартин
источник
Может ли Mathematica использовать произвольные кодировки? Символ квадратного корня составляет 1 байт во многих однобайтовых кодировках.
Mego
Он действительно может использовать много кодировок, например, Mac OS Roman, у которого есть указанное вами свойство. Однако я понимаю, что мне нужно будет включить байты, необходимые для переключения на кодировку не по умолчанию, которая в этом случае превышает 2 «потраченных впустую» байта.
Грег Мартин
О, это требует переключателя командной строки (или некоторого вызова функции)? Валовой.
Mego
4
Mathematica - это удивительное сопоставление удивительного и грубого: D
Грег Мартин
3

Perl 6 , 66 байт

->\s,\f,\z=1.96 {(s+(-z|z)*sqrt(s*f/(s+f)+z*z/4)+z*z/2)/(s+f+z*z)}

Эта функция фактически возвращает ор-соединение нижней и верхней границ; например, если вызывается с аргументами 100 и 0, возвращается:

any(0.963005192523998, 1)

Это, по меньшей мере, нетрадиционный формат вывода, но не был указан конкретный формат, и присутствуют оба обязательных значения.

Шон
источник
Мне кажется, это нормально. Отсутствие определенного формата вывода было преднамеренным - требование определенного формата для вывода дает преимущества для некоторых языков и излишне усложняет задачу. Пока оба выходных значения присутствуют в некоторой пригодной для использования форме, это приемлемо.
Mego
3

05AB1E , 34 байта

"1.96"Dn©4/¹P¹O/+t*D()®;+¹0è+®¹O+/

Вход имеет вид [n_s, n_f]
Выход имеет вид[upper, lower]

Попробуйте онлайн!

объяснение

"1.96"                             # push 1.96
      Dn©                          # duplicate, square, store a copy in register
         4/                        # divide by 4
           ¹P¹O/                   # product of input divided by sum of input
                +                  # add this to (z^2)/4
                 t*                # sqrt and multiply with z
                   D()             # wrap in list together with a negated copy
                      ®;+          # add (z^2)/2
                         ¹0è+      # add n_s
                             ®¹O+/ # divide by z^2+n
Emigna
источник
3

Рунические чары , 105 байт

#StillBetterThanJava

/:2,:2,i:3s:3s:i:3s*3s+::6s4s,+'qA{*:Z4s3TRr4s{++}\
\p2:,C1Ä'<> yyyyyyyyyyyyyyyyyyy'Ä1C,2p:2,//@S ',+ /

Попробуйте онлайн!

Входные данные имеют вид n_s n_f
Выходные данные имеют вид lower upperи имеют завершающий пробел

Боже мой, это беспорядок. Вот развернутая версия:

>'Ä1C,:2p:2,:2,i:3s:3s:i:3s*3s+::6s4s,+'qA{*:Z4s3TRr4s{++}+,' S@
                  > yyyyyyyyyyyyyyyyyyy'Ä1C,2p:2,//

Все yэто должно замедлить второй IP, чтобы он Tдостиг точки передачи в нужное время (т.е. второй). Это перемещает верхние 3 элемента одного указателя на другой (настройка этого действия показана ниже). 'Ä1C,генерирует zпутем деления символа 196 на 100 (dup, square, dup, div 2, dup, div 2 ...). Все остальное - просто набор математических и стековых манипуляций, чтобы сбрасывать будущие значения в стек, пока они не понадобятся. По большей части они оказываются в правильном порядке, и только до тех пор r4s{++}, пока нам не понадобится перевернуть стек и повернуть все это, чтобы получить нужные значения рядом друг с другом.

Вероятно, есть место для улучшения, но оно достаточно сложное, чтобы я его не видел. Черт, случайно прочитал «z» вместо «n» в исходной формуле в какой-то момент, и исправить это было грубо.

Мне нужно было вытащить карточки и смоделировать стопки, чтобы убедиться, что это правильно:

Stack Funtimes

Каждый из них имеет значение на обоих концах из-за того, сколько было переменных (например, у меня была бы одна с S и одна с F, я бы совал их обе, перевернул одну и добавил S + F, который был на другой конец к вершине стека). Вы можете видеть, что одна из sqrt(...)карт имеет Sнижний край.

Draco18s больше не доверяет SE
источник
3

R , 58 53 51 49 41 байт

-15 байт благодаря Дж. Доу. -2 байта благодаря Джузеппе.

function(x,y)prop.test(t(c(x,y)),cor=F)$c
Роберт С.
источник
1
Мне нравится, когда R соперничает с языками игры в гольф ...
J.Doe
2

APL (Dyalog Unicode) , 50 байтов

{(+/⍺⍵z)÷⍨(⍺+z÷2)(-,+).5*⍨z×(⍺×⍵÷⍺+⍵)+4÷⍨z3.8416}

Попробуйте онлайн!

NsNе .

Спасибо H.PWiz и dzaima за помощь.

Как:

                                        z3.8416   Set z=1.96²
                                     4÷⍨           Divide it by 4
                                    +              plus
                           (⍺×⍵÷⍺+⍵)              (nf×nsn
                         z×                        ×z²
                     .5*⍨                          to the power .5 (square root)
                (-,+)                              ±
         (⍺+z÷2)                                   ns+(z²/2)
(+/⍺⍵z)÷⍨                                         all divided by nf+ns+z²
Ж. Салле
источник
@ Adám Это не выражение и не полная программа, но вы можете сделать это выражение, инициализировав zего при самом правом использовании: ...÷z+(z←1.908)++для того же количества байтов. Также: ⊣×⊢÷+->×÷+
ngn
1
@ngn Правильно, но на самом деле это допускается двойным мета-консенсусом: (1) и (2) .
Адам
1

Python, 79 67 байт

lambda s,f,z=3.8416:2j**.5*(s-(-z*(f*s/(f+s)+z/4))**.5+z/2)/(f+s+z)

Выход - это сложное целое число с интервалом, хранящимся как вещественная / мнимая часть.

orlp
источник
1

постоянный ток , 71 байт

16k?dsa2*?sb1.96 2^dso+dlalb4**lalb+/lo+vlov*dsd+lalblo++2*dsx/rld-lx/f

Принимает оба входа в две отдельные строки при вызове и выводит в две отдельные строки с верхней границей внизу и нижней границей на сверху .

Например:

bash-4.4$ dc -e '16k?dsa2*?sb1.96 2^dso+dlalb4**lalb+/lo+vlov*dsd+lalblo++2*dsx/rld-lx/f'
10                # Input n_s
90                # Input n_f
.0552285416131361 # Output lower bound
.1743673043676654 # Output upper bound
Р. Кап
источник
1

Ракетка 134 байта

(let*((n(+ s f))(z 1.96)(h(* z z))(p(/ 1(+ n h)))(q(+ s(/ h 2)))(r(* z(sqrt(+(/(* s f) n)(/ h 4))))))(values(* p(- q r))(* p(+ q r))))

Ungolfed:

(define (g s f)
  (let* ((n (+ s f))
         (z 1.96)
         (zq (* z z))
         (p (/ 1 (+ n zq)))
         (q (+ s (/ zq 2)))
         (r (* z (sqrt (+ (/(* s f) n) (/ zq 4))))))
    (values (* p (- q r)) (* p (+ q r)))))

Тестирование:

(g 1 10)

Выход:

0.016231752262825982
0.3773646254862038
rnso
источник
1

Java 7, 130 байт

Golfed:

double[]w(int s,int f){double n=s+f,z=1.96,x=z*z,p=s+x/2,d=z*Math.sqrt(s*f/n+x/4),m=1/(n+x);return new double[]{m*(p-d),m*(p+d)};}

Ungolfed:

double[] w(int s, int f)
{
    double n = s + f, z = 1.96, x = z * z, p = s + x / 2, d = z * Math.sqrt(s * f / n + x / 4), m = 1 / (n + x);
    return new double[]
    { m * (p - d), m * (p + d) };
}

Попробуйте онлайн

Возвращает массив типа double длины 2, вероятно, может быть больше в гольфе.

Peech
источник
1

> <> с -vфлагом, 100 байт

:{:@:}*@+:@,24a,a,-:@:*:&4,+:\$~*{&:&2,+}:{:@@-{&+:&,nao+&,n;
,}:{::*@@-:0$0(?$-1a,:*:*:*(?\}:{:@,+2

Ожидает, что входные данные будут присутствовать в стеке в начале выполнения, в порядке n_s, n_f. Попробуйте онлайн!

Какой глупый язык, чтобы попытаться это в ...

Поскольку> <> не хватает оператора степени или корневого оператора, квадратный корень вычисляется во второй строке кода с использованием вавилонского метода с точностью 1e-8- для каждого примера, который я пробовал, с точностью не менее 10 десятичных знаков. Если это не достаточно точно, границы могут быть ужесточены, добавив больше:* во второй строке, перетасовывая вещи, чтобы сохранить зеркала в линии.

Вывод в следующем виде:

<lower bound>
<upper bound>
Sok
источник
1

Pyth, 38 байт

J*K1.96Kmc++dhQcJ2+sQJ_B*K@+cJ4c*FQsQ2

Ввод в виде списка значений [n_s, n_f]. Вывод: [upper, lower]попробуйте онлайн здесь или проверьте все тестовые примеры сразу здесь .

J*K1.96Kmc++dhQcJ2+sQJ_B*K@+cJ4c*FQsQ2   Implicit: Q=eval(input())

  K1.96                                  Set variable K=1.96 (z)
J*K    K                                 Set variable J=K*K (z^2)
                                *FQ      Product of input pair
                               c   sQ    Divide the above by the sum of the input pair
                            cJ4          J / 4
                           +             Add the two previous results
                          @          2   Take the square root of the above
                        *K               Multiply by K
                      _B                 Pair the above with itself, negated
        m                                Map each in the above, as d, using:
             hQ                            First value of input (i.e. n_s)
               cJ2                         J / 2
          ++d                              Sum the above two with d
         c                                 Divided by...
                  +sQJ                     ... (J + sum of input)
Sok
источник
1

Желе , 30 байт

×÷++1.96²©HH¤×®½×Ø-+®H¤+³÷++®ɗ

Попробуйте онлайн!

объяснение

                   Inputs: s and f
×÷+                (s×f)÷(s+f)
    1.96²©HH¤      (© ← 1.96²)÷4      (call this W)

   +                         (s×f)÷(s+f)+W
             ×®             ((s×f)÷(s+f)+W)ש
               ½      sqrt[ ((s×f)÷(s+f)+W)ש ]   (call this R)

                ×Ø-            [   -R,      +R  ]
                   +®H¤        [©/2-R,   ©/2+R  ]
                       +³      [©/2-R+s, ©/2+R+s]

                         ÷           Divide both by:
                          ++®ɗ       (s+f)+©

Заметка

Некоторые из этих функций новее, чем вызов. Я полагаю, что в то время, когда этот вызов был опубликован, ++®¶×÷++1.96²©HH¤×®½×-,1+®H¤+³÷çбыл действительно Jelly (32 байта), не хватает ɗи Ø-.

Линн
источник
1

APL (NARS), 49 символов, 98 байтов

{k←1.9208⋄(2+n÷k)÷⍨(1+⍺÷k)+¯1 1×√1+2×⍺×⍵÷k×n←⍺+⍵}

тестовое задание

  f←{k←1.9208⋄(2+n÷k)÷⍨(1+⍺÷k)+¯1 1×√1+2×⍺×⍵÷k×n←⍺+⍵}
  25 f 75
0.17545094 0.3430464637 
  0 f 1
0 0.7934567085 
  1 f 0
0.2065432915 1 
RosLuP
источник