感度=陽性的中率の特性

概要

機械学習のモデルの性能や感染症検査の確からしさを検証する際、陽性的中率(適合度)や陰性的中率を確認すべきだが、これらの値が、そもそものデータの特性やモデル/検査の性能によってどのように変化するかを確認する。

具体的には、注目事象の率と真陽性率(感度)・真陰性率(特異度)を変化させたときの、陽性的中率・陰性的中率の変化を見る。

これらの値の意味や計算方法については、Confusing matrixを参照。

その結果から、以下のようなことがわかった。

  • 予測モデルや検査において、単に感度のみを向上させても適合度(陽性的中率)は大きく変化しない
  • 特異度を向上させることで適合度は大きく向上する
  • ターゲット比率がとても小さい場合、感度・特異度をかなり大きくしても、適合度は小さな値になる

2020年現在、世界的に大きな影響を及ぼしているCOVID-19(新型コロナウィルス)感染症のPCR検査では、一般に感度が70%程度、特異度が90%以上、陽性的中率が数%程度という値が多い。感度が7割程度というのは少し低く、陽性的中率がそもそも小さすぎるという気がしていたが、上記のことと符合することがわかった。

指標

以下の指標を、目的として計算する指標とする。

  • PPV(Positive Predicted Value):陽性的中率、適合度、Precision
  • NPV(Negative Predicted Value):陰性的中率

これらの指標を計算するために用いる指標は以下の通り。

  • TR(Target Rate):注目事象の全体比率(ターゲット比率)
  • TPR(True Positive Rate):真陽性率、感度(Sencitivity)
  • TNR(True Negative Rate):真陰性率、特異度(Specificity)

例えば感染症の例で言うと、有病率(TR)、検査の感度(TPR)、特異度(TNR)がわかっているときに、陽性的中率(PPV)、陰性的中率(NPV)を求めることに相当する。

PPV・NPVの計算式の導出

元データの構成

まず、confusing matrixを以下のように表現する。これは、データ数で表現されたテーブルの各要素を全データ数で割った率で表すことに相当する。

     \begin{align*} \begin{array}{cc|cc|c} & & \mathrm{Prediction}\\ & & \mathrm{Positive} & \mathrm{Negative} & \mathrm{Sum} \\ \hline \mathrm{Fact} & \mathrm{Positive} & tp & fn & r_1 \\ & \mathrm{Negative} & fp & tn & r_2 \\ \hline & \mathrm{Sum}& c_1 & c_2 & 1 \end{array} \end{align}

PPV・NPVの計算式

まず、事実(Fact)がpositiveである率がr1に相当し、これはTR (target rate)に等しい。このTRと率TPRを使って、Positiveの行のtp(true positive)とfn (false negative)の率を計算。

(1)    \begin{align*} r_1 &= TR \\ tp &= r_1 \cdot TPR = TR \cdot TPR \\ fn &= r_1 \cdot (1 - TPR) = TR (1 - TPR) \end{align*}

2行目の合計r2については、行和の合計が1になることから以下のように計算される。

(2)    \begin{align*} r_2 &= 1 - r_1 = 1 - TR \end{align*}

このr2と率TNRからNegativeの行のtn(true negative)とfp (false positive)を計算。

(3)    \begin{align*} tn &= r_2 \cdot TNR = (1 - TR) TNR \\ fp &= r_2 (1 - TNR) = (1 - TR) (1 - TNR) \end{align*}

tpとfpからc1を、tnとfnからc2を計算。

(4)    \begin{align*} c_1 &= tp + fp = TR \cdot TPR + (1 - TR) (1 - TNR) \\ c_2 &= tn + fn = (1 - TR) TNR + TR (1 - TPR) \end{align*}

PPV(陽性的中率、感度)はc1に対するtpの率で計算される。以下の式は分数の分数で若干ややこしいが、3つの指標が1回ずつ現れ、整った形になる。

(5)    \begin{align*} PPV &= \frac{tp}{c_1} = \frac{TR \cdot TPR}{TR \cdot TPR + (1 - TR) (1 - TNR) } \\ &= \frac{1}{1 + \left(\dfrac{1}{TR} - 1 \right) \dfrac{1 - TNR}{TPR}} \end{align*}

NPV(陰性的中率、特異度)はc2に対するtnの率で計算される。以下の式とPPVの式を比べると、はTRの分数項ついて逆数であり、TPRTNRが入れ替わっていて、PPVNPVで対称性がある。

(6)    \begin{align*} NPV &= \frac{tn}{c_2} = \frac{(1 - TR) TNR}{(1 - TR) TNR + TR (1 - TPR)}\\ &= \frac{1}{1 + \dfrac{TR}{1 - TR} \dfrac{1 - TPR}{TNR}} \end{align*}

