불확도와 단위은(는) 무엇을 하나요?
범위
이 스킬은 계산이 물리적 단위를 수반하거나 보고된 숫자에 불확도가 필요한 경우에 사용하세요. 구체적으로는:
- 단위 간 변환(물리적 컨텍스트가 필요한 변환 포함: 파장에서 광자 에너지, 질량에서 물질량, 에너지에서 온도)
- 상관되거나 상관되지 않은 입력을 포함한 측정 모델을 통한 불확도 전파
- 교정 증명서, 사양서, 반복성 데이터로부터 GUM 불확도 예산 수립
- 포함 인자 선택 및
k = 2가 방어 가능한지 결정 - 독자가
±의 의미를 알 수 있도록 결과 반올림 및 작성 - 상관 관계를 버리지 않고 곡선 맞춤에서 매개변수 불확도 추출
- 묵시적 단위 및 불확도 결함에 대한 기존 분석 코드 검토
- 차원적으로 일관된 답이 물리적으로도 가능한지 확인 — 크기 차수, 무차원 군, 그리고 그것이 의미하는 영역
이 스킬은 계측(metrology)과 이를 구현하는 두 라이브러리를 다룹니다. 통계적 추론, 모델 선택, 또는 연구 설계는 다루지 않습니다. 해당 내용은 statistical-analysis, statistical-power, experimental-design를 참조하세요.
현재 릴리스 및 설치
2026-07-26 기준 검증됨:
- pint 0.25.3, 2026-03-19 릴리스; Python 3.11+ 필요
- uncertainties 3.2.3, 2025-04-21 릴리스; Python 3.8+ 필요
- NumPy 2.5.1 및 SciPy 1.18.0; 둘 다 Python 3.12+ 필요
- SciPy 1.18.0의
scipy.constants는 CODATA 2022를 제공합니다. SciPy 1.11 및 이전 버전은 CODATA 2018을 제공했으며, 여러 권장 값이 서로 다릅니다.
uv venv --python 3.13
source .venv/bin/activate
uv pip install "pint==0.25.3" "uncertainties==3.2.3" "numpy==2.5.1" "scipy==1.18.0"
pint-pandas와 pint-xarray는 단위 인식 열과 배열을 추가하며 별도로 설치해야 합니다.
비협상 워크플로우
- 입력 시 단위를 첨부하고 출력 시에만 제거하세요.
ureg.wraps또는m_as("unit")를 사용하여 함수 경계에서 변환하고, 계산 중간에서는 절대 하지 마세요. - 측정 모델을 명시적으로 작성하세요. 추정값이 0인 수정 사항을 포함하여, 계산하기 전에 작성하세요. 모델에서 누락된 수정 사항은 예산에서 그 불확도를 누락시킵니다.
- 모든 입력에 네 가지를 제공하세요: 추정값, 표준 불확도, 불확도가 비롯된 분포, 그리고 그 자유도.
- 올바른 제수로 Type B 명세문을 변환하세요. 교정 증명서의 확장 불확도는 명시된
k로 나누고, 직사각형 한계는sqrt(3)으로 나눕니다. - 결합하기 전에 상관 관계를 식별하세요. 동일한 표준으로 교정되었거나, 동일한 기기로 측정되었거나, 동일한 맞춤에서 얻은 입력은 상관 관계가 있습니다.
- 감도 계수를 계산하고, 원시 불확도가 아닌
c_i * u(x_i)에서 예산을 읽으세요. - 선형화를 확인하세요. GUM 프레임워크와 함께 몬테카를로를 실행하고 JCGM 101 8절 비교를 적용하세요. 실패 시 몬테카를로 결과를 보고하세요.
- 습관이 아닌 유효 자유도로
k를 선택하세요. - 불확도를 먼저 반올림한 다음, 동일한 소수 자리로 값을 반올림하세요.
±가 무엇인지 명시하세요 — 표준 또는 확장,k, 포함 확률, 그리고 방법을 포함하여.- 보고 전에 크기를 타당성 검사하세요. 차원적으로 일관된 결과라도 여전히 불가능할 수 있습니다. 알려진 스케일 또는 무차원 군과 비교하고, 의존했던 모든 가정이 해당 영역에서 여전히 유효한지 확인하세요.
이 스킬이 예방하고자 하는 오류들
다음 각각은 오류 없이 실행되며 그럴듯한 숫자를 생성합니다.
알 수 없는 스케일로 제거된 단위
length = (12.7 * ureg.mm).magnitude # 12.7 -- 무엇의?
length = (12.7 * ureg.mm).m_as("m") # 0.0127 미터, 명시됨
.magnitude는 수량이 가지고 있던 값을 그대로 반환합니다. 추출 지점에서 매번 단위를 명시하세요.
오프셋 온도 산술
Q(20, "degC") + Q(5, "degC") # OffsetUnitCalculusError -- 올바르게 거부됨
Q(20, "degC") + Q(5, "delta_degC") # 25 degree_Celsius
Q(25, "degC") - Q(20, "degC") # 5 delta_degree_Celsius
섭씨와 화씨는 간격 척도입니다. 온도에 대한 불확도는 항상 차이이며 delta_ 단위에 속합니다: 20 ± 0.5 degC를 화씨로 변환하면 68 degF ± 0.9 delta_degF가 되며, 한 줄에 두 가지 다른 변환이 발생합니다.
곱셈으로 더해지는 로그 단위
Q(10, "dBm") + Q(10, "dBm") # 0.0001 kilogram**2 * meter**4 / second**6
이는 10 mW × 10 mW이며, 20 mW도 아니고 13 dBm도 아닙니다. 아무것도 오류를 발생시키지 않습니다. 산술 연산 전에 선형 단위로 변환하세요.
왕복으로 파괴된 상관 관계
x = ufloat(1.0, 0.1)
x - x # 0.0+/-0
x - ufloat(x.nominal_value, x.std_dev) # 0.00+/-0.14
공칭 값과 표준 편차로 변수를 재구성하면 독립 변수가 생성됩니다. float 쌍을 통과하는 모든 직렬화도 마찬가지입니다. 상관 집합을 재구성하려면 correlated_values(values, covariance_matrix)를 사용하세요.
묵시적으로 재조정된 공분산 행렬
popt, pcov = curve_fit(f, x, y, sigma=sigma) # 기본값
popt, pcov = curve_fit(f, x, y, sigma=sigma, absolute_sigma=True)
기본값은 pcov를 축소된 카이제곱으로 재조정하므로, 매개변수 불확도가 적합도를 흡수하여 sigma를 전혀 전달하지 않았을 때와 일치하게 됩니다. 하나의 합성 직선 맞춤에서 두 경우는 [0.0364, 0.2154]와 [0.0477, 0.2820]을 제공합니다 — 31% 차이입니다. sigma가 실제 표준 불확도를 담을 때마다 absolute_sigma=True를 전달하세요.
확인되지 않은 선형화
x = 1.0 ± 0.5인 y = x²에 대해, GUM 프레임워크는 y = 1.0, u_c = 1.0, 95% 구간 [-0.96, 2.96]을 제공합니다 — 제곱된 양에 대해 대부분 음수입니다. 몬테카를로는 평균 1.25, u_c = 1.06, 최단 95% 구간 [0, 3.32]를 제공합니다. 선형 전파 라이브러리에서는 이런 일이 발생했음을 알려주지 않습니다.
번들된 로컬 CLI
모든 도우미는 오프라인에서 실행되고, URL과 심볼릭 링크를 거부하며, 입력을 제한하고, 비공개 권한으로 원자적으로 출력을 작성하며, --force 없이는 덮어쓰기를 거부합니다.
python skills/uncertainty-and-units/scripts/propagate_uncertainty.py --help
python skills/uncertainty-and-units/scripts/uncertainty_budget.py --help
python skills/uncertainty-and-units/scripts/format_result.py --help
python skills/uncertainty-and-units/scripts/convert_units.py --help
python skills/uncertainty-and-units/scripts/audit_units.py --help
python skills/uncertainty-and-units/scripts/check_plausibility.py --help
propagate_uncertainty.py
동일한 모델에 대해 두 전파 방법을 모두 실행하고 JCGM 101 8절 검증 테스트를 적용합니다.
python skills/uncertainty-and-units/scripts/propagate_uncertainty.py \
--expression "m / (pi * (d / 2) ** 2 * h)" \
--variable "m=250.0,0.05" \
--variable "d=20.0,0.02,rectangular" \
--variable "h=40.0,0.05,rectangular" \
--measurand density --unit "g/cm3" --format markdown
각 --variable은 name=value,standard_uncertainty[,distribution[,dof]]이며, 분포는 normal, rectangular, triangular, arcsine, 또는 exact이고 몬테카를로 샘플링만 제어합니다. 상관 관계는 --correlation "a,b=0.9"로 입력합니다. 장기적으로 사용할 모델은 JSON --spec 파일에 저장합니다.
표현식은 추상 구문 트리로 파싱되고 + - * / **와 고정된 함수 목록에 대한 명시적 순회를 통해 축소됩니다. 컴파일되거나 실행되지 않습니다.
보고서는 추정값, u_c, 감도 계수, 백분율 예산, 유효 자유도, k, U, 두 몬테카를로 포함 구간, 그리고 선형화된 결과를 보고해도 되는지에 대한 판정을 제공합니다.
uncertainty_budget.py
교정 증명서와 데이터 시트가 명시하는 방식대로 구성 요소를 결합합니다.
python skills/uncertainty-and-units/scripts/uncertainty_budget.py --template > budget.json
python skills/uncertainty-and-units/scripts/uncertainty_budget.py --spec budget.json --format markdown
각 구성 요소는 제수를 결정하는 distribution을 지정합니다. expanded는 coverage_factor로 나누고, rectangular는 sqrt(3), triangular는 sqrt(6), arcsine은 sqrt(2), normal은 1로 나눕니다. 선택적 sensitivity, dof, relative: true가 있습니다. 도구는 u_c, Welch-Satterthwaite 유효 자유도, t-분포로부터의 k, U를 계산하고, Type A 구성 요소에 자유도가 없을 때, nu_eff가 너무 작아 k = 2가 부적절할 때, 하나의 구성 요소가 지배적일 때, 그리고 normal로 선언된 Type B 구성 요소가 아마도 나누지 않은 확장 불확도일 때 경고합니다.
format_result.py
python skills/uncertainty-and-units/scripts/format_result.py \
--value 12.34567 --uncertainty 0.02345 --unit mm \
--coverage-factor 2.26 --coverage-probability 0.95
12.346 ± 0.023 mm, 12.346(23) mm, 과학적 및 LaTeX 형식, 그리고 숫자와 함께 제공되어야 하는 문장을 반환합니다. 1 또는 2로 시작하는 불확도에 대해 유효숫자 하나가 요청될 때, 그리고 불확도가 추정값을 초과할 때 경고합니다.
convert_units.py
python skills/uncertainty-and-units/scripts/convert_units.py \
--value 532 --unit nm --to eV --context spectroscopy --uncertainty 0.5
python skills/uncertainty-and-units/scripts/convert_units.py \
--value 1.0 --unit g --to mol --context chemistry --context-parameter "mw=180.156 g/mol"
변환의 국소 도함수를 통해 불확도를 전달합니다. 이는 컨텍스트 변환이 비례적이기보다는 역수적이기 때문에 중요합니다. 변환에 컨텍스트가 필요할 때 오류 메시지에 컨텍스트를 명명하고, 오프셋 및 로그 단위에 플래그를 지정합니다. --list-contexts는 레지스트리가 정의한 컨텍스트를 보여줍니다.
audit_units.py
기존 분석 코드의 정적 검토. 파싱만 하고, 가져오거나 실행하지 않습니다.
python skills/uncertainty-and-units/scripts/audit_units.py \
--input analysis.py --format markdown --fail-on medium
| 규칙 | 심각도 | 감지 대상 |
|---|---|---|
UNIT001 | medium | 한 모듈에 두 번째 UnitRegistry — 레지스트리 간 ValueError |
UNIT002 | medium | delta_ 단위가 전혀 없는 오프셋 온도 단위 |
UNIT003 | high | 앞에 .to(...) 또는 .m_as(...) 없이 사용된 .magnitude |
UNIT004 | medium | 로그 단위, +가 곱셈을 수행 |
UNC001 | high | absolute_sigma 없이 사용된 curve_fit |
UNC002 | medium | ddof 없이 사용된 np.std / np.var |
UNC003 | medium | uncertainties를 사용하는 모듈에서 사용된 math 또는 numpy 함수 |
UNC004 | high | .nominal_value와 .std_dev로 재구성된 ufloat |
CONST001 | low | CODATA 상수의 0.1% 이내인 리터럴 |
종료 상태는 발견 항목이 --fail-on(기본값 high)에 해당할 때 1이며, 이는 pre-commit 또는 CI 검사로 사용 가능하게 만듭니다.
규칙은 휴리스틱이므로, 지시 주석으로 오탐지를 억제할 수 있습니다. 뒤따르는 주석은 해당 줄을, 줄 단독은 다음 줄을 커버합니다:
value = quantity.magnitude # audit-units: ignore UNIT003 -- 이미 업스트림에서 변환됨
# audit-units: ignore UNC003 -- 여기 인수는 일반 float 배열임
scaled = np.log10(counts)
# audit-units: ignore-file CONST001은 전체 모듈을 커버하고, 규칙을 명명하지 않으면 모두 억제합니다. 억제는 숨겨지지 않고 보고서에 집계되므로, 모든 것을 무음 처리하는 파일도 그 사실을 알립니다.
check_plausibility.py
차원적 일관성은 물리적 가능성을 의미하지 않습니다. 2m 너비의 세포와 모세관에서의 4e7 레이놀즈 수는 모두 모든 단위 검사를 통과합니다. 이 도구는 무차원 군, 특성 스케일, 선별된 크기 대역에 대한 수량 집합을 테스트하고, 숫자를 보고하기 전에 각 공식의 차원을 검증합니다.
python skills/uncertainty-and-units/scripts/check_plausibility.py \
--quantity "density=1060 kg/m**3" --quantity "velocity=0.5 mm/s" \
--quantity "length=8 um" --quantity "viscosity=3.5 mPa*s" \
--group reynolds --format markdown
# Re = 0.001211 -- 층류 (원형 파이프, 길이 = 직경)
python skills/uncertainty-and-units/scripts/check_plausibility.py \
--quantity "diameter=2 m" --band "eukaryotic_cell_diameter=diameter"
# implausible: 5-100 um 범위에서 4.3 자릿수 초과
--group은 14개의 무차원 군 중 하나를 평가하고 시스템이 위치하는 영역을 명명합니다; --scale은 확산 시간, Debye 길이, 또는 Stokes 침강 속도와 같은 특성 스케일을 계산합니다; --band는 제공된 수량을 관측 범위와 비교합니다. --list는 각 공식에 필요한 입력과 함께 전체 카탈로그를 출력합니다.
물리 상수(k_B, N_A, R_gas, g_earth 등)는 제공되지 않아도 모든 공식에서 사용 가능하며, 리터럴로 작성되지 않고 런타임에 scipy.constants에서 읽어오므로 SciPy가 제공하는 CODATA 릴리스를 추적합니다.
차원 검사가 핵심입니다. 공식이 동적 점도를 필요로 하는데 동점도(둘 다 "점도"라고 불리며, 둘 다 물에 대해 표로 작성되며, ρ의 인자만큼 다름)를 전달하면 숫자가 계산되기 전에 거부됩니다:
error: viscosity must have dimensionality [mass] / ([length] * [time]),
but m²/s is [length] ** 2 / [time]
종료 상태는 판정이 --fail-on(기본값 implausible; 대역의 한 자릿수 내에 있는 값은 questionable)에 해당할 때 1입니다. 임계값은 소프트 엣지를 가진 관례이며, 상관 관계가 맞춰진 형상을 가정합니다. 각 경우에 사용할 특성 길이는 references/plausibility-scales.md를 참조하세요.
전파 방법 선택
| 상황 | 방법 |
|---|---|
| 선형 또는 거의 선형 모델, 정규 분포에 가까운 입력, 큰 자유도 | GUM 프레임워크만 |
| 입력의 ±2u 범위에서 비선형성 | 둘 다 실행, 8절 테스트 적용 |
| 입력 중 하나에 대해 약 20% 이상의 상대 불확도 | 둘 다 실행, 8절 테스트 적용 |
| 비대칭 분포 | 몬테카를로 |
| 알려진 공분산을 가진 상관 입력 | GUM 프레임워크 (공분산 행렬과 함께) |
| 모델이 분석적으로 미분 불가능 | 몬테카를로 |
| 독립적인 구성 요소로부터의 예산, 명세서의 Type B | uncertainty_budget.py 사용 |
외부 참조
references/gum-guide-summary.md— JCGM 100:2008 핵심 공식 및 용어references/jcgm-101-summary.md— 몬테카를로 검증 절차 (8절)references/plausibility-scales.md— 각 무차원 군에 대한 특성 길이references/type-a-evaluation.md— 평균, 표준 편차, 자유도
pip install pint, pip install uncertainties를 통해 라이브러리 문서를 로컬에 설치하면 python -m pydoc pint 및 python -m pydoc uncertainties로 읽을 수 있습니다. 온라인 문서는 https://pint.readthedocs.io/ 및 https://uncertainties-python-package.readthedocs.io/에 있습니다.