pyg-nightly 2.7.0.dev20250211__py3-none-any.whl → 2.7.0.dev20250213__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pyg-nightly
3
- Version: 2.7.0.dev20250211
3
+ Version: 2.7.0.dev20250213
4
4
  Summary: Graph Neural Network Library for PyTorch
5
5
  Keywords: deep-learning,pytorch,geometric-deep-learning,graph-neural-networks,graph-convolutional-networks
6
6
  Author-email: Matthias Fey <matthias@pyg.org>
@@ -1,4 +1,4 @@
1
- torch_geometric/__init__.py,sha256=w6FK2cWfDKMk6__QpIY3W_iaTmbYGeA71r1ni5R1cZk,1904
1
+ torch_geometric/__init__.py,sha256=wOLNLy1SUhTvDg4h0bCQM5edX6RXk83qnn4omNGqmaw,1904
2
2
  torch_geometric/_compile.py,sha256=f-WQeH4VLi5Hn9lrgztFUCSrN_FImjhQa6BxFzcYC38,1338
3
3
  torch_geometric/_onnx.py,sha256=V9ffrIKSqhDw6xUZ12lkuSfNs48cQp2EeJ6Z19GfnVw,349
4
4
  torch_geometric/backend.py,sha256=lVaf7aLoVaB3M-UcByUJ1G4T4FOK6LXAg0CF4W3E8jo,1575
@@ -288,8 +288,8 @@ torch_geometric/loader/shadow.py,sha256=_hCspYf9SlJYX0lqEjxFec9e9t1iMScNThOoWR1w
288
288
  torch_geometric/loader/temporal_dataloader.py,sha256=AQ2QFeiXKbPp6I8sUeE8H7br-1_yndivXt7Z6_w62zI,2248
289
289
  torch_geometric/loader/utils.py,sha256=f27mczQ7fEP2HpTsJGJxKS0slPu0j8zTba3jP8ViNck,14901
290
290
  torch_geometric/loader/zip_loader.py,sha256=3lt10fD15Rxm1WhWzypswGzCEwUz4h8OLCD1nE15yNg,3843
291
- torch_geometric/metrics/__init__.py,sha256=9gPEg0_oMfq7LAr5rsrebasnvYN9nDXwq2ML56lWcMo,529
292
- torch_geometric/metrics/link_pred.py,sha256=H-s9U9n2CKpj9pRQWG9KdTZ0jueds1iy7hr893BmGoE,23121
291
+ torch_geometric/metrics/__init__.py,sha256=3krvDobW6vV5yHTjq2S2pmOXxNfysNG26muq7z48e94,699
292
+ torch_geometric/metrics/link_pred.py,sha256=X8LXJvJ0dwjOeO0PvB6xe-qkBntmefHKC4zex7Q2i0I,29766
293
293
  torch_geometric/nn/__init__.py,sha256=RrWRzEoqtR3lsO2lAzYXboLPb3uYEX2z3tLxiBIVWjc,847
294
294
  torch_geometric/nn/data_parallel.py,sha256=lDAxRi83UNuzAQSj3eu9K2sQheOIU6wqR5elS6oDs90,4764
295
295
  torch_geometric/nn/encoding.py,sha256=QNjwWczYExZ1wRGBmpuqYbn6tB7NC4BU-DEgzjhcZqw,3115
@@ -630,6 +630,6 @@ torch_geometric/utils/undirected.py,sha256=H_nfpI0_WluOG6VfjPyldvcjL4w5USAKWu2x5
630
630
  torch_geometric/visualization/__init__.py,sha256=PyR_4K5SafsJrBr6qWrkjKr6GBL1b7FtZybyXCDEVwY,154
631
631
  torch_geometric/visualization/graph.py,sha256=ZuLPL92yGRi7lxlqsUPwL_EVVXF7P2kMcveTtW79vpA,4784
632
632
  torch_geometric/visualization/influence.py,sha256=CWMvuNA_Nf1sfbJmQgn58yS4OFpeKXeZPe7kEuvkUBw,477
