code: def _compare_nodes(
      predicted_nodes: Counter[Node],
      expected_nodes: Counter[Node],
      per_label_confusions: Optional[PerLabelConfusions] = None,
  ) -> Confusions:
      true_positives = predicted_nodes & expected_nodes
      false_positives = predicted_nodes - true_positives
      false_negatives = expected_nodes - true_positives
  
      if per_label_confusions:
          for node, count in true_positives.items():
              per_label_confusions.update(node.label, "TP", count)
          for node, count in false_positives.items():
              per_label_confusions.update(node.label, "FP", count)
          for node, count in false_negatives.items():
              per_label_confusions.update(node.label, "FN", count)
  
      return Confusions(
          TP=sum(true_positives.values()),
          FP=sum(false_positives.values()),
          FN=sum(false_negatives.values()),
      )
  
imports: from collections import Counter, defaultdict
  from copy import deepcopy
  from typing import AbstractSet, Any, Callable, Counter, Dict, List, NamedTuple, Optional, Sequence, Tuple
  from pytext.data.data_structures.annotation import INVALID_TREE_INTENT
  from pytext.data.data_structures.node import Node, Span
  from .None import AllConfusions, Confusions, PerLabelConfusions, PRF1Metrics, PRF1Scores, safe_division
label_desc: Use image node_id 1 for calling a global function with example usage: _compare_nodes(predicted_nodes, expected_nodes, per_label_confusions) and returns: Confusions