感度,特異度を求めるユーザー定義のスカラー値関数をSQL Serverで定義する

 前回の記事では階乗を求めるユーザー定義関数を経てFisherの直接確率をストアドプロシージャで求めた.今回は四分表から感度と特異度を求めたい.

四分表とは

 四分表とは表頭に真実の有無,表側に検査の結果を記述した表のことである.

  疾病あり 疾病なし  
検査陽性 a b a+b
検査陰性 c d c+d
  a+c b+d N

感度,特異度とは

 a+cが実際に疾病のある人数,aはそのうち検査で陽性となった人数である.感度とはa/(a+c)のことである.

 b+dが実際に疾病のない人数,dはそのうち検査で陰性となった人数である.特異度とはd/(b+d)のことである.

 ちなみに a/(a+b) を陽性的中率,d/(c+d) を陰性的中率という.

 b は検査が陽性でも実際には疾病のない人数のことで,偽陽性という.

 c は検査が陰性でも実際には疾病のある人数のことで,偽陰性という.

受信者動作特性曲線とは

 Receiver Operating Characteristic curve といい,頭文字を取って ROC 曲線という.もともとはレーダー技術であって,雑音の中から敵機を検出する受信者の特性を測るための方法として開発された.横軸に 1 – 特異度,縦軸に感度をプロットすると下図のような曲線が描かれる.曲線は原点,(0, 1), (1, 1) の範囲内に描かれ,点 (0,1) に近いほど検査として有効であるとされる.

死亡の日最高気温のROC
死亡の日最高気温のROC

感度,特異度を求めるユーザー定義のスカラー値関数

 繰り返しになるが感度とは a/(a+c), 特異度とは d/(b+d) が定義である.これをSQL Serverのユーザー定義関数に実装する.

 下図のように「プログラミング」「関数」を右クリックして「新規作成」「スカラー値関数…」へと進む.

「プログラミング」「関数」「新規作成」「スカラー値関数...」
「プログラミング」「関数」「新規作成」「スカラー値関数…」

 下記コードをクエリウィンドウに記述し実行する.引数は本来整数型であるが,SQL Server では整数の計算結果は整数に丸められるため,割り算の際に問題となる.そのため引数のデータ型を小数型で定義している.なお,Specificity を求める関数は名前が違うだけで,やっていることは第一引数を第二引数で割るだけの同じ処理である.

  • 1行目 USE 句で関数を組み込むデータベースを指定する
  • 3行目 CREATE FUNCTION で関数名を定義する
  • 5行目と6行目,関数名の次の ( ) 内で引数とそのデータ型を定義する.引数が複数ある場合はコンマで区切る
  • 8行目 RETURNS で戻り値のデータ型を定義する
  • 10行目以降 BEGIN から END までで関数の内容を定義する
  • 13行目 RETURN で関数に戻り値を代入する
USE [HeatStrokeDB]
GO
CREATE FUNCTION [dbo].[Sensitivity]
(
	@a	FLOAT,
	@b	FLOAT
)
RETURNS FLOAT
AS
BEGIN
	DECLARE @ResultVar	FLOAT
	SET	@ResultVar = @a/@b
	RETURN	@ResultVar
END

感度,特異度をストアドプロシージャに組み込む

 ここまで来たら日最高気温と熱中症の重症度別の搬送人員数を検討するで使用したストアドプロシージャにこれらの関数を組み込んでしまおう.ユーザー定義関数(ここでは Sensitivity あるいは Specificity)の前にdbo.を書き加えておかないと,「組み込み関数名として認識されません」というエラーが出る.

USE [HeatStrokeDB]
GO
ALTER PROCEDURE [dbo].[Temperature_Death] 
	@Temperature int
AS
BEGIN
SELECT	@Temperature							AS '閾値'
,	SUM(CASE WHEN E.[傷病程度:死亡] > 0 AND T.日最高気温 >= @Temperature THEN 1 ELSE 0 END)	AS a
,	SUM(CASE WHEN E.[傷病程度:死亡] = 0 AND T.日最高気温 >= @Temperature THEN 1 ELSE 0 END)	AS b
,	SUM(CASE WHEN E.[傷病程度:死亡] > 0 AND T.日最高気温 <  @Temperature THEN 1 ELSE 0 END)	AS c
,	SUM(CASE WHEN E.[傷病程度:死亡] = 0 AND T.日最高気温 <  @Temperature THEN 1 ELSE 0 END)	AS d
,	SUM(CASE WHEN E.[傷病程度:死亡] > 0 THEN 1 ELSE 0 END)		AS 'a+c'
,	SUM(CASE WHEN E.[傷病程度:死亡] = 0 THEN 1 ELSE 0 END)		AS 'b+d'
,	SUM(CASE WHEN T.日最高気温 >= @Temperature THEN 1 ELSE 0 END)	AS 'a+b'
,	SUM(CASE WHEN T.日最高気温 <  @Temperature THEN 1 ELSE 0 END)	AS 'c+d'
,	COUNT(*)							AS N
,	dbo.Sensitivity(SUM(CASE WHEN E.[傷病程度:死亡] > 0 AND T.日最高気温 >= @Temperature THEN 1 ELSE 0 END)
,	SUM(CASE WHEN E.[傷病程度:死亡] > 0 THEN 1 ELSE 0 END))		AS 'Sensitivity'
,	dbo.Specificity(SUM(CASE WHEN E.[傷病程度:死亡] = 0 AND T.日最高気温 <  @Temperature THEN 1 ELSE 0 END)
,	SUM(CASE WHEN E.[傷病程度:死亡] = 0 THEN 1 ELSE 0 END))		AS 'Specificity'
,	1 - dbo.Specificity(SUM(CASE WHEN E.[傷病程度:死亡] = 0 AND T.日最高気温 < @Temperature THEN 1 ELSE 0 END)
,	SUM(CASE WHEN E.[傷病程度:死亡] = 0 THEN 1 ELSE 0 END))		AS '1-Specificity'
FROM	dbo.T_HeatStroke	AS E
INNER JOIN	dbo.T_MaxTemperature	AS T
ON	E.日付 = T.年月日
AND	E.都道府県コード = T.都道府県コード
END
GO

まとめ

 SQL Serverのユーザー定義関数で感度と特異度を定義し,四分表を作成するストアドプロシージャを定義した.ここからROC曲線を描くことができる.閾値を求めるまであと一歩である.

“感度,特異度を求めるユーザー定義のスカラー値関数をSQL Serverで定義する” への1件の返信

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください