Python: count TP, FP, FN Ð¸ TN
<p>I have dataframe with true class and class, that were predicted by some algorithm.</p>

<pre><code>     true  pred
0       1     0
1       1     1
2       1     1
3       0     0
4       1     1
</code></pre>

<p>I try to use</p>

<pre><code>def classification(y_actual, y_hat):
    TP = 0
    FP = 0
    TN = 0
    FN = 0

    for i in range(len(y_hat)): 
        if y_actual[i] == y_hat[i] == 1:
           TP += 1
    for i in range(len(y_hat)): 
        if y_actual[i] == 1 and y_actual != y_hat[i]:
           FP += 1
    for i in range(len(y_hat)): 
        if y_actual[i] == y_hat[i] == 0:
           TN += 1
    for i in range(len(y_hat)): 
        if y_actual[i] == 0 and y_actual != y_hat[i]:
           FN += 1

    return(TP, FP, TN, FN)
</code></pre>

<p>but it return me</p>

<blockquote>
  <p>ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
  How can I fix that or maybe there are the better decision?</p>
</blockquote>

<p>The error message happens because Python tries to convert an array to a boolean and fails.</p>

<p>That's because you're comparing <code>y_actual</code> with <code>y_hat[i]</code>.</p>

<p>It should be <code>y_actual[i] != y_hat[i]</code> (2 times in the code)</p>

<p>(I realize that it's just a typo, but the message is cryptic enough for the problem to become interesting)</p>

<p>While we're at it, you could make a more efficient routine by merging all your counters in a sole loop and using enumerate to avoid at least one access by index:</p>

<pre><code>def classification(y_actual, y_hat):
    TP = 0
    FP = 0
    TN = 0
    FN = 0

    for i,yh in enumerate(y_hat): 
        if y_actual[i] == yh == 1:
           TP += 1
        if y_actual[i] == 1 and y_actual[i] != yh:
           FP += 1
        if y_actual[i] == yh == 0:
           TN += 1
        if y_actual[i] == 0 and y_actual[i] != yh:
           FN += 1

    return(TP, FP, TN, FN)
</code></pre>

<p>you see that this way it can be even be simplified even more
, cutting a lot through tests and branches:</p>

<pre><code>def classification(y_actual, y_hat):
    TP = 0
    FP = 0
    TN = 0
    FN = 0

    for i,yh in enumerate(y_hat): 
        if y_actual[i] == yh:
           if yh == 1:
               TP += 1
           elif yh == 0:
               TN += 1
        else: # y_actual[i] != yh
           if y_actual[i] == 1 and :
              FP += 1
           elif y_actual[i] == 0:
              FN += 1

    return(TP, FP, TN, FN)
</code></pre>

python machine-learning scikit-learn