In [1]:
import numpy as np

In [175]:
def _last_axis_binary_clf_curve(y_true, y_predicted):
    """
    returns y_predicted.shape[-2] binary clf curves calculated axis[-1]-wise

    """
    assert y_true.shape == y_predicted.shape
    axis = -1
    sort_idx = list(np.ogrid[[slice(x) for x in predicted.shape]])
    sort_idx[axis] = predicted.argsort(axis=axis)
    reverse = [slice(None)] * predicted.ndim
    reverse[axis] = slice(None, None, -1)
    sorted_y_predicted = predicted[sort_idx][reverse]
    sorted_y_true = true[sort_idx][reverse]


    tps = sorted_y_true.cumsum(axis=axis)
    count = (np.ones(y_predicted.shape) * np.arange(y_predicted.shape[-1]))
    fps = 1 + count - tps
    threshold_values = sorted_y_predicted

    return fps, tps, threshold_values

def last_axis_roc_curve(y_true, y_predicted):
    fps, tps, thresholds = _last_axis_binary_clf_curve(y_true, y_predicted)
    i = [slice(None)] * fps.ndim
    i[-1] = -1
    fpr = fps.astype('float32') / fps[i][:, np.newaxis]
    tpr = tps.astype('float32') / tps[i][:, np.newaxis]
    return fpr, tpr, thresholds

In [179]:
true = np.random.binomial(n=1, p=.5, size=(2, 10))
predicted = np.random.random((2, 10))
print true
print predicted


[[0 0 1 1 0 1 0 0 1 0]
 [0 1 1 0 0 1 1 1 0 1]]
[[ 0.33675335  0.99791057  0.85496188  0.46930929  0.66810304  0.2796852
   0.95192796  0.50157568  0.89468309  0.3586071 ]
 [ 0.76556221  0.25490741  0.65876228  0.34060118  0.2203393   0.13465922
   0.68278155  0.69037581  0.37279552  0.9754339 ]]

In [174]:
a = np.asarray([[1, 1, 0],
                [0, 1, 1]])
a.cumsum(axis=-1)


Out[174]:
array([[1, 2, 2],
       [0, 1, 2]])

In [180]:
fps, tps, thresh = _last_axis_binary_clf_curve(true, predicted)
print 'fps'
print fps
print 'tps'
print tps
print 'thresh'
print thresh
#i = [slice(None)] * fps.ndim
#i[-1] = -1
#print fps / fps[i][:, np.newaxis]
fpr, tpr, thresh2 = last_axis_roc_curve(true, predicted)
print 'fpr'
print fpr
print 'tpr'
print tpr


fps
[[ 1.  2.  2.  2.  3.  4.  4.  5.  6.  6.]
 [ 0.  1.  1.  1.  1.  2.  3.  3.  4.  4.]]
tps
[[0 0 1 2 2 2 3 3 3 4]
 [1 1 2 3 4 4 4 5 5 6]]
thresh
[[ 0.99791057  0.95192796  0.89468309  0.85496188  0.66810304  0.50157568
   0.46930929  0.3586071   0.33675335  0.2796852 ]
 [ 0.9754339   0.76556221  0.69037581  0.68278155  0.65876228  0.37279552
   0.34060118  0.25490741  0.2203393   0.13465922]]
fpr
[[ 0.16666667  0.33333333  0.33333333  0.33333333  0.5         0.66666667
   0.66666667  0.83333333  1.          1.        ]
 [ 0.          0.25        0.25        0.25        0.25        0.5         0.75
   0.75        1.          1.        ]]
tpr
[[ 0.          0.          0.25        0.5         0.5         0.5         0.75
   0.75        0.75        1.        ]
 [ 0.16666667  0.16666667  0.33333333  0.5         0.66666667  0.66666667
   0.66666667  0.83333333  0.83333333  1.        ]]

In [181]:
np.trapz(tpr, fpr)


Out[181]:
array([ 0.41666667,  0.58333333])

In [142]:
fps.shape


Out[142]:
(2, 3, 4, 5)

In [5]:
predicted.ndim


Out[5]:
2

In [6]:
axis = -1

In [18]:
sort_idx[axis] = predicted.argsort(axis=axis)
sort_idx


Out[18]:
[slice(None, None, None), array([[0, 2, 1],
        [0, 1, 2]])]

In [19]:
predicted[sort_idx]


