Fisher の確率はカットオフ値の関数であると以前書きました.今回は下記のクエリで ROC 曲線を描き,Fisherの直接確率検定を行います.ROC 曲線では横軸に偽陽性率を取り,縦軸に感度を取ります.カットオフ値を横軸に取り,Fisher の確率を縦軸にグラフを描くと,グラフの最小値に該当するカットオフ値が求めるものとなります.ただし,p
CREATE TABLE [dbo].[T_DATA]
( ID nchar(8) NOT NULL, PRIMARY KEY
, Test decimal(4, 2) NOT NULL
, Outcome nchar(1) NOT NULL
);
GO
ALTER TABLE T_DATA ADD CONSTRAINT CK_Outcome CHECK (Outcome = '0' OR Outcome = '1');
GO
下記の関数は階乗を対数の和に変換します.
CREATE FUNCTION [dbo].[LOG_FACT](
@SrcNumber FLOAT
)
RETURNS FLOAT
BEGIN
DECLARE @DesNumber FLOAT
SET @DesNumber = LOG(1)
WHILE @SrcNumber > 0
BEGIN
SET @DesNumber = @DesNumber + LOG(@SrcNumber)
SET @SrcNumber = @SrcNumber - 1
END
RETURN @DesNumber
END
GO
下記のストアドプロシージャはカットオフ値を変数化して T_DATA からクロス表を作成します.
CREATE PROCEDURE [dbo].[sp_Cut_by_Test]
@CutOff decimal(4, 2)
AS
BEGIN
WITH Cross_Table AS
(
SELECT COUNT(*) AS 'N'
, SUM(CASE WHEN T_DATA.Test @CutOff AND T_DATA.Outcome = '1' THEN 1 ELSE 0 END) AS 'c'
, SUM(CASE WHEN T_DATA.Test > @CutOff AND T_DATA.Outcome = '0' THEN 1 ELSE 0 END) AS 'd'
, SUM(CASE WHEN T_DATA.Outcome = '1' THEN 1 ELSE 0 END) AS 'a+c'
, SUM(CASE WHEN T_DATA.Outcome = '0' THEN 1 ELSE 0 END) AS 'b+d'
, SUM(CASE WHEN T_DATA.Test @CutOff THEN 1 ELSE 0 END) AS 'c+d'
FROM T_DATA
)
SELECT @CutOff
, Cross_Table.[N]
, Cross_Table.[a]
, Cross_Table.[b]
, Cross_Table.
, Cross_Table.[d]
, Cross_Table.[a+c]
, Cross_Table.[b+d]
, Cross_Table.[a+b]
, Cross_Table.
, Cross_Table.[a]/Cross_Table.[a+c] AS 'Sensitivity'
, Cross_Table.[d]/Cross_Table.[b+d] AS 'Specificity'
, 1 - Cross_Table.[d]/Cross_Table.[b+d] AS 'FalsePositive'
FROM Cross_Table;
END
GO
下記のストアドプロシージャはクロス表から Fisher の確率を求めます.@Start とは test の最小値であり, @End は test の最大値, @Step は @Start から @End までの増分のことです.例えばそれぞれ @Start を 2.0 とし,@End を 4.0 とし,@Step を 0.1 とするなどです.
CREATE PROCEDURE [dbo].[FisherExactTest]
( @Start decimal(4, 2)
, @End decimal(4, 2)
, @Step decimal(4, 2)
)
AS
BEGIN
CREATE TABLE #Result
( [CutOff] decimal(4, 2) NOT NULL
, N int NOT NULL
, a int NOT NULL
, b int NOT NULL
, c int NOT NULL
, d int NOT NULL
, [a+c] int NOT NULL
, [b+d] int NOT NULL
, [a+b] int NOT NULL
, int NOT NULL
, Sensitivity FLOAT NOT NULL
, Specificity FLOAT NOT NULL
, FalsePositive FLOAT NOT NULL
)
DECLARE @CutOff decimal(4, 2)
SET @CutOff = @Start
WHILE @CutOff
参照記事
対数を用いてFisherの直接確率検定を計算するには
周辺度数からクロス表を作成するには
対数により階乗を計算するストアドプロシージャを作成する