示例#1
0
def test_bayes_confusion_hyp():
    from mvpa2.clfs.transerror import BayesConfusionHypothesis
    conf = np.array([[10, 0, 5, 5], [0, 10, 5, 5], [5, 5, 10, 0],
                     [5, 5, 0, 10]])
    conf = Dataset(conf, sa={'labels': ['A', 'B', 'C', 'D']})
    bayes = BayesConfusionHypothesis(labels_attr='labels')
    skip_if_no_external('scipy')  # uses factorial from scipy.misc
    hyptest = bayes(conf)
    # by default comes with all hypothesis and posterior probs
    assert_equal(hyptest.shape, (15, 2))
    assert_array_equal(hyptest.fa.stat, ['log(p(C|H))', 'log(p(H|C))'])
    # check order of hypothesis (coarse)
    assert_array_equal(hyptest.sa.hypothesis[0], [['A', 'B', 'C', 'D']])
    assert_array_equal(hyptest.sa.hypothesis[-1], [['A'], ['B'], ['C'], ['D']])
    # now with limited hypothesis (given with literal labels), set and in
    # non-log scale
    bayes = BayesConfusionHypothesis(labels_attr='labels',
                                     log=False,
                                     hypotheses=[[['A', 'B', 'C', 'D']],
                                                 [[
                                                     'A',
                                                     'C',
                                                 ], ['B', 'D']],
                                                 [[
                                                     'A',
                                                     'D',
                                                 ], ['B', 'C']],
                                                 [['A'], ['B'], ['C'], ['D']]])
    hyptest = bayes(conf)
    # also with custom hyp the post-probs must add up to 1
    post_prob = hyptest.samples[:, 1]
    assert_almost_equal(np.sum(post_prob), 1)
    # in this particular case ...
    assert (post_prob[3] - np.sum(post_prob[1:3]) < 0.02)
示例#2
0
def test_confusion_as_node():
    from mvpa2.misc.data_generators import normal_feature_dataset
    from mvpa2.clfs.gnb import GNB
    from mvpa2.clfs.transerror import Confusion
    ds = normal_feature_dataset(snr=2.0,
                                perlabel=42,
                                nchunks=3,
                                nonbogus_features=[0, 1],
                                nfeatures=2)
    clf = GNB()
    cv = CrossValidation(clf,
                         NFoldPartitioner(),
                         errorfx=None,
                         postproc=Confusion(labels=ds.UT),
                         enable_ca=['stats'])
    res = cv(ds)
    # needs to be identical to CA
    assert_array_equal(res.samples, cv.ca.stats.matrix)
    assert_array_equal(res.sa.predictions, ds.UT)
    assert_array_equal(res.fa.targets, ds.UT)

    skip_if_no_external('scipy')

    from mvpa2.clfs.transerror import BayesConfusionHypothesis
    from mvpa2.base.node import ChainNode
    # same again, but this time with Bayesian hypothesis testing at the end
    cv = CrossValidation(clf,
                         NFoldPartitioner(),
                         errorfx=None,
                         postproc=ChainNode((Confusion(labels=ds.UT),
                                             BayesConfusionHypothesis())))
    res = cv(ds)
    # only two possible hypothesis with two classes
    assert_equals(len(res), 2)
    # the first hypothesis is the can't discriminate anything
    assert_equal(len(res.sa.hypothesis[0]), 1)
    assert_equal(len(res.sa.hypothesis[0][0]), 2)
    # and the hypothesis is actually less likely than the other one
    # (both classes can be distinguished)
    assert (np.e**res.samples[0, 0] < np.e**res.samples[1, 0])
示例#3
0
def test_confusion_as_node():
    from mvpa2.misc.data_generators import normal_feature_dataset
    from mvpa2.clfs.gnb import GNB
    from mvpa2.clfs.transerror import Confusion
    ds = normal_feature_dataset(snr=2.0, perlabel=42, nchunks=3,
                                nonbogus_features=[0,1], nfeatures=2)
    clf = GNB()
    cv = CrossValidation(
        clf, NFoldPartitioner(),
        errorfx=None,
        postproc=Confusion(labels=ds.UT),
        enable_ca=['stats'])
    res = cv(ds)
    # needs to be identical to CA
    assert_array_equal(res.samples, cv.ca.stats.matrix)
    assert_array_equal(res.sa.predictions, ds.UT)
    assert_array_equal(res.fa.targets, ds.UT)

    skip_if_no_external('scipy')

    from mvpa2.clfs.transerror import BayesConfusionHypothesis
    from mvpa2.base.node import ChainNode
    # same again, but this time with Bayesian hypothesis testing at the end
    cv = CrossValidation(
        clf, NFoldPartitioner(),
        errorfx=None,
        postproc=ChainNode([Confusion(labels=ds.UT),
                            BayesConfusionHypothesis()]))
    res = cv(ds)
    # only two possible hypothesis with two classes
    assert_equals(len(res), 2)
    # the first hypothesis is the can't discriminate anything
    assert_equal(len(res.sa.hypothesis[0]), 1)
    assert_equal(len(res.sa.hypothesis[0][0]), 2)
    # and the hypothesis is actually less likely than the other one
    # (both classes can be distinguished)
    assert(np.e**res.samples[0,0] < np.e**res.samples[1,0])

    # Let's see how well it would work within the searchlight when we also
    # would like to store the hypotheses per each voxel
    # Somewhat an ad-hoc solution for the answer posted on the ML
    #
    # run 1d searchlight of radii 0, for that just provide a .fa with coordinates
    ds.fa['voxel_indices'] = [[0], [1]]
    # and a custom Node which would collect .sa.hypothesis to place together along
    # with the posterior probabilities
    from mvpa2.base.node import Node
    from mvpa2.measures.searchlight import sphere_searchlight

    class KeepBothPosteriorAndHypothesis(Node):
        def _call(self, ds):
            out = np.zeros(1, dtype=object)
            out[0] = (ds.samples, ds.sa.hypothesis)
            return out
    cv.postproc.append(KeepBothPosteriorAndHypothesis())
    sl = sphere_searchlight(cv, radius=0, nproc=1)
    res = sl(ds)

    assert_equal(res.shape, (1, 2))
    assert_equal(len(res.samples[0,0]), 2)
    assert_equal(res.samples[0,0][0].shape, (2, 2))   # posteriors per 1st SL
    assert_equal(len(res.samples[0,0][1]), 2)   # 2 of hypotheses