Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions hyperbench/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from . import hyperlink_prediction
from . import negative_sampling
from . import pipelines
from . import utils

__all__ = [
"hyperlink_prediction",
"negative_sampling",
"pipelines",
"utils"
]
7 changes: 7 additions & 0 deletions hyperbench/hyperlink_prediction/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from . import datasets, loader, models

__all__ = [
"datasets",
"loader",
"models"
]
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from .arb_dataset import ARBDataset
from .dataset_hypergraph import DatasetHyperGraph
from .imdb_dataset import IMDBHypergraphDataset, ARXIVHypergraphDataset, COURSERAHypergraphDataset
from .imdb_dataset import IMDBHypergraphDataset, ARXIVHypergraphDataset, COURSERAHypergraphDataset, CHLPBaseDataset

__all__ = data_classes = [
'DatasetHyperGraph',
'ARBDataset',
'CHLPBaseDataset',
'IMDBHypergraphDataset',
'COURSERAHypergraphDataset',
'ARXIVHypergraphDataset'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import tarfile
import torch
import torch.nn.functional as F
from hyperlink_prediction.datasets.dataset_hypergraph import DatasetHyperGraph
from .dataset_hypergraph import DatasetHyperGraph
from torch_geometric.data.hypergraph_data import HyperGraphData
from os import remove, listdir

Expand All @@ -22,7 +22,7 @@ class ARBDataset(DatasetHyperGraph):
"tags-math-sx": "1eDevpF6EZs19rLouNpiKGLIlFOLUfKKG",
"contact-high-school": "1VA2P62awVYgluOIh1W4NZQQgkQCBk-Eu",
"contact-primary-school": "1sBHSEIyvVKavAho524Ro4cKL66W6rn-t",
"NDC-substances": "1dLJt3qzAOYieay03Sp9h8ZfVMiU-nMqC"
"NDC-substances": "1mGOg0DMh46J2zQdimSXMde1pKNtfAdh8"
}


Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import torch
import pickle
from abc import ABC
from hyperlink_prediction.datasets.dataset_hypergraph import DatasetHyperGraph
from .dataset_hypergraph import DatasetHyperGraph
from torch_geometric.data.hypergraph_data import HyperGraphData


Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import torch
from typing import List, Any
from torch.utils.data import DataLoader
from utils.set_negative_samplig_method import setNegativeSamplingAlgorithm
from negative_sampling.hypergraph_negative_sampling_algorithm import HypergraphNegativeSampler, MotifHypergraphNegativeSampler
from ...utils.data_and_sampling_selector import setNegativeSamplingAlgorithm
from ...negative_sampling.hypergraph_negative_sampling_algorithm import HypergraphNegativeSampler, MotifHypergraphNegativeSampler
from torch_geometric.data.hypergraph_data import HyperGraphData
from hyperlink_prediction.datasets.dataset_hypergraph import DatasetHyperGraph
from ..datasets.dataset_hypergraph import DatasetHyperGraph


class DatasetLoader(DataLoader):
Expand Down
9 changes: 9 additions & 0 deletions hyperbench/hyperlink_prediction/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from .hyperlink_prediction_base import HyperlinkPredictor
from .hyperlink_prediction_algorithm import CommonNeighbors
from .hyperlink_prediction_result import HyperlinkPredictionResult

