Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: change qmu API and remove test_stat return #712

Merged
merged 7 commits into from
Jan 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 104 additions & 75 deletions docs/examples/notebooks/binderexample/StatisticalAnalysis.ipynb

Large diffs are not rendered by default.

43 changes: 9 additions & 34 deletions docs/examples/notebooks/hello-world.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Observed: [0.05290116], Expected: [0.06445521]\n"
"Observed: 0.05290116224852556, Expected: 0.06445521290832805\n"
]
}
],
Expand All @@ -67,7 +67,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Observed CL_s: [0.05290116], CL_sb: [0.0236], CL_b: [0.44611493]\n"
"Observed CL_s: 0.05290116224852556, CL_sb: 0.023599998519978738, CL_b: 0.4461149342826869\n"
]
}
],
Expand Down Expand Up @@ -120,13 +120,13 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Observed CL_s: [0.05290116]\n",
"Observed CL_s: 0.05290116224852556\n",
"\n",
"Expected CL_s(-2 σ): [0.00260641]\n",
"Expected CL_s(-1 σ): [0.01382066]\n",
"Expected CL_s : [0.06445521]\n",
"Expected CL_s(1 σ): [0.23526104]\n",
"Expected CL_s(2 σ): [0.57304182]\n"
"Expected CL_s(-2 σ): 0.0026064088679947964\n",
"Expected CL_s(-1 σ): 0.013820657528619273\n",
"Expected CL_s : 0.06445521290832805\n",
"Expected CL_s(1 σ): 0.23526103626937836\n",
"Expected CL_s(2 σ): 0.5730418174887743\n"
]
}
],
Expand All @@ -136,31 +136,6 @@
"for p_value, n_sigma in enumerate(np.arange(-2,3)):\n",
" print('Expected CL_s{}: {}'.format(' ' if n_sigma==0 else '({} σ)'.format(n_sigma),CLs_exp_band[p_value]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Returning the test statistics for the observed and Asimov data**"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"q_mu: [3.93824492], Asimov q_mu: [3.41886758]\n"
]
}
],
"source": [
"CLs_obs, test_statistics = pyhf.infer.hypotest(1.0, [51, 48] + pdf.config.auxdata, pdf, return_test_statistics=True)\n",
"print('q_mu: {}, Asimov q_mu: {}'.format(test_statistics[0], test_statistics[1]))"
]
}
],
"metadata": {
Expand All @@ -179,7 +154,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.6"
"version": "3.7.5"
}
},
"nbformat": 4,
Expand Down
13 changes: 2 additions & 11 deletions src/pyhf/infer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ def hypotest(
return_tail_probs (bool): Bool for returning :math:`\textrm{CL}_{s+b}` and :math:`\textrm{CL}_{b}`
return_expected (bool): Bool for returning :math:`\textrm{CL}_{\textrm{exp}}`
return_expected_set (bool): Bool for returning the :math:`(-2,-1,0,1,2)\sigma` :math:`\textrm{CL}_{\textrm{exp}}` --- the "Brazil band"
return_test_statistics (bool): Bool for returning :math:`q_{\mu}` and :math:`q_{\mu,A}`

Returns:
Tuple of Floats and lists of Floats:
Expand Down Expand Up @@ -74,8 +73,6 @@ def hypotest(

for :math:`\mu'=0` and :math:`N \in \left\{-2, -1, 0, 1, 2\right\}`. These values define the boundaries of an uncertainty band sometimes referred to as the "Brazil band". Only returned when ``return_expected_set`` is ``True``.

- :math:`\left[q_{\mu}, q_{\mu,A}\right]`: The test statistics for the observed and Asimov datasets respectively. Only returned when ``return_test_statistics`` is ``True``.

"""
init_pars = init_pars or pdf.config.suggested_init()
par_bounds = par_bounds or pdf.config.suggested_bounds()
Expand All @@ -84,14 +81,10 @@ def hypotest(
asimov_mu = 0.0
asimov_data = generate_asimov_data(asimov_mu, data, pdf, init_pars, par_bounds)

qmu_v = tensorlib.clip(
qmu(poi_test, data, pdf, init_pars, par_bounds), 0, max_value=None
)
qmu_v = qmu(poi_test, data, pdf, init_pars, par_bounds)
sqrtqmu_v = tensorlib.sqrt(qmu_v)

qmuA_v = tensorlib.clip(
qmu(poi_test, asimov_data, pdf, init_pars, par_bounds), 0, max_value=None
)
qmuA_v = qmu(poi_test, asimov_data, pdf, init_pars, par_bounds)
sqrtqmuA_v = tensorlib.sqrt(qmuA_v)

CLsb, CLb, CLs = pvals_from_teststat(sqrtqmu_v, sqrtqmuA_v, qtilde=qtilde)
Expand All @@ -109,8 +102,6 @@ def hypotest(
_returns.append(CLs_exp)
elif kwargs.get('return_expected'):
_returns.append(pvals_from_teststat_expected(sqrtqmuA_v)[-1])
if kwargs.get('return_test_statistics'):
_returns.append([qmu_v, qmuA_v])
# Enforce a consistent return type of the observed CLs
return tuple(_returns) if len(_returns) > 1 else _returns[0]

Expand Down
6 changes: 3 additions & 3 deletions src/pyhf/infer/test_statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ def qmu(mu, data, pdf, init_pars, par_bounds):
)
qmu = fixed_poi_fit_lhood_val - unconstrained_fit_lhood_val
qmu = tensorlib.where(
muhatbhat[pdf.config.poi_index] > mu, tensorlib.astensor([0]), qmu
)
return qmu
muhatbhat[pdf.config.poi_index] > mu, tensorlib.astensor(0.0), qmu
)[0]
return tensorlib.clip(qmu, 0, max_value=None)
14 changes: 11 additions & 3 deletions src/pyhf/infer/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,16 @@ def _false_case():
return nullval, altval

nullval, altval = tensorlib.conditional(
(sqrtqmu_v < sqrtqmuA_v)[0], _true_case, _false_case
(sqrtqmu_v < sqrtqmuA_v), _true_case, _false_case
)
CLsb = 1 - tensorlib.normal_cdf(nullval)
CLb = 1 - tensorlib.normal_cdf(altval)
CLs = CLsb / CLb
return CLsb, CLb, CLs
return (
tensorlib.reshape(CLsb, (1,)),
tensorlib.reshape(CLb, (1,)),
tensorlib.reshape(CLs, (1,)),
)


def pvals_from_teststat_expected(sqrtqmuA_v, nsigma=0):
Expand All @@ -86,4 +90,8 @@ def pvals_from_teststat_expected(sqrtqmuA_v, nsigma=0):
CLsb = tensorlib.normal_cdf(nsigma - sqrtqmuA_v)
CLb = tensorlib.normal_cdf(nsigma)
CLs = CLsb / CLb
return CLsb, CLb, CLs
return (
tensorlib.reshape(CLsb, (1,)),
tensorlib.reshape(CLb, (1,)),
tensorlib.reshape(CLs, (1,)),
)
1 change: 0 additions & 1 deletion tests/benchmarks/test_benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ def hypotest(pdf, data):
return_tail_probs=True,
return_expected=True,
return_expected_set=True,
return_test_statistics=True,
)


Expand Down
11 changes: 3 additions & 8 deletions tests/test_backend_consistency.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,9 @@ def test_hypotest_q_mu(
backend.session = tf.compat.v1.Session()
pyhf.set_backend(backend)

q_mu = pyhf.infer.hypotest(
1.0,
data,
pdf,
pdf.config.suggested_init(),
pdf.config.suggested_bounds(),
return_test_statistics=True,
)[-1][0]
q_mu = pyhf.infer.test_statistics.qmu(
1.0, data, pdf, pdf.config.suggested_init(), pdf.config.suggested_bounds(),
)
test_statistic.append(pyhf.tensorlib.tolist(q_mu))

# compare to NumPy/SciPy
Expand Down
26 changes: 0 additions & 26 deletions tests/test_infer.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,29 +86,3 @@ def test_hypotest_return_expected_set(tmpdir, hypotest_args):
assert isinstance(result[2], type(tb.astensor(result[2])))
assert len(result[3]) == 5
assert check_uniform_type(result[3])


def test_hypotest_return_test_statistics(tmpdir, hypotest_args):
"""
Check that the return structure of pyhf.infer.hypotest with the
additon of the return_test_statistics keyword arg is as expected
"""
tb = pyhf.tensorlib

kwargs = {
'return_tail_probs': True,
'return_expected': True,
'return_expected_set': True,
'return_test_statistics': True,
}
result = pyhf.infer.hypotest(*hypotest_args, **kwargs)
# CLs_obs, [CLsb, CLb], CLs_exp, CLs_exp @[-2, -1, 0, +1, +2]sigma, [q_mu, q_mu_Asimov]
assert len(list(result)) == 5
assert isinstance(result[0], type(tb.astensor(result[0])))
assert len(result[1]) == 2
assert check_uniform_type(result[1])
assert isinstance(result[2], type(tb.astensor(result[2])))
assert len(result[3]) == 5
assert check_uniform_type(result[3])
assert len(result[4]) == 2
assert check_uniform_type(result[4])
1 change: 0 additions & 1 deletion tests/test_public_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ def test_hypotest(backend, model_setup):
init_pars,
model.config.suggested_bounds(),
return_expected_set=True,
return_test_statistics=True,
)


Expand Down