パラメーターに応じたPPV・NPVの変化

PPV

上記の結果を用いて、ターゲット比率、真陽性率(感度)、真陰性率(特異度)の様々な値に対するPPV(陽性的中率)、NPV(陰性的中率の変化を観察する。

まず、ターゲット比率が1に近い(ほとんどがターゲットとなるような)状態から、ターゲットが0に近いような(ターゲットとなるデータがほとんどないような)状態の間で、PPVがどのように変化するか確認してみる。

TPR(感度)の値によって曲線の形に若干の変化はあるがあまり大きくは変わらず、むしろTNR(特異度)の値による曲線の形状の変化が大きい。ここでTRが0.1~0と小さい範囲のところを見てみる。

やはり感度の影響はあまり大きくないようである。TNRを大きくするにしたがって曲線の形状は大きく変化し、ターゲット比率が小さいところでの適合度が向上するが、ターゲット比率が0に近いところではPPVがかなり小さくなる。

次に、TPRを変化させたときの曲線の違いが分かるように、表示させる変数を入れ替えてみる。まずTRが1~0の全域。

やはり感度による曲線の変化は小さく、特異度の影響が大きい。以下のようにTRが0.1~0の範囲を拡大しても同様の傾向。

以上の結果から、以下のことが言える。

  • ターゲット比率が低くなるほどNPVは小さくなる(適合度が低くなり、予測/検査の信頼性が下がる)
  • 予測モデルや検査のTPR(感度)を上げることによるPPVの向上効果はあまり大きくない(いたずらに感度を上げても顕著な効果はない)
  • TNR(特異度)の向上によって、適合度は大きく向上する
  • ターゲット比率がとても小さい場合、その率の現象に従って適合度は急激に低下する

さらにこれを一般的な表現でまとめると、

  • 予測モデルや検査において、単に感度のみを向上させても適合度(陽性的中率)は大きく変化しない
  • 特異度を向上させることで適合度は大きく向上する
  • ターゲット比率がとても小さい場合、感度・特異度をかなり大きくしても、適合度は小さな値になる

NPV

PPVと同様にNPVについても計算してみた。

まずいくつかのTPRに対して、TNRを変化させて曲線を描いたもの。PPVの場合と比べて形状が左右逆で、TNRを固定してTPRを変化させたときの図と同じ傾向。

次に、いくつかのTNRを固定してTPRを変化させたもの。これもPPVと形状、TPRTNRの関係が逆になっている。

PPVとNPVの関係

PPVNPVが同じTPRTNRに対してどのように変化するか重ねてみる。

TPRとTNRを同程度とすることでターゲット比率0.5付近で双方が等しくなり、その値を高くすることで、より広い範囲でPPVが向上する。

シミュレーションによる挙動確認

これまでの結果は、confusion matrixの各要素にTR、TPRなどの比率を適用してPPV、NPVを計算した。この方法は、ある予測/判定が理論通りに再現された場合だが、実際にはターゲットとなる事象の割合も、予測がpositive/negativeになる割合も確率事象である。

そこで念のため、多数の二値(True/False)正解データをランダムに生成し、これに対してTPR、TNRの設定に従った答えを出す疑似的なモデルで「予測」する。その結果を整理したconfusion_matrixからPPVを計算したのが以下の図である。

その結果は計算式による場合と同じで、理論上の挙動と実世界で起こるであろう挙動が一致している。

処理内容は以下の通り。

  • 与えられたTrue/Falseに対して、あらかじめ設定したTPR/TNRと一様乱数に従ってTrue/Falseを「予測」する疑似予測モデルを準備
  • TR=1~0の間で100個のデータについてPPVを計算する
    • 1つのTRについて10万個の2値正解データを生成
    • 正解データセットを疑似予測モデルに適用して予測データセットを得る
    • 予測データセットからconfusion matrixを構成し、その要素からPPVを計算し、配列に格納
  • 以上の結果をプロット

 

罹患率と有病率

概要

2020年、COVID-19(新型コロナウイルス)の感染は続き、PCR検査が毎日のように各都道府県で行われている。これに伴って検査の信頼性がときどき話題になることがある(もっと真面目に議論されてもいいと思うが)。偽陽性/偽陰性などについて、一度Bayes理論などによって自分でトレースしてみようとしたときに、有病率と罹患率の違いがあることがわかってきたので、一度まとめてみる。

有病率

有病率を簡単に言うと、ある時点において、人口に対して疾病にかかっている人の割合、ということになる。Prevalence rateまたは単にPrevelanceと呼ばれることも多い。

より正確には、有病率rPは以下のように定義される。

(1)    \begin{equation*} r_P = \frac{N_C}{N_R}} \end{equation*}