633
- pyg_nightly-2.7.0.dev20250211.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
634
- pyg_nightly-2.7.0.dev20250211.dist-info/METADATA,sha256=MY9WTWMv3sau6yXUUPC0D4AXP12sq2_PsX4Fq6-kGoQ,62977
635
- pyg_nightly-2.7.0.dev20250211.dist-info/RECORD,,
633
+ pyg_nightly-2.7.0.dev20250213.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
634
+ pyg_nightly-2.7.0.dev20250213.dist-info/METADATA,sha256=KMYn4w4Bn5To5C_3fCsn61FLL62Iz10xQk493Q4OeCE,62977
635
+ pyg_nightly-2.7.0.dev20250213.dist-info/RECORD,,
@@ -30,7 +30,7 @@ from .lazy_loader import LazyLoader
30
30
  contrib = LazyLoader('contrib', globals(), 'torch_geometric.contrib')
31
31
  graphgym = LazyLoader('graphgym', globals(), 'torch_geometric.graphgym')
32
32
 
33
- __version__ = '2.7.0.dev20250211'
33
+ __version__ = '2.7.0.dev20250213'
34
34
 
35
35
  __all__ = [
36
36
  'Index',
@@ -9,8 +9,11 @@ from .link_pred import (
9
9
  LinkPredMAP,
10
10
  LinkPredNDCG,
11
11
  LinkPredMRR,
12
+ LinkPredHitRatio,
12
13
  LinkPredCoverage,
13
14
  LinkPredDiversity,
15
+ LinkPredPersonalization,
16
+ LinkPredAveragePopularity,
14
17
  )
15
18
 
16
19
  link_pred_metrics = [
@@ -22,8 +25,11 @@ link_pred_metrics = [
22
25
  'LinkPredMAP',
23
26
  'LinkPredNDCG',
24
27
  'LinkPredMRR',
28
+ 'LinkPredHitRatio',
25
29
  'LinkPredCoverage',
26
30
  'LinkPredDiversity',
31
+ 'LinkPredPersonalization',
32
+ 'LinkPredAveragePopularity',
27
33
  ]
28
34
 
29
35
  __all__ = link_pred_metrics
@@ -423,7 +423,12 @@ class LinkPredMetricCollection(torch.nn.ModuleDict):
423
423
 
424
424
 
425
425
  class LinkPredPrecision(LinkPredMetric):
426
- r"""A link prediction metric to compute Precision @ :math:`k`.
426
+ r"""A link prediction metric to compute Precision @ :math:`k`, *i.e.* the
427
+ proportion of recommendations within the top-:math:`k` that are actually
428
+ relevant.
429
+
430
+ A higher precision indicates the model's ability to surface relevant items
431
+ early in the ranking.
427
432
 
428
433
  Args:
429
434
  k (int): The number of top-:math:`k` predictions to evaluate against.
@@ -437,7 +442,11 @@ class LinkPredPrecision(LinkPredMetric):
437
442
 
438
443
 
439
444
  class LinkPredRecall(LinkPredMetric):
440
- r"""A link prediction metric to compute Recall @ :math:`k`.
445
+ r"""A link prediction metric to compute Recall @ :math:`k`, *i.e.* the
446
+ proportion of relevant items that appear within the top-:math:`k`.
447
+
448
+ A higher recall indicates the model's ability to retrieve a larger
449
+ proportion of relevant items.
441
450
 
442
451
  Args:
443
452
  k (int): The number of top-:math:`k` predictions to evaluate against.
@@ -472,7 +481,11 @@ class LinkPredF1(LinkPredMetric):
472
481
 
473
482
  class LinkPredMAP(LinkPredMetric):
474
483
  r"""A link prediction metric to compute MAP @ :math:`k` (Mean Average
475
- Precision).
484
+ Precision), considering the order of relevant items within the
485
+ top-:math:`k`.
486
+
487
+ MAP @ :math:`k` can provide a more comprehensive view of ranking quality
488
+ than precision alone.
476
489
 
477
490
  Args:
478
491
  k (int): The number of top-:math:`k` predictions to evaluate against.
@@ -493,6 +506,10 @@ class LinkPredNDCG(LinkPredMetric):
493
506
  r"""A link prediction metric to compute the NDCG @ :math:`k` (Normalized
494
507
  Discounted Cumulative Gain).
495
508
 
509
+ In particular, can account for the position of relevant items by
510
+ considering relevance scores, giving higher weight to more relevant items
511
+ appearing at the top.
512
+
496
513
  Args:
497
514
  k (int): The number of top-:math:`k` predictions to evaluate against.
498
515
  weighted (bool, optional): If set to :obj:`True`, assumes sorted lists
@@ -549,7 +566,8 @@ class LinkPredNDCG(LinkPredMetric):
549
566
 
550
567
  class LinkPredMRR(LinkPredMetric):
551
568
  r"""A link prediction metric to compute the MRR @ :math:`k` (Mean
552
- Reciprocal Rank).
569
+ Reciprocal Rank), *i.e.* the mean reciprocal rank of the first correct
570
+ prediction (or zero otherwise).
553
571
 
554
572
  Args:
555
573
  k (int): The number of top-:math:`k` predictions to evaluate against.
@@ -564,9 +582,28 @@ class LinkPredMRR(LinkPredMetric):
564
582
  return (pred_rel_mat / arange).max(dim=-1)[0]
565
583
 
566
584
 
585
+ class LinkPredHitRatio(LinkPredMetric):
586
+ r"""A link prediction metric to compute the hit ratio @ :math:`k`, *i.e.*
587
+ the percentage of users for whom at least one relevant item is present
588
+ within the top-:math:`k` recommendations.
589
+
590
+ A high ratio signifies the model's effectiveness in satisfying a broad
591
+ range of user preferences.
592
+ """
593
+ higher_is_better: bool = True
594
+ weighted: bool = False
595
+
596
+ def _compute(self, data: LinkPredMetricData) -> Tensor:
597
+ pred_rel_mat = data.pred_rel_mat[:, :self.k]
598
+ return pred_rel_mat.max(dim=-1)[0].to(torch.get_default_dtype())
599
+
600
+
567
601
  class LinkPredCoverage(_LinkPredMetric):
568
602
  r"""A link prediction metric to compute the Coverage @ :math:`k` of
569
- predictions.
603
+ predictions, *i.e.* the percentage of unique items recommended across all
604
+ users within the top-:math:`k`.
605
+
606
+ Higher coverage indicates a wider exploration of the item catalog.
570
607
 
571
608
  Args:
572
609
  k (int): The number of top-:math:`k` predictions to evaluate against.
@@ -667,3 +704,136 @@ class LinkPredDiversity(_LinkPredMetric):
667
704
  def _reset(self) -> None:
668
705
  self.accum.zero_()
669
706
  self.total.zero_()
707
+
708
+
709
+ class LinkPredPersonalization(_LinkPredMetric):
710
+ r"""A link prediction metric to compute the Personalization @ :math:`k`,
711
+ *i.e.* the dissimilarity of recommendations across different users.
712
+
713
+ Higher personalization suggests that the model tailors recommendations to
714
+ individual user preferences rather than providing generic results.
715
+
716
+ Dissimilarity is defined by the average inverse cosine similarity between
717
+ users' lists of recommendations.
718
+
719
+ Args:
720
+ k (int): The number of top-:math:`k` predictions to evaluate against.
721
+ batch_size (int, optional): The batch size to determine how many pairs
722
+ of user recommendations should be processed at once.
723
+ (default: :obj:`2**16`)
724
+ """
725
+ higher_is_better: bool = True
726
+
727
+ def __init__(self, k: int, batch_size: int = 2**16) -> None:
728
+ super().__init__(k)
729
+ self.batch_size = batch_size
730
+
731
+ if WITH_TORCHMETRICS:
732
+ self.add_state('preds', default=[], dist_reduce_fx='cat')
733
+ self.add_state('dev_tensor', torch.empty(0), dist_reduce_fx='sum')
734
+ else:
735
+ self.preds: List[Tensor] = []
736
+ self.register_buffer('dev_tensor', torch.empty(0))
737
+
738
+ def update(
739
+ self,
740
+ pred_index_mat: Tensor,
741
+ edge_label_index: Union[Tensor, Tuple[Tensor, Tensor]],
742
+ edge_label_weight: Optional[Tensor] = None,
743
+ ) -> None:
744
+ # NOTE Move to CPU to avoid memory blowup.
745
+ self.preds.append(pred_index_mat[:, :self.k].cpu())
746
+
747
+ def compute(self) -> Tensor:
748
+ device = self.dev_tensor.device
749
+ score = torch.tensor(0.0, device=device)
750
+ total = torch.tensor(0, device=device)
751
+
752
+ if len(self.preds) == 0:
753
+ return score
754
+
755
+ pred = torch.cat(self.preds, dim=0)
756
+
757
+ if pred.size(0) == 0:
758
+ return score
759
+
760
+ # Calculate all pairs of nodes (e.g., triu_indices with offset=1).
761
+ # NOTE We do this in chunks to avoid memory blow-up, which leads to a
762
+ # more efficient but trickier implementation.
763
+ num_pairs = (pred.size(0) * (pred.size(0) - 1)) // 2
764
+ offset = torch.arange(pred.size(0) - 1, 0, -1, device=device)
765
+ rowptr = cumsum(offset)
766
+ for start in range(0, num_pairs, self.batch_size):
767
+ end = min(start + self.batch_size, num_pairs)
768
+ idx = torch.arange(start, end, device=device)
769
+
770
+ # Find the corresponding row:
771
+ row = torch.searchsorted(rowptr, idx, right=True) - 1
772
+ # Find the corresponding column:
773
+ col = idx - rowptr[row] + (pred.size(0) - offset[row])
774
+
775
+ left = pred[row.cpu()].to(device)
776
+ right = pred[col.cpu()].to(device)
777
+
778
+ # Use offset to work around applying `isin` along a specific dim:
779
+ i = max(left.max(), right.max()) + 1 # type: ignore
780
+ i = torch.arange(0, i * row.size(0), i, device=device).view(-1, 1)
781
+ isin = torch.isin(left + i, right + i)
782
+
783
+ # Compute personalization via average inverse cosine similarity:
784
+ cos = isin.sum(dim=-1) / pred.size(1)
785
+ score += (1 - cos).sum()
786
+ total += cos.numel()
787
+
788
+ return score / total
789
+
790
+ def _reset(self) -> None:
791
+ self.preds = []
792
+
793
+
794
+ class LinkPredAveragePopularity(_LinkPredMetric):
795
+ r"""A link prediction metric to compute the Average Recommendation
796
+ Popularity (ARP) @ :math:`k`, which provides insights into the model's
797
+ tendency to recommend popular items by averaging the popularity scores of
798
+ items within the top-:math:`k` recommendations.
799
+
800
+ Args:
801
+ k (int): The number of top-:math:`k` predictions to evaluate against.
802
+ popularity (torch.Tensor): The popularity of every item in the training
803
+ set, *e.g.*, the number of times an item has been rated.
804
+ """
805
+ higher_is_better: bool = False
806
+
807
+ def __init__(self, k: int, popularity: Tensor) -> None:
808
+ super().__init__(k)
809
+
810
+ if WITH_TORCHMETRICS:
811
+ self.add_state('accum', torch.tensor(0.), dist_reduce_fx='sum')
812
+ self.add_state('total', torch.tensor(0), dist_reduce_fx='sum')
813
+ else:
814
+ self.register_buffer('accum', torch.tensor(0.))
815
+ self.register_buffer('total', torch.tensor(0))
816
+
817
+ self.popularity: Tensor
818
+ self.register_buffer('popularity', popularity)
819
+
820
+ def update(
821
+ self,
822
+ pred_index_mat: Tensor,
823
+ edge_label_index: Union[Tensor, Tuple[Tensor, Tensor]],
824
+ edge_label_weight: Optional[Tensor] = None,
825
+ ) -> None:
826
+ pred_index_mat = pred_index_mat[:, :self.k]
827
+ popularity = self.popularity[pred_index_mat]
828
+ popularity = popularity.to(self.accum.dtype).mean(dim=-1)
829
+ self.accum += popularity.sum()
830
+ self.total += popularity.numel()
831
+
832
+ def compute(self) -> Tensor:
833
+ if self.total == 0:
834
+ return torch.zeros_like(self.accum)
835
+ return self.accum / self.total
836
+
837
+ def _reset(self) -> None:
838
+ self.accum.zero_()
839
+ self.total.zero_()