多產線混批的抽驗命中機率

本頁目錄

程式碼:examples/r/sampling-probability/

問題

幾條產線各有不同的不良率,產出混在一起出貨。客戶連續驗了 4 批,每批抽 1 包,一次都沒抽到不良

這代表什麼?是我們運氣好,還是不良率其實沒那麼高?

模型

分兩層:

① 單抽命中機率 p  ← 各產線不良率,以「產量佔比」加權
② n 批的中批數    ← Binomial(n, p_batch)
single_draw_p <- function(qty, rate) {
  total <- sum(qty)
  sum((qty / total) * rate)          # 加權平均
}

hit_distribution <- function(qty, rate, n_batch, m_per_batch = 1) {
  p       <- single_draw_p(qty, rate)
  p_batch <- 1 - (1 - p)^m_per_batch   # 每批抽 m 包,任一包不良就算中
  k       <- 0:n_batch
  prob    <- dbinom(k, size = n_batch, prob = p_batch)
  list(p_single = p, p_batch = p_batch,
       table = data.frame(k = k, prob = prob),
       p_none = prob[1], p_at_least1 = 1 - prob[1],
       expected = n_batch * p_batch)
}

算一次

B 產線 12,497 件、不良率 19.08%;C 產線 52,503 件、全良品。總共 65,000 件。

單抽命中機率 p = 0.036684 (3.6684%)

連續 4 批、每批抽 1 包:
 k     prob     pct
 0 0.861144 86.1144
 1 0.131171 13.1171
 2 0.007493  0.7493
 3 0.000190  0.0190
 4 0.000002  0.0002

P(一次都沒中)  = 86.11%
P(至少中 1 批) = 13.89%

四批全過完全不能證明沒問題。 就算真的有 19% 不良的一整條產線混在裡面, 四批每批抽一包也有 86% 的機率一次都抓不到。 「沒抽到」不是「沒有」——這是抽樣檢驗最重要、也最常被誤解的一件事。

反過來用:要驗幾批才夠

這才是這個模型真正有用的地方。

batches_needed <- function(qty, rate, conf = 0.95, m_per_batch = 1) {
  p_batch <- 1 - (1 - single_draw_p(qty, rate))^m_per_batch
  ceiling(log(1 - conf) / log(1 - p_batch))
}
=== 每批多抽幾包的效果(連續 4 批)===
  每批抽  1 包:P(至少中 1 批) =  13.89%
  每批抽  2 包:P(至少中 1 批) =  25.84%
  每批抽  3 包:P(至少中 1 批) =  36.14%
  每批抽  5 包:P(至少中 1 批) =  52.64%
  每批抽 10 包:P(至少中 1 批) =  77.57%

=== 要幾批才有 95% 把握抓到 ===
  每批抽 1 包 -> 需要 81 批
  每批抽 2 包 -> 需要 41 批
  每批抽 5 包 -> 需要 17 批

多抽幾包比多驗幾批有效率得多。 這個數字可以直接拿去跟客戶或主管討論抽驗計畫。

前提:這個加權平均什麼時候不成立

p = Σ (qty_i / total) × rate_i 假設抽出來的那一包是從混合後的整體隨機抽的

不成立的情況:

情況 為什麼不能用加權平均
每批只來自某一條產線 該批的 p 就是那條線自己的不良率,不是平均
依產線分棧板、抽樣時只抽某幾板 抽到的機率不等於產量佔比
不良集中在某個時段 同一條線內部也不是均勻的

批次沒有真正混合的話,加權平均會嚴重低估風險。 如果客戶剛好整批都拿到 B 產線的貨,他看到的是 19.08%,不是 3.67%。 用這個模型之前先確認:出貨批是不是真的混過?

二項還是超幾何

dbinom() 假設抽出放回(或母體無限大)。嚴格說抽驗是不放回,該用超幾何分布 dhyper()

但當批量 ≫ 抽樣數時兩者幾乎相同。經驗法則:抽樣數 < 批量的 10% 就用二項分布,誤差可以忽略。

65,000 件抽 4 包,比例是 0.006%——差異在小數點後很多位,不用理會。

反過來,批量 50 件抽 5 件(10%)就該用超幾何:

# 批量 N=50,其中 D=10 件不良,抽 n=5 件,抓到 k 件的機率
dhyper(k, m = 10, n = 40, k = 5)

輸入正規化的歧義

原始版本有這個貼心設計:

norm_rate <- function(x) {
  if (x > 1) x <- x / 100     # 允許填 19.08 或 0.1908
  x
}

方便,但有個無法消除的歧義:使用者輸入 0.5,是 0.5% 還是 50%?

依這個規則會被當成 50%——差了一百倍,而且不會有任何警告。

處理方式二選一:

# 方式一:接受寬鬆輸入,但介面上明確標示規則,並加上範圍檢查
normalize_rate <- function(x) {
  x <- as.numeric(x)
  if (is.na(x) || x < 0) stop("不良率不能為負數")
  if (x > 100) stop(sprintf("不良率 %g 超出範圍", x))
  if (x > 1) x / 100 else x        # 標籤要寫清楚:「>1 視為百分比」
}

# 方式二:強制單位,不猜
# numericInput("B_def", "B 產線不良率 (%)", value = 19.08, min = 0, max = 100)
# rate <- input$B_def / 100

方式二比較好。 少一個猜測就少一種錯法,而且 0.5% 這種真實會出現的低不良率才填得進去。

你該檢查的

  • 出貨批是不是真的混合過?沒混的話加權平均不成立
  • 抽樣數有沒有超過批量的 10%?超過要改用超幾何
  • 不良率輸入的單位是否明確?0.5 會被解讀成什麼?
  • 有沒有把「四批全過」當成「沒問題」的證據?

回到頂端

MIT License — 範例程式可自由取用。

This site uses Just the Docs, a documentation theme for Jekyll.