fullseye

どの大きさなら見つかるか(検出確率 POD と a90/95、MIL-HDBK-1823A)

できること

検査の性能を「この大きさの傷は何 % の確率で見つかるか」で言います。欠陥の大きさ a と検査系の応答 â(あるいは見つけた/見落とした)の組から、POD(a) 曲線・a50・a90・a90/95(90 % の確率で見つかると 95 % の信頼で言える最小の大きさ)と、無欠陥部位の応答から誤検出確率を出します。手順は非破壊検査の信頼性評価の公開ハンドブック MIL-HDBK-1823A のとおりです。

What it does

Probability of detection per MIL-HDBK-1823A: â-vs-a regression with left and right censoring (a Tobit-type maximum likelihood, concave in Olsen’s coordinates, reducing exactly to least squares when nothing is censored), the POD(a) curve with a50 / a90 / a90/95 by the delta method, the hit/miss generalised linear model with both Wald and likelihood-ratio a90/95, false-call probability from unflawed sites (binomial one-sided bounds that reproduce the handbook’s PFP table to 7.2e-05), and the decision-threshold trade-off. Estimates agree with an independently written likelihood minimised by a different algorithm to 6.6e-08. The delta-method a90/95 covers the true a90 in 94.3 % of large-sample replicates but only 89.2 % at n=60 — reported, not hidden. A slope that cannot be told from zero is refused rather than turned into an absurd a90, and an a90/95 beyond the largest size tested carries a flag.

向くところ / 向かないところ

最初の 1 本

import numpy as np
import fullseye as fs

# 傷の大きさ a と応答 â(雑音床 0.3 で左打ち切り)
rng = np.random.default_rng(0)
a = np.exp(rng.uniform(np.log(0.1), np.log(2.0), 80))
ahat = np.exp(1.0 + 1.5 * np.log(a) + rng.normal(0.0, 0.4, a.size))
fit = fs.ledger.pod_ahat_fit({"a": a, "ahat": ahat}, log_size=True, log_response=True,
                             censor_low=0.3)
pod = fs.ledger.pod_from_ahat(fit, 1.0)
print("打ち切り %d 点 / a50 %.3f / a90 %.3f / a90/95 %.3f"
      % (fit["n_censored"], pod["a50"], pod["a90"], pod["a90_95"]))

# 無欠陥部位の応答から誤検出確率(0 回でも 0 にはしない)
noise = np.exp(rng.normal(-1.5, 0.4, 150))
fc = fs.ledger.pod_false_call(noise, 1.0)
print("誤検出 %d / %d、PFP50 %.4f" % (fc["n_false"], fc["n"], fc["pfp50"]))

裏づけ