ここでNCはある時点における疾病者数(C: Contract)、NRは当該疾病のリスクを有する母集団の人数(R: Risk)。

とはいっても、当該疾病リスクを有する人を除外することはなかなか難しいので、対象とするエリアの人口を近似値として用いるのが一般的らしい。

また、ある時期と言っても疾病者数や人口の調査にはそれなりの時間がかかるため、ある期間に調査した結果を「いついつ時点」としたその時点で扱われるだろう。

有病率は0~1の実数だが、通常は対人口千人あたりとか10万人あたりで示されることが多いとのことである。

ここでPrevalenceという言葉は、流行するとか行き渡るといった意味であり、ある疾病がある時点でどれだけ広がっているか、というイメージになるだろう。

罹患率/発生率

罹患率を簡単に言うと、ある期間において対象とする疾病リスクを有する者が罹患する割合、ということになる。有病率はIncidence rateまたは単にIncidenceと言われることが多い。本来の意味で言うと「発生率」の方がより妥当で、実際にその用語も使われている。ちなみにincidentは出来事、incidenceは(望ましくない事象の)発生率・頻度という意味。

より正確には、罹患率rIは以下のように定義される。

(2)    \begin{equation*} r_I = \frac{N_I}{N_R}} \end{equation*}

ここでNIはある期間内に新たに罹患した人の数(I: Incidence)、NRは観察期間内に当該疾病のリスクを有する集団の延べ人数(R: Risk)。

分子の方は新たに罹患した人の数なので、観察期間より前から罹患している人は含まれない。

有病率と罹患率(発生率)

有病率はある時点tにおける罹患者の数を表し、罹患率はある期間Δtにおける新たな罹患者数を表す。いわば有病率は罹患者の関数値、罹患率は罹患者数の変化率のうち発生による増加率を表すことになる(時間で除していないので罹患が広がるスピードの概念は含まれていない)。

また、罹患率以外に疾病が治癒する人、疾病により死亡する人、観察エリア外に出て行ってしまう人はいずれも負の変化率に相当するが、これらを含めた(あるいはこれらを総括した「罹患減少率」のような)パラメーターはあまり登場しない。

したがって、この2つのデータだけを見ていると、罹患者数が増大しているのに有病率が変化しなかったり減少する場合がある。

なお、有病率にしても罹患率にしても一定の期間で捕捉しなければならないが、一つ違う点は、対象となる期間より前から罹患していた人は罹患率の場合分母・分子の両方から除かれるという点である。一般に中止するエリアの人口に比べてそのような人の数は少ないので、近似的には既罹患者の分だけ率が小さくなる。

(3)    \begin{align*} \lim_{N \rightarrow \infty} \frac{N_C - N_{Cprev}}{N - N_{Cprev}} = \lim_{N \rightarrow \infty} \frac{\dfrac{N_C - N_{Cprev}}{N}}{1 - \dfrac{N_{Cprev}}{N}} = \frac{N_C - N_{Cprev}}{N} \end{align*}

どういうときにどちらを使うか

以上の点を踏まえると、有病率と罹患率はそれぞれ次のような場合に有用と思われる。

有病率

その時点時点での、疾病への対策を検討する場合。たとえば、

  • 疾病に対する薬品を準備するのにどの程度の総量が必要か検討する場合
  • 地域や国などの対策重点度を判断する場合

罹患率

疾病の発生状況を重視する場合。たとえば、

  • 感染症などの拡大期に、その危険性を判断する場合の一つの指標として
    • ここで「一つの指標」としたのは、その他に有病期間、致死率など「単に罹っただけ」で騒ぐのではない判断要素も必要と考えたため。
  • 疾病に対する予防法の効果を検証する場合

PCR検査?

2020年9月時点、COVID-19(新型コロナウイルス)の発症は続いており、PCR検査に関する議論も喧しい。個別の陽性反応に対してどのように対処するかという議論と別に、そもそもPCR検査の偽陽性/偽陰性、陽性/陰性的中率を議論するときは、有病率と罹患率のどちらを使うのが適切だろうか。

まず罹患率の方を考えてみる。