__all__ = data_classes = [
'HyperlinkPredictor',
'CommonNeighbors',
'HyperlinkPredictionResult'
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import torch
from torch import Tensor
from .hyperlink_prediction_base import HyperlinkPredictor
from .hyperlink_prediction_result import HyperlinkPredictionResult

class CommonNeighbors(HyperlinkPredictor):
def __init__(self, device='cpu'):
super().__init__(device)
self.H = None
self.num_node = None
self.num_hyperlink = None

def fit(self, X, y, edge_index, *args, **kwargs):

self.num_node = int(edge_index[0].max().item()) + 1
self.num_hyperlink = int(edge_index[1].max().item()) + 1

sparse = torch.sparse_coo_tensor(
edge_index,
torch.ones(edge_index.shape[1], device=self.device),
(self.num_node, edge_index.max().item() + 1),
device=self.device
)

self.H = sparse.to_dense()
return self

def score_CN(self, H, u, v):
return torch.dot(H[u], H[v]).item()

def predict(self, edge_index: Tensor):
if self.H is None:
if edge_index is None:
raise ValueError("Model not fitted. Call fit() first.")
self.fit(None, None, edge_index)
H = self.H

CN_matrix = torch.matmul(H, H.T)

new_edges = torch.nonzero(torch.triu(CN_matrix, diagonal=1)).T

return HyperlinkPredictionResult(
edge_index=new_edges,
device=self.device
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import torch
import numpy as np
from abc import abstractmethod
from .hyperlink_prediction_result import HyperlinkPredictionResult
class HyperlinkPredictor():

def __init__(self, num_node: int, device: torch.device = torch.device('cpu')):
self.num_node = num_node
self.device = device

@abstractmethod
def fit(self, X, y, edge_index, *args, **kwargs):
pass

@abstractmethod
def predict(self, X, edge_index: torch.Tensor) -> HyperlinkPredictionResult:
pass

Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import negative_sampling
from .hypergraph_negative_sampling import HypergraphNegativeSampler
from .hypergraph_negative_sampling_result import HypergraphNegativeSamplerResult, ABSizedHypergraphNegativeSamplerResult
from .hypergraph_negative_sampling_algorithm import ABSizedHypergraphNegativeSampler,SizedHypergraphNegativeSampler, MotifHypergraphNegativeSampler, CliqueHypergraphNegativeSampler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
import torch_geometric.nn.aggr as aggr
from enum import Enum
from torch import Tensor
from negative_sampling.hypergraph_negative_sampling import HypergraphNegativeSampler
from negative_sampling.hypergraph_negative_sampling_result import HypergraphNegativeSamplerResult, ABSizedHypergraphNegativeSamplerResult
from .hypergraph_negative_sampling import HypergraphNegativeSampler
from .hypergraph_negative_sampling_result import HypergraphNegativeSamplerResult, ABSizedHypergraphNegativeSamplerResult

import warnings
warnings.filterwarnings('ignore', category=UserWarning)
Expand Down Expand Up @@ -119,7 +119,7 @@ def generate(self, edge_index: Tensor) -> ABSizedHypergraphNegativeSamplerResult
local_edge_index[1] += num_hyperedges
num_hyperedges = torch.max(local_edge_index[1]) + 1
negative_edge_index = torch.cat([negative_edge_index , local_edge_index], dim = 1)
global_positives = torch.cat([global_positives, probabilities], dim = 0)
global_positives = torch.empty((0, probabilities.shape[1]), dtype=torch.float32, device=self.device)
global_replace_mask = torch.cat([global_replace_mask, replace_mask], dim = 0)
global_replacement = torch.cat([global_replacement, replacement], dim = 0)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import torch_geometric.nn.aggr as aggr
from abc import ABC
from torch import Tensor
from negative_sampling.hypergraph_negative_sampling import HypergraphNegativeSampler
from .hypergraph_negative_sampling import HypergraphNegativeSampler

class HypergraphNegativeSamplerResult(ABC):
""" A class Result which rapresents the hypergraph generated by
Expand Down
5 changes: 5 additions & 0 deletions hyperbench/pipelines/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from . import pipeline

__all__ = [
pipeline
]
22 changes: 7 additions & 15 deletions pipelines/pipeline.py → hyperbench/pipelines/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

def execute():
parser = argparse.ArgumentParser(description="Insert dataset_name, insert negative_sampling method")
parser.add_argument('--dataset_name', type=str, help="The dataset's name, possible dataset's name: \nIMDB,\nCURSERA,\nARXIV", required=True)
parser.add_argument('--dataset_name', type=str, help="The dataset's name, possible dataset's name: \nIMDB,\nCOURSERA,\nARXIV", required=True)
parser.add_argument('--negative_sampling', type=str, help="negative sampling method to use, possible methods: \n SizedHypergraphNegativeSampler,\nMotifHypergraphNegativeSampler,\nCliqueHypergraphNegativeSampler", required=True)
parser.add_argument('--hlp_method', type=str, help="hyperlink prediction method to use, possible method: \nCommonNeighbors", required=True)
parser.add_argument('--output_path', type=str, help="Path to save the results", default="./results")
Expand All @@ -21,11 +21,10 @@ def execute():
import matplotlib.pyplot as plt
import time
from random import randint, seed
from hyperlink_prediction.loader.dataloader import DatasetLoader
from hyperlink_prediction.hyperlink_prediction_algorithm import CommonNeighbors
from hyperlink_prediction.datasets.imdb_dataset import CHLPBaseDataset, IMDBHypergraphDataset, ARXIVHypergraphDataset, COURSERAHypergraphDataset
from utils.set_negative_samplig_method import setNegativeSamplingAlgorithm
from utils.hyperlink_train_test_split import train_test_split
from ..hyperlink_prediction.loader.dataloader import DatasetLoader
from ..hyperlink_prediction.models.hyperlink_prediction_algorithm import CommonNeighbors
from ..utils.data_and_sampling_selector import setNegativeSamplingAlgorithm, select_dataset
from ..utils.hyperlink_train_test_split import train_test_split
from torch_geometric.nn import HypergraphConv
from tqdm.auto import trange, tqdm
from torch_geometric.data.hypergraph_data import HyperGraphData
Expand Down Expand Up @@ -57,14 +56,7 @@ def pre_transform(data: HyperGraphData):

return data

dataset : CHLPBaseDataset
match(dataset_name):
case 'IMDB':
dataset = IMDBHypergraphDataset("./data", pre_transform= pre_transform)
case 'ARXIV':
dataset = ARXIVHypergraphDataset("./data", pre_transform = pre_transform)
case 'COURSERA':
dataset = COURSERAHypergraphDataset("./data", pre_transform = pre_transform)
dataset = select_dataset(dataset_name, pre_transform= pre_transform)

test_size = 0.2
val_size = 0.0
Expand Down Expand Up @@ -170,7 +162,7 @@ def forward(self, x, x_e, edge_index):
negative_test = negative_sampler.generate(h.edge_index)

hlp_method = CommonNeighbors(h.num_nodes)
hlp_result = hlp_method.generate(negative_test.edge_index)
hlp_result = hlp_method.predict(negative_test.edge_index)

y_pos = torch.ones(hlp_result.edge_index.size(1), 1)
y_neg = torch.zeros(negative_test.edge_index.size(1), 1)
Expand Down
7 changes: 7 additions & 0 deletions hyperbench/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from .hyperlink_train_test_split import train_test_split
from .data_and_sampling_selector import setNegativeSamplingAlgorithm, select_dataset
__all__ = [
'train_test_split',
'setNegativeSamplingAlgorithm',
'select_dataset'
]
31 changes: 31 additions & 0 deletions hyperbench/utils/data_and_sampling_selector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from ..hyperlink_prediction.datasets import ARBDataset, IMDBHypergraphDataset, ARXIVHypergraphDataset, COURSERAHypergraphDataset, CHLPBaseDataset
from ..negative_sampling.hypergraph_negative_sampling_algorithm import SizedHypergraphNegativeSampler, MotifHypergraphNegativeSampler, CliqueHypergraphNegativeSampler, HypergraphNegativeSampler

def setNegativeSamplingAlgorithm(ns_algorithm: str, num_node: int):
ns_method : HypergraphNegativeSampler
match(ns_algorithm):
case 'SizedHypergraphNegativeSampler':
ns_method = SizedHypergraphNegativeSampler(num_node)
case 'MotifHypergraphNegativeSampler':
ns_method = MotifHypergraphNegativeSampler(num_node)
case 'CliqueHypergraphNegativeSampler':
ns_method = CliqueHypergraphNegativeSampler(num_node)

return ns_method

def select_dataset(ds: str, pre_transform):

dataset : ARBDataset
if ds in ARBDataset.GDRIVE_IDs.keys():
dataset = ARBDataset(ds, pre_transform= pre_transform)
else:
dataset : CHLPBaseDataset
match(ds):
case 'IMDB':
dataset = IMDBHypergraphDataset("./data", pre_transform= pre_transform)
case 'ARXIV':
dataset = ARXIVHypergraphDataset("./data", pre_transform = pre_transform)
case 'COURSERA':
dataset = COURSERAHypergraphDataset("./data", pre_transform = pre_transform)

return dataset
13 changes: 0 additions & 13 deletions hyperlink_prediction/__init__.py

This file was deleted.

27 changes: 0 additions & 27 deletions hyperlink_prediction/hyperlink_prediction_algorithm.py

This file was deleted.

24 changes: 0 additions & 24 deletions hyperlink_prediction/hyperlink_prediction_base.py

This file was deleted.

6 changes: 0 additions & 6 deletions pipelines/__init__.py

This file was deleted.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ dependencies = [
requires-python = ">=3.9"

[project.scripts]
pipeline = "pipelines.pipeline:execute"
pipeline = "hyperbench.pipelines.pipeline:execute"

[project.urls]
Homepage = "https://www.isislab.it/"
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
include_package_data=True,
entry_points={
'console_scripts': [
'pipeline=pipelines.pipeline:execute',
'pipeline=hyperbench.pipelines.pipeline:execute',
],
},
install_requires=[],
Expand Down
5 changes: 5 additions & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from . import methods_test

__all__ = [
"methods_test"
]
Loading