Out[19]:
array([[[ 0.0722574 ,  0.27311446,  0.77148499],
        [ 0.0722574 ,  0.77148499,  0.27311446]],

       [[ 0.29435724,  0.97089053,  0.62205234],
        [ 0.29435724,  0.62205234,  0.97089053]]])

In [9]:
true[sort_idx]


Out[9]:
array([[[0, 0, 1, 1, 0],
        [0, 0, 1, 1, 0]],

       [[0, 1, 0, 0, 0],
        [0, 0, 0, 0, 1]]])

In [10]:
true[sort_idx].cumsum(axis=axis)


Out[10]:
array([[[0, 0, 1, 2, 2],
        [0, 0, 1, 2, 2]],

       [[0, 1, 1, 1, 1],
        [0, 0, 0, 0, 1]]])

In [11]:
true


Out[11]:
array([[0, 0, 1, 0, 1],
       [1, 0, 0, 0, 0]])

In [12]:
predicted


Out[12]:
array([[ 0.98754118,  0.02636933,  0.81213639,  0.03802334,  0.25226396],
       [ 0.71941426,  0.10981821,  0.72675193,  0.97651941,  0.96657049]])

In [26]:
predicted[..., predicted.argsort()].shape


Out[26]:
(2, 2, 3)

In [27]:
predicted[np.asarray([[0,0,0],[1,1,1]]), predicted.argsort()]


Out[27]:
array([[ 0.0722574 ,  0.27311446,  0.77148499],
       [ 0.29435724,  0.62205234,  0.97089053]])

In [31]:
np.choose(predicted.argsort(), predicted)


---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-31-ea431f594f87> in <module>()
----> 1 np.choose(predicted.argsort(), predicted[predicted.argsort()])

IndexError: index 2 is out of bounds for axis 0 with size 2

In [32]:
predicted.argsort().shape


Out[32]:
(2, 3)

In [39]:
np.where(predicted.argsort())


Out[39]:
(array([0, 0, 1, 1]), array([1, 2, 1, 2]))

In [40]:
predicted.argsort()


Out[40]:
array([[0, 2, 1],
       [0, 1, 2]])

In [45]:
predicted[np.ogrid[0:predicted.shape[0], ], predicted.argsort()]


---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-45-7daf4d1f3482> in <module>()
----> 1 predicted[np.ogrid[0:predicted.shape[0], ], predicted.argsort()]

IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (1,2) (2,3) 

In [91]:
predicted


Out[91]:
array([[ 0.07952977,  0.67182169,  0.95863163],
       [ 0.01306065,  0.0049748 ,  0.96606391]])

In [100]:
import copy
axis = -1
i = list(np.ogrid[[slice(x) for x in predicted.shape]])
reverse = [slice(None)] * predicted.ndim
reverse[axis] = slice(None, None, -1)
i[axis] = predicted.argsort(axis=axis)

predicted[i][reverse]


Out[100]:
array([[ 0.95863163,  0.67182169,  0.07952977],
       [ 0.96606391,  0.01306065,  0.0049748 ]])

In [48]:
i[axis] = predicted.argsort(axis=axis)

In [49]:
predicted[i]


Out[49]:
array([[ 0.0722574 ,  0.27311446,  0.77148499],
       [ 0.29435724,  0.62205234,  0.97089053]])

In [92]:
predicted.argsort().shape


Out[92]:
(2, 3)

In [93]:
predicted.argsort()


Out[93]:
array([[0, 1, 2],
       [1, 0, 2]])

In [94]:
predicted.argsort()[::-1]


Out[94]:
array([[1, 0, 2],
       [0, 1, 2]])

In [95]:



Out[95]:
array([[ 0.95863163,  0.67182169,  0.07952977],
       [ 0.96606391,  0.0049748 ,  0.01306065]])

In [182]:
predicted


Out[182]:
array([[ 0.33675335,  0.99791057,  0.85496188,  0.46930929,  0.66810304,
         0.2796852 ,  0.95192796,  0.50157568,  0.89468309,  0.3586071 ],
       [ 0.76556221,  0.25490741,  0.65876228,  0.34060118,  0.2203393 ,
         0.13465922,  0.68278155,  0.69037581,  0.37279552,  0.9754339 ]])

In [183]:
predicted.shape


Out[183]:
(2, 10)

In [189]:
predicted[slice(None), predicted.argsort()].shape


Out[189]:
(2, 2, 10)

In [ ]: