调整自适应顺序分析的 p 值(用于卡方检验)?

机器算法验证 假设检验 卡方检验 p 值 多重比较 顺序分析
2022-03-11 10:32:18

我想知道哪些统计文献与以下问题相关,甚至想知道如何解决它。

想象以下问题:

对于某些疾病,我们有 4 种可能的治疗方法。为了检查哪种治疗效果更好,我们进行了特殊试验。在试验中,我们从没有受试者开始,然后,一个接一个地,更多的受试者进入试验。每个患者被随机分配到 4 种可能的治疗中的一种。治疗的最终结果是“健康”或“仍然生病”,让我们说我们可以立即知道这个结果。这意味着在任何给定点,我们都可以创建一个 2 x 4 列联表,说明有多少受试者属于哪种治疗/最终结果。

在任何时候,我们都可以检查列联表(例如,使用卡方检验),以查看 4 种可能的治疗方法之间是否存在统计学差异。如果其中一个比其他所有更好 - 我们停止试验并选择它作为“赢家”。如果某项试验被证明比其他三个试验都更糟,我们将把他从试验中剔除,并停止将其提供给未来的患者。

然而,这里的问题是我如何调整 p 值,因为测试可以在任何给定点执行,测试之间存在相关性,以及过程的自适应性质操纵过程(对于例如,如果发现某些治疗是“坏的”)?

2个回答

连续临床试验的这一领域已在文献中进行了大量探索。一些著名的研究人员包括 Scott Emerson、Tom Flemming、David DeMets、Stephen Senn 和 Stuart Pocock 等。

可以指定“alpha-sending-rule”。该术语起源于常客(非费舍尔)测试的性质,其中,增加误报发现风险的每项操作都必然会降低保持测试规模正确的能力。但是,大多数此类测试都要求根据研究的信息范围预先指定“停止规则”。(提醒一下,当 null 为假时,更多信息意味着更大的权力)。

听起来您感兴趣的是一个持续的监控过程,其中每个事件时间都需要“查看”数据。据我所知,这样的测试没有任何效力。它可以通过贝叶斯分析来完成,其中后验作为时间的函数不断更新,贝叶斯因子用于总结证据而不是值。p

[1] www.rctdesign.org/

这听起来像一个模拟是为了。

所以我模拟了你的程序如下:人被一个接一个地添加到试验中,随机分配到组中的一个。这个人的治疗结果是随机选择的(即我正在模拟所有具有零效应的治疗的零假设)。列联表执行卡方检验并检查是否如果是,那么(并且仅在那时)我另外对减少的列联表执行卡方检验,以测试每个组与其他三个合并在一起的组。如果这四个测试中的一个结果显着(具有相同的N=100044×2pα2×2α),然后我检查这种处理的效果是否比其他三个合并在一起的效果更好或更差。如果更糟,我会取消这种处理并继续添加人员。如果更好,我停止审判。如果添加了所有人而没有任何获胜治疗,则试验结束(请注意,我的分析结果将强烈依赖于)。NN

现在我们可以运行很多次,并找出其中一种治疗方法在运行中获胜的比例——这些都是误报。运行 1000 次,我会得到 282 个误报,即的 II 类错误率。α=0.050.28

重复整个分析,看看我们得到的实际错误率是多少:所以如果你想让实际的错误率保持在水平,你应该选择左右当然最好运行一个更长的模拟来更精确地估计这一点。α

αerror rate0.050.280.010.060.0010.008
0.05α0.008


下面是我在 Matlab 中的快速而肮脏的代码。请注意,这段代码是脑死的,根本没有优化;一切都在循环中运行,而且速度非常慢。这可能会加速很多。

function seqAnalysis()
    alphas = [0.001 0.01 0.05];
    for a = 1:length(alphas)
        falsePositives(a) = trials_run(1000, 1000, alphas(a));
    end
    display(num2str([alphas; falsePositives]))
end

function outcome = trials_run(Nrep, N, alpha)
    outcomes = zeros(1,Nrep);
    for rep = 1:Nrep
        if mod(rep,10) == 0
            fprintf('.')            
        end
        outcomes(rep) = trial(N, alpha);
    end
    fprintf('\n')
    outcome = sum(outcomes);
end


function result = trial(N, alpha)
    outcomes = zeros(2,4);

    result = 0;
    winner = [];

    %// adding subjects one by one
    for subject = 1:N
        group = randi(size(outcomes,2));
        outcome = randi(2);    
        outcomes(outcome, group) = outcomes(outcome, group) + 1;

        %// if groups are significantly different
        if chisqtest(outcomes) < alpha
            %// compare each treatment against the rest
            for group = 1:size(outcomes,2)
                contrast = [outcomes(:, group) ...
                            sum(outcomes(:, setdiff(1:size(outcomes,2), group)),2)];
                %// if significantly different
                if chisqtest(contrast) < alpha
                    %// check if better or worse
                    if contrast(1,1)/contrast(2,1) < contrast(1,2)/contrast(2,2)
                        %// kick out this group
                        outcomes = outcomes(:, setdiff(1:size(outcomes,2), group));
                    else
                        %// winner!
                        winner = group;
                    end
                    break
                end
            end
        end

        if ~isempty(winner)
            result = 1;    
            break
        end
    end
end

function p = chisqtest(x)
    e = sum(x,2)*sum(x)/sum(x(:));
    X2 = (x-e).^2./e;
    X2 = sum(X2(:));
    df = prod(size(x)-[1 1]);
    p = 1-chi2cdf(X2,df);
end