Расчет точности, отзыва и F-счета за один проход - питон

Точность, точность, отзыв и f-оценка являются мерами качества системы в системах машинного обучения. Это зависит от матрицы путаницы Истинных / Ложных Позитивов / Негативов.

Учитывая задачу двоичной классификации, я попробовал следующее, чтобы получить функцию, которая возвращает точность, точность, отзыв и f-оценка:

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

Но похоже, что я избыточно перебрал набор данных 4 раза, чтобы получить истинные / ложные положительные / отрицательные значения.

Также несколькоtry-excepts пойматьZeroDivisionError немного излишним.

Так какой же питонный способ получить количество истинных / ложных положительных / отрицательных значений без множественных циклов в наборе данных?

Как я могу пойматьZeroDivisionError без нескольких try-исключений?

Я мог бы также сделать следующее, чтобы посчитать истинные / ложные положительные / отрицательные значения в одном цикле, ноесть ли альтернативный способ без многократногоif?:

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

Ответы на вопрос(3)

Ваш ответ на вопрос