各都道府県でPCR検査が毎日行われているが、陽性率とのセットで考えるなら、PCR検査の結果もリアルタイムに近い形で(少なくともそういう思想で)発生者の全容を捉えるべきだろう。ところがその数は日単位で悉皆の調査というレベルには程遠い(日本に限らずこれはどこの国もそうだ)。一か月程度で各都道府県の全人口の検査ができるなら月単位での罹患者増加状況は捉えられるが、それでも実現性には難があり、スピードが遅すぎる。まして一週間単位で(しかも毎週?)そのようなことをしようとするのも無理だ。したがって、PCR検査に対して罹患率の考えを適用するのは難しいだろう。考えてみれば、罹患率の場合は既発生者が除かれるのだから、ヒアリングか何かで期間前に罹患していた人を除外しなければ分母と分子で意味が違ってしまう。

となると、PCR検査でいろいろとデータをいじるのは、有病率を使って、ということになる。

「期間前の既発生者も除かない」ということと、検査で陽性/陰性になった人の状況からその時点での全容を推測する、という点から見れば、Bayes理論で条件付確率を計算するときなどに用いるのは有病率だろう。

まとめ

罹患率と有病率の区別は、医学・疫学の世界ではあたりまえとされていることが、あまり伝わっていない例の一つだ。違いを説明しようとするとやっかいだが、そういうことを明快に伝えて、受け取る側も腹に落とすことができれば一番いいのだが。

これはIT業界、建設業界でも同じで、説明に関する意識の問題(その前段の必要性を感じるかどうかの問題)であるとともに、門外の専門家や一般の多くの人の側が理解しようとする文化も大切かもしれない。技術・政策や危機管理に関するコミュニケーションの問題(発する側、受ける側のどちらも)に通ずると思う。

 

複利計算

概要

複利計算でいろいろなサイトを見るが、どれも前提なしで話を始めたりいきなりExcelの関数を使ったりするものばかりで、スタートラインからどう考えているのかを説明するものにあたらなかった(きっとあるのだろうけれど)。

なので、自分なりの頭の整理のために一から組み立ててみる。

預金の複利計算

一時払い

一時払いは、最初に一定金額を預けた後は預金口座に手を触れずに、満期や解約の時にいくらになるかというもので、これは比較的わかりやすい。たとえば年率1%の預金に100万円を預けたら10年後にいくらになっているか、というような計算。表計算で計算すると以下のようになる。

このとき、以下のような仕組みだということを明記しておく。

  • 期首の途中に預けても、期末までに年利率がすべて適用される(日割りなどはされない)
  • その年利率を適用した利子が期首金額に加えられ、翌期の期首金額となる
  • 毎年の利子の計算の際、小数点以下は切り落としている

これくらいだと、元本に対して利率1%を定額で10年適用した結果と変わらない。ところが50年も置いておくと最終金額は16,443円になり、定額の15,000円との乖離が大きくなってくる。

年利率を2%にすると様相が変わってきて、10年後の利子は2,186円、50年後には利子分で16,873円になる。

50年間の預金額の変化を1%、2%の定額と複利で比較してみると以下のようになる。

所謂指数関数で、利率が大きくなると、あるいは期間が長くなるとカーブの上がり方が急になる。

こういった計算は高校で数列を習うと教えてくれる。たとえば上の例で、預入金額をa、年利率をRとするとn年目の期末残高bは以下のように表される。

(1)    \begin{equation*} b = a (1+R)^n \end{equation*}

この式に上の金額や利率、年数を入れると同じ結果が出ることが確認できる。式で計算した方が数円額が大きくなるが、これは表計算の際に端数を切り落としたのに対して、数式では丸めずに計算するからである。

積立て

たとえば毎年10万円を積み立てながら年利率1%を適用した時にどうなるか。この場合は、前期末の金額に積立額を加えた額が期首金額となり、以下のような結果になる。

これを定式化するのに次のように考える。毎月a円を積み立てるとして1年目の期末金額b1は、

(2)    \begin{equation*} b_1 = a (1+R) \end{equation*}

2年目の期末残高は、この期末残高にa円を加えて利率を適用するので、

(3)    \begin{equation*} b_2 = (b_1 + a) (1+R) = \left( a (1+R) + a \right) (1+R) = a(1+R) + a(1+R)^2 \end{equation*}

これをn年目まで繰り返すと、最終的な残高は以下のようになる。各月に預けた額ごとに、現在までの利子が複利で適用されて積み重なっているのが表現されている。

(4)    \begin{equation*} b_n = a (1+R) + a (1+R)^2 + \cdots + a(1+R)^n \end{equation*}

これは初項がa (1 + R)、公比が1 + Rの等比数列の和になるので、預金残高は以下の式で計算できる。

(5)    \begin{align*} b_n &= a (1+R) \frac{1 - (1+R)^n}{1 - (1+R)} = a(1+R) \frac{(1+R)^n - 1}{R} \\ &=a \frac{(1+R)^{n+1} - R - 1}{R} \end{align*}

