Loads the Cora dataset. The dataset is downloaded from https://linqs-data.soe.ucsc.edu/public/lbc/cora.tgz.
(path='./cora', device='cpu')
| 207 | ################################ |
| 208 | |
| 209 | def load_cora(path='./cora', device='cpu'): |
| 210 | """ |
| 211 | Loads the Cora dataset. The dataset is downloaded from https://linqs-data.soe.ucsc.edu/public/lbc/cora.tgz. |
| 212 | |
| 213 | """ |
| 214 | |
| 215 | # Set the paths to the data files |
| 216 | content_path = os.path.join(path, 'cora.content') |
| 217 | cites_path = os.path.join(path, 'cora.cites') |
| 218 | |
| 219 | # Load data from files |
| 220 | content_tensor = np.genfromtxt(content_path, dtype=np.dtype(str)) |
| 221 | cites_tensor = np.genfromtxt(cites_path, dtype=np.int32) |
| 222 | |
| 223 | # Process features |
| 224 | features = torch.FloatTensor(content_tensor[:, 1:-1].astype(np.int32)) # Extract feature values |
| 225 | scale_vector = torch.sum(features, dim=1) # Compute sum of features for each node |
| 226 | scale_vector = 1 / scale_vector # Compute reciprocal of the sums |
| 227 | scale_vector[scale_vector == float('inf')] = 0 # Handle division by zero cases |
| 228 | scale_vector = torch.diag(scale_vector).to_sparse() # Convert the scale vector to a sparse diagonal matrix |
| 229 | features = scale_vector @ features # Scale the features using the scale vector |
| 230 | |
| 231 | # Process labels |
| 232 | classes, labels = np.unique(content_tensor[:, -1], return_inverse=True) # Extract unique classes and map labels to indices |
| 233 | labels = torch.LongTensor(labels) # Convert labels to a tensor |
| 234 | |
| 235 | # Process adjacency matrix |
| 236 | idx = content_tensor[:, 0].astype(np.int32) # Extract node indices |
| 237 | idx_map = {id: pos for pos, id in enumerate(idx)} # Create a dictionary to map indices to positions |
| 238 | |
| 239 | # Map node indices to positions in the adjacency matrix |
| 240 | edges = np.array( |
| 241 | list(map(lambda edge: [idx_map[edge[0]], idx_map[edge[1]]], |
| 242 | cites_tensor)), dtype=np.int32) |
| 243 | |
| 244 | V = len(idx) # Number of nodes |
| 245 | E = edges.shape[0] # Number of edges |
| 246 | adj_mat = torch.sparse_coo_tensor(edges.T, torch.ones(E), (V, V), dtype=torch.int64) # Create the initial adjacency matrix as a sparse tensor |
| 247 | adj_mat = torch.eye(V) + adj_mat # Add self-loops to the adjacency matrix |
| 248 | |
| 249 | # return features.to_sparse().to(device), labels.to(device), adj_mat.to_sparse().to(device) |
| 250 | return features.to(device), labels.to(device), adj_mat.to(device) |
| 251 | |
| 252 | ################################# |
| 253 | ### TRAIN AND TEST FUNCTIONS ### |