sxjscience commented on a change in pull request #9777: [MX-9588] Add micro 
averaging strategy for F1 metric
URL: https://github.com/apache/incubator-mxnet/pull/9777#discussion_r167993481
 
 

 ##########
 File path: python/mxnet/metric.py
 ##########
 @@ -475,8 +475,84 @@ def update(self, labels, preds):
             self.num_inst += num_samples
 
 
+class _BinaryClassificationMixin(object):
+    """
+    Private mixin for keeping track of TPR, FPR, TNR, FNR counts for a 
classification metric.
+    """
+
+    def __init__(self):
+        self._true_positives = 0
+        self._false_negatives = 0
+        self._false_positives = 0
+        self._true_negatives = 0
+
+    def _update_binary_stats(self, label, pred):
+        """
+        Update various binary classification counts for a single (label, pred)
+        pair.
+
+        Parameters
+        ----------
+        label : `NDArray`
+            The labels of the data.
+
+        pred : `NDArray`
+            Predicted values.
+        """
+        pred = pred.asnumpy()
+        label = label.asnumpy().astype('int32')
+        pred_label = numpy.argmax(pred, axis=1)
+
+        check_label_shapes(label, pred)
+        if len(numpy.unique(label)) > 2:
+            raise ValueError("%s currently only supports binary 
classification."
+                             % self.__class__.__name__)
+
+        for y_pred, y_true in zip(pred_label, label):
 
 Review comment:
   I've previously written the codes to accelerate F1 calculation in GPU. 
However it's not based on metric and directly uses NDArray:
   ```python
   def nd_f1(pred, label, num_class, average="micro"):
       """Evaluate F1 using mx.nd.NDArray
   
       Parameters
       ----------
       pred : nd.NDArray
           Shape (num, label_num) or (num,)
       label : nd.NDArray
           Shape (num, label_num) or (num,)
       num_class : int
       average : str
   
       Returns
       -------
       f1 : float
       """
       if pred.dtype != np.float32:
           pred = pred.astype(np.float32)
           label = label.astype(np.float32)
       assert num_class > 1
       assert pred.ndim == label.ndim
       if num_class == 2 and average == "micro":
           tp = nd.sum((pred == 1) * (label == 1)).asscalar()
           fp = nd.sum((pred == 1) * (label == 0)).asscalar()
           fn = nd.sum((pred == 0) * (label == 1)).asscalar()
           precision = float(tp) / (tp + fp)
           recall = float(tp) / (tp + fn)
           f1 = 2 * (precision * recall) / (precision + recall)
       else:
           assert num_class is not None
           pred_onehot = nd.one_hot(indices=pred, depth=num_class)
           label_onehot = nd.one_hot(indices=label, depth=num_class)
           tp = pred_onehot * label_onehot
           fp = pred_onehot * (1 - label_onehot)
           fn = (1 - pred_onehot) * label_onehot
           if average == "micro":
               tp = nd.sum(tp).asscalar()
               fp = nd.sum(fp).asscalar()
               fn = nd.sum(fn).asscalar()
               precision = float(tp) / (tp + fp)
               recall = float(tp) / (tp + fn)
               f1 = 2 * (precision * recall) / (precision + recall)
           elif average == "macro":
               if tp.ndim == 3:
                   tp = nd.sum(tp, axis=(0, 1))
                   fp = nd.sum(fp, axis=(0, 1))
                   fn = nd.sum(fn, axis=(0, 1))
               else:
                   tp = nd.sum(tp, axis=0)
                   fp = nd.sum(fp, axis=0)
                   fn = nd.sum(fn, axis=0)
               precision = nd.mean(tp / (tp + fp)).asscalar()
               recall = nd.mean(tp / (tp + fn)).asscalar()
               f1 = 2 * (precision * recall) / (precision + recall)
           else:
               raise NotImplementedError
       return f1
   ```

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to