Cálculo de precisão, rechamada e pontuação F em uma passagem - python

Exatidão, precisão, recall e f-score são medidas de qualidade de um sistema em sistemas de aprendizado de máquina. Depende de uma matriz de confusão de Verdadeiros / Falsos Positivos / Negativos.

Dada uma tarefa de classificação binária, tentei o seguinte para obter uma função que retorne precisão, precisão, recall e f-score:

gold = [1] + [0] * 9
predicted = [1] * 10

def evaluation(gold, predicted):
  true_pos = sum(1 for p,g in zip(predicted, gold) if p==1 and g==1)
  true_neg = sum(1 for p,g in zip(predicted, gold) if p==0 and g==0)
  false_pos = sum(1 for p,g in zip(predicted, gold) if p==1 and g==0)
  false_neg = sum(1 for p,g in zip(predicted, gold) if p==0 and g==1)
  try:
    recall = true_pos / float(true_pos + false_neg)
  except:
    recall = 0
  try:
    precision = true_pos / float(true_pos + false_pos)
  except:
    precision = 0
  try:
    fscore = 2*precision*recall / (precision + recall)
  except:
    fscore = 0
  try:
    accuracy = (true_pos + true_neg) / float(len(gold))
  except:
    accuracy = 0
  return accuracy, precision, recall, fscore

Mas parece que eu fiz um loop redundante no conjunto de dados 4 vezes para obter os Positivos / Negativos Verdadeiros / Falsos.

Também o múltiplotry-excepts pegar oZeroDivisionError é um pouco redundante.

Então, qual é a maneira pitônica de obter as contagens de Verdadeiros / Falsos Positivos / Negativos sem vários loops no conjunto de dados?

Como capturar pythonically oZeroDivisionError sem as várias tentativas-excede?

Eu também poderia fazer o seguinte para contar os Verdadeiros / Falsos Positivos / Negativos em um loop, masexiste uma maneira alternativa sem os múltiplosif?:

for p,g in zip(predicted, gold):
    if p==1 and g==1:
        true_pos+=1
    if p==0 and g==0:
        true_neg+=1
    if p==1 and g==0:
        false_pos+=1
    if p==0 and g==1:
        false_neg+=1

questionAnswers(3)

yourAnswerToTheQuestion