【发布时间】:2022-01-18 05:45:10
【问题描述】:
我想使用 PyTorch 报告我的数据的 90、95、99 等置信区间。但是置信区间似乎太重要了,不能让我的实现未经测试或受到批评,所以我想要反馈——至少应该由一些专家检查。此外,我已经注意到当我的值为负时我得到了 NaN 值,这让我认为我的代码只适用于分类(至少),但我也做回归。我也很惊讶直接使用 numpy 代码实际上给了我可微的张量......不是我所期待的。
那么这样对吗?:
import numpy as np
import scipy
import torch
from torch import Tensor
P_CI = {0.90: 1.64,
0.95: 1.96,
0.98: 2.33,
0.99: 2.58,
}
def mean_confidence_interval_rfs(data, confidence=0.95):
"""
https://stackoverflow.com/a/15034143/1601580
"""
a = 1.0 * np.array(data)
n = len(a)
m, se = np.mean(a), scipy.stats.sem(a)
h = se * scipy.stats.t.ppf((1 + confidence) / 2., n - 1)
return m, h
def mean_confidence_interval(data, confidence=0.95):
a = 1.0 * np.array(data)
n = len(a)
m, se = np.mean(a), scipy.stats.sem(a)
h = se * scipy.stats.t.ppf((1 + confidence) / 2., n - 1)
return m, m - h, m + h
def ci(a, p=0.95):
import numpy as np, scipy.stats as st
st.t.interval(p, len(a) - 1, loc=np.mean(a), scale=st.sem(a))
# def ci(a, p=0.95):
# import statsmodels.stats.api as sms
#
# sms.DescrStatsW(a).tconfint_mean()
def compute_confidence_interval_classification(data: Tensor,
by_pass_30_data_points: bool = False,
p_confidence: float = 0.95
) -> Tensor:
"""
Computes CI interval
[B] -> [1]
According to [1] CI the confidence interval for classification error can be calculated as follows:
error +/- const * sqrt( (error * (1 - error)) / n)
The values for const are provided from statistics, and common values used are:
1.64 (90%)
1.96 (95%)
2.33 (98%)
2.58 (99%)
Assumptions:
Use of these confidence intervals makes some assumptions that you need to ensure you can meet. They are:
Observations in the validation data set were drawn from the domain independently (e.g. they are independent and
identically distributed).
At least 30 observations were used to evaluate the model.
This is based on some statistics of sampling theory that takes calculating the error of a classifier as a binomial
distribution, that we have sufficient observations to approximate a normal distribution for the binomial
distribution, and that via the central limit theorem that the more observations we classify, the closer we will get
to the true, but unknown, model skill.
Ref:
- computed according to: https://machinelearningmastery.com/report-classifier-performance-confidence-intervals/
todo:
- how does it change for other types of losses
"""
B: int = data.size(0)
# assert data >= 0
assert B >= 30 and (not by_pass_30_data_points), f' Not enough data for CI calc to be valid and approximate a' \
f'normal, you have: {B=} but needed 30.'
const: float = P_CI[p_confidence]
error: Tensor = data.mean()
val = torch.sqrt((error * (1 - error)) / B)
print(val)
ci_interval: float = const * val
return ci_interval
def compute_confidence_interval_regression():
"""
todo
:return:
"""
raise NotImplementedError
# - tests
def ci_test():
x: Tensor = abs(torch.randn(35))
ci_pytorch = compute_confidence_interval_classification(x)
ci_rfs = mean_confidence_interval(x)
print(f'{x.var()=}')
print(f'{ci_pytorch=}')
print(f'{ci_rfs=}')
x: Tensor = abs(torch.randn(35, requires_grad=True))
ci_pytorch = compute_confidence_interval_classification(x)
ci_rfs = mean_confidence_interval(x)
print(f'{x.var()=}')
print(f'{ci_pytorch=}')
print(f'{ci_rfs=}')
x: Tensor = torch.randn(35) - 10
ci_pytorch = compute_confidence_interval_classification(x)
ci_rfs = mean_confidence_interval(x)
print(f'{x.var()=}')
print(f'{ci_pytorch=}')
print(f'{ci_rfs=}')
if __name__ == '__main__':
ci_test()
print('Done, success! \a')
输出:
tensor(0.0758)
x.var()=tensor(0.3983)
ci_pytorch=tensor(0.1486)
ci_rfs=(tensor(0.8259), tensor(0.5654), tensor(1.0864))
tensor(0.0796, grad_fn=<SqrtBackward>)
x.var()=tensor(0.4391, grad_fn=<VarBackward>)
ci_pytorch=tensor(0.1559, grad_fn=<MulBackward0>)
Traceback (most recent call last):
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevd.py", line 1483, in _exec
pydev_imports.execfile(file, globals, locals) # execute the script
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "/Users/brandomiranda/ultimate-utils/ultimate-utils-proj-src/uutils/torch_uu/metrics/metrics.py", line 154, in <module>
ci_test()
File "/Users/brandomiranda/ultimate-utils/ultimate-utils-proj-src/uutils/torch_uu/metrics/metrics.py", line 144, in ci_test
ci_pytorch = compute_confidence_interval_classification(x, by_pass_30_data_points)
如何修复上面的代码以进行回归,例如任意大小的负值?
考虑到 CI 应该是多么重要……也许是深度学习的坏习惯,目前还没有实现,尤其是官方 PyTorch 还没有实现,这有点令人惊讶?不幸的是,很少在论文中看到它。
参考资料:
- 交叉发布:https://discuss.pytorch.org/t/what-is-the-proper-way-to-compute-95-confidence-intervals-with-pytorch-for-classification-and-regression/139398
- Compute a confidence interval from sample data
- https://machinelearningmastery.com/report-classifier-performance-confidence-intervals/
- https://medium.com/hal24k-techblog/how-to-generate-neural-network-confidence-intervals-with-keras-e4c0b78ebbdf
- https://discuss.pytorch.org/t/variance-or-confidence-interval-for-outputs/91043
- https://github.com/WangYueFt/rfs/blob/master/eval/meta_eval.py
- Calculate the accuracy every epoch in PyTorch
- Construct 95% confidence interval for regression model
- https://www.quora.com/unanswered/How-do-you-calculate-a-95-confidence-interval-for-a-simple-regression
- https://www.quora.com/unanswered/What-is-the-95-confidence-interval-in-regression
- https://www.quora.com/unanswered/What-is-the-proper-way-to-compute-95-confidence-intervals-with-PyTorch-for-classification-and-regression
- https://stats.stackexchange.com/questions/556265/what-is-the-proper-way-to-report-confidence-intervals-or-std-variance-for-mac
【问题讨论】:
-
pytorch 论坛中的相同问题:discuss.pytorch.org/t/…
-
您可以考虑在datascience.stackexchange.com 上提问。
-
@TimRoberts 可能不允许交叉发布...那么您有什么建议?我觉得 SO 总的来说也很强大 - 特别是对于实现/编码 - 这就是我在这里选择它的原因,但它有点武断......必须在某个地方发布!。
-
无论您是否将其留在这里,我都认为您会在 Data Science Stack Exchange 上得到更集中的响应。
标签: python machine-learning pytorch statistics pytorch-lightning