Belle II Software  release-06-01-15
scores.py
1 
8 
9 """This module contains score functions to quantify the quality of a classification
10 
11 All score function have the signature
12 def score(truths, predictions):
13 
14 comparing the truth information against a model and return a numerical value.
15 """
16 
17 import numpy as np
18 
19 
20 def data_amount(truths, predictions):
21  """Score function: amount of data after a selection"""
22  n_predictions = len(predictions)
23  n_truths = len(truths)
24 
25  if n_predictions != n_truths:
26  raise ValueError("Prediction and truth do not represent the same amount of data.")
27 
28  return n_predictions
29 
30 
31 def signal_amount(truths, predictions):
32  """Score function: amount of signal of a classification"""
33  return np.count_nonzero(truths)
34 
35 
36 def accepted_amount(truths, predictions):
37  """Score function: amount accepted of a classification"""
38  return np.count_nonzero(predictions)
39 
40 
41 def accepted_signal_amount(truths, predictions):
42  """Score function: amount of accepted signal of a classification"""
43  return np.count_nonzero(predictions * truths)
44 
45 
46 # Functions independent of the data model
47 
48 # Amounts #
49 # ####### #
50 
51 def background_amount(truths, predictions):
52  """Score function: amount of background of a classification"""
53  return data_amount(truths, predictions) - signal_amount(truths, predictions)
54 
55 
56 def rejected_amount(truths, predictions):
57  """Score function: amount rejected of a classification"""
58  return data_amount(truths, predictions) - accepted_amount(truths, predictions)
59 
60 
61 def rejected_signal_amount(truths, predictions):
62  """Score function: amount of rejected signal of a classification"""
63  return signal_amount(truths, predictions) - accepted_signal_amount(truths, predictions)
64 
65 
66 def accepted_background_amount(truths, predictions):
67  """Score function: amount of accepted background of a classification"""
68  return accepted_amount(truths, predictions) - accepted_signal_amount(truths, predictions)
69 
70 
71 def rejected_background_amount(truths, predictions):
72  """Score function: amount of rejected background of a classification"""
73  return background_amount(truths, predictions) - accepted_background_amount(truths, predictions)
74 
75 
76 # Ratios #
77 # ###### #
78 
79 def purity(truths, predictions):
80  """Score function: purity = accepted signal / accepted"""
81  return np.divide(1.0 * accepted_signal_amount(truths, predictions), accepted_amount(truths, predictions))
82 
83 
84 def efficiency(truths, predictions):
85  """Score function: efficiency = accepted signal / signal"""
86  return np.divide(1.0 * accepted_signal_amount(truths, predictions), signal_amount(truths, predictions))
87 
88 
89 def accuracy(truths, predictions):
90  """Score function: accuracy = (accepted signal + rejected background) / total"""
91  n_correct = accepted_signal_amount(truths, predictions) + rejected_background_amount(truths, predictions)
92  n_data = data_amount(truths, predictions)
93  return np.divide(1.0 * n_correct, n_data)
94 
95 
96 def background_rejection(truths, predictions):
97  """Score function: background rejection = rejected background / background"""
98  n_background = background_amount(truths, predictions)
99  n_rejected_background = rejected_background_amount(truths, predictions)
100  return np.divide(1.0 * n_rejected_background, n_background)
101 
102 
103 def signal_background_ratio(truths, predictions):
104  """Score function: background / signal"""
105  n_data = data_amount(truths, predictions)
106  n_signal = signal_amount(truths, predictions)
107  n_background = n_data - n_signal
108  return np.divide(1.0 * n_signal, n_background)