借金の複利計算

元利均等返済方式

借金を返す場合、期首に残っている額に利子を掛けた要返済額から各期の返済額を引いた額が翌期首の残額となる。利率は年率表示だが、返済は月ごととし、月利率=年利率÷12とする。

年利3%で120万円を借り入れて、毎月返済して12か月で返すケースを考え、月ごとの額を同額としたいとする。試みに、120万円に利子がつかないとすると毎月10万円を返せばいいが、この場合は積み重なっていく利子の分だけ返しきれない。

次に120万円に対して12か月間の月利率を複利で適用すると120×1.002512≒123万6500円。これを12か月で割ると、突き当りの返済額は約1万3千円となる。これは毎月の返済を全くしない想定なので、実際に借入残高が減っていくのに対して返しすぎることになる。

この2つの値の間で二分法で答えを探していくと、以下の額に到達する。この時の利子の総額は19,584円で、借り入れの利回りは約1.632%になる。

これを数式で表現してみる。借入額をa、月利をr、返済額pとすると、一月目の借入残額b1は、

(6)    \begin{equation*} b_1 = a (1+r) - p \end{equation*}

二月目の借入残額b2は、一月目の残額に月利を適用してから返済するので、

(7)    \begin{align*} b_2 &= b_1 (1+r) - p = \left( a (1+r) - p \right) (1+r) - p \\ &= a (1+r)^2 - p (1+r) - p \end{align*}

これは、n月までに借入額に複利で計算した額に対して、返す方も毎月の月数に応じた複利で足し上げて返しますよということになる。これをn月後まで続けた残額bnは以下のようになる。

(8)    \begin{align*} b_n &= a (1+r)^n - p (1+r)^{n-1} - \cdots - p \\ &= a (1+r)^n - p \frac{1 - (1+r)^n}{1 - (1+r)} \\ &= a (1+r)^n - p \frac{(1+r)^n - 1}{r} \end{align*}

n月目で残額がゼロとなるようにすると、毎月の返済額pは以下で表される。

(9)    \begin{align*} p = a (1+r)^n \frac{r}{(1+r)^n - 1} \end{align*}

先ほどの計算では手計算で収束させたが、利率が与えられたときの元利均等の返済額は解析的に求めることができる。表計算ソフトの関数も、この煩雑な関数をシンプルに表現しているに過ぎない。

元本均等方式

元金均等方式は借入額を返済期数で割って均等とし、これに毎期の発生する利子を加えて返済する。この場合の利子総額は19,500円で、借り入れ利回りは1.625%となる。

借入額をa、借り入れ期数をm、月利をr、一月目の借入利子i1とすると、残額b1は、

(10)    \begin{equation*} b_1 = a (1+r) - \frac{a}{m} - ar = a - \frac{a}{m} \end{equation*}

二月目の残額b2は、

(11)    \begin{equation*} b_2 = b_1 (1+r) - \frac{a}{m} - b_1 r = b_1 - \frac{a}{m} = a - 2 \frac{a}{m} \end{equation*}

これを繰り返してn月目の残額は、

(12)    \begin{equation*} b_n = a - n \frac{a}{m} \end{equation*}

n期目の利子額inは、n − 1期末の残額に利率を適用して、以下で計算される。

(13)    \begin{equation*} i_n = \left( a - (n - 1) \frac{a}{m} \right) r \end{equation*}

アドオン方式

この方法は、単利計算に相当し、元本とそれに対する利子の総額を期数で割って均等化した額を返済する。利率は年率を用いて利子を計算し、これを月ごとに均等に割る。これまでの例で計算すると、利子総額は36,000円で、借り入れ利回りは3%。

毎月の返済額pは、借入額aに年利Rをそのまま適用して期数mで割ればよい。

(14)    \begin{equation*} p = \frac{a (1 + R)}{m} \end{equation*}

比較

元利均等方式は、初期の残額が大きいときの利子を後期に分担させて返済額を均等にする。返済計画が明瞭になるため、一般的なローンに用いられる。

これに対して元本均等方式は初期の残額に対する利子をそのまま負担するので、元利均等方式に比べて初期の利払いが多くなる。逆に早い段階から大きな額で返済していくため、トータルの利払いは元本均等方式の方が元利均等方式よりも少なくなる。企業の資金借入れはこの方法が多い。

アドオン方式は返済中の元利の減少を全く考慮しないため、利払いが最も大きくなる。毎月の返済額が一定で計算も簡単なため、割賦販売の場合に用いられる。