Biểu diễn graph cho bài toán clasification

Posted by Hao Do on February 20, 2023

Biểu diễn graph cho bài toán clasification

Pytorch library

1
2
3
4
5
6
7
import torch

!pip3 uninstall torch-scatter torch-sparse torch-geometric torch-cluster  --y
!pip3 install torch-scatter -f https://data.pyg.org/whl/torch-{torch.__version__}.html
!pip3 install torch-sparse -f https://data.pyg.org/whl/torch-{torch.__version__}.html
!pip3 install torch-cluster -f https://data.pyg.org/whl/torch-{torch.__version__}.html
!pip3 install git+https://github.com/pyg-team/pytorch_geometric.git
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import numpy as np
import pandas as pd
import pickle
import csv
import os
import torch
from torch_geometric.data import Data
from torch_geometric.nn import MessagePassing
import math
import torch
import torch.nn.functional as F
from torch.nn import Parameter
from torch_geometric.nn.conv import MessagePassing
import os
import os.path as osp
import torch
import torch.nn.functional as F
from torch_geometric.datasets import Planetoid
import torch_geometric.transforms as T
from torch_geometric.datasets import TUDataset
from torch_geometric.utils import degree
import torch_geometric.transforms as T
import time

import torch
import torch.nn.functional as F
from torch import tensor
from torch.optim import Adam
from sklearn.model_selection import StratifiedKFold
from torch_geometric.data import DataLoader, DenseDataLoader as DenseLoader
import torch
import torch.nn.functional as F
from torch.nn import Linear, Sequential, ReLU, BatchNorm1d as BN
from torch_geometric.nn import global_mean_pool, MessagePassing
from torch_geometric.utils import remove_self_loops
from itertools import product
np.random.seed(42)

x: vector đặc trưng của mỗi node, trong ví dụ len(vector_node) = 2

y: nhãn mỗi node (hiện tại có 4 nút, gồm có 2 nhãn)

edge_index: ma trận 2 * 5 (có 5 cạnh, 2 thể hiện là node i vs node j kết nối với nhau)

data: thể hiện là một đồ thị tương ứng.

1
2
3
4
5
6
7
8
9
10
11
12
import torch
from torch_geometric.data import Data


x = torch.tensor([[2,1], [5,6], [3,7], [12,0]], dtype=torch.float)
y = torch.tensor([0, 1, 0, 1], dtype=torch.float)

edge_index = torch.tensor([[0, 2, 1, 0, 3],
                           [3, 1, 0, 1, 2]], dtype=torch.long)

data = Data(x=x, y=y, edge_index=edge_index)
print(data)

Keras Library

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import os
import pandas as pd
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow import keras
from keras import layers

zip_file = keras.utils.get_file(
    fname="cora.tgz",
    origin="https://linqs-data.soe.ucsc.edu/public/lbc/cora.tgz",
    extract=True,
)
data_dir = os.path.join(os.path.dirname(zip_file), "cora")

citations = pd.read_csv(
    os.path.join(data_dir, "cora.cites"),
    sep="\t",
    header=None,
    names=["target", "source"],
)
print("Citations shape:", citations.shape)
citations.sample(frac=1).head()

citations: cho biết node nào kết nối với node nào? node_i với node_j

1
2
3
4
5
6
7
column_names = ["paper_id"] + [f"term_{idx}" for idx in range(1433)] + ["subject"]
papers = pd.read_csv(
    os.path.join(data_dir, "cora.content"), sep="\t", header=None, names=column_names,
)
print("Papers shape:", papers.shape)
print(papers.sample(5).T)
print(papers.subject.value_counts())

papers: mỗi node_i gồm có một vector với 1434 giá trị và một nhãn cho nút đó (ở cột cuối cùng)

Lưu ý: lúc này nó sẽ sinh ra rất nhiều graph KHÔNG LIÊN THÔNG VỚI NHAU

Việc này là node classification

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class_values = sorted(papers["subject"].unique())
class_idx = {name: id for id, name in enumerate(class_values)}
paper_idx = {name: idx for idx, name in enumerate(sorted(papers["paper_id"].unique()))}

papers["paper_id"] = papers["paper_id"].apply(lambda name: paper_idx[name])
citations["source"] = citations["source"].apply(lambda name: paper_idx[name])
citations["target"] = citations["target"].apply(lambda name: paper_idx[name])
papers["subject"] = papers["subject"].apply(lambda value: class_idx[value])

colors = papers["subject"].tolist()
cora_graph = nx.from_pandas_edgelist(citations.sample(n=1500))
subjects = list(papers[papers["paper_id"].isin(list(cora_graph.nodes))]["subject"])

train_data, test_data = [], []

for _, group_data in papers.groupby("subject"):
    # Select around 50% of the dataset for training.
    random_selection = np.random.rand(len(group_data.index)) <= 0.5
    train_data.append(group_data[random_selection])
    test_data.append(group_data[~random_selection])

train_data = pd.concat(train_data).sample(frac=1)
test_data = pd.concat(test_data).sample(frac=1)

print("Train data shape:", train_data.shape)
print("Test data shape:", test_data.shape)

stellargraph library

1
2
3
4
5
6
7
8
9
10
11
12
13
14
!pip3 install stellargraph
import pandas as pd
import os

import stellargraph as sg
from stellargraph.mapper import FullBatchNodeGenerator
from stellargraph.layer import GCN

from keras import layers, optimizers, losses, metrics, Model
from sklearn import preprocessing, model_selection
from IPython.display import display, HTML
import matplotlib.pyplot as plt
%matplotlib inline

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from stellargraph.datasets import Cora
import os

cora = Cora()
cora.download()

# the base_directory property tells us where it was downloaded to:
cora_cites_file = os.path.join(cora.base_directory, "cora.cites")
cora_content_file = os.path.join(cora.base_directory, "cora.content")

cora_cites = pd.read_csv(
    cora_cites_file,
    sep="\t",  # tab-separated
    header=None,  # no heading row
    names=["target", "source"],  # set our own names for the columns
)
cora_cites

cora_feature_names = [f"w{i}" for i in range(1433)]

cora_raw_content = pd.read_csv(
    cora_content_file,
    sep="\t",  # tab-separated
    header=None,  # no heading row
    names=["id", *cora_feature_names, "subject"],  # set our own names for the columns
)
cora_raw_content

cora_content_str_subject = cora_raw_content.set_index("id")
cora_content_str_subject

cora_content_no_subject = cora_content_str_subject.drop(columns="subject")
cora_content_no_subject


citations: cho biết node nào kết nối với node nào? node_i với node_j

papers: mỗi node_i gồm có một vector với 1434 giá trị và một nhãn cho nút đó (ở cột cuối cùng)

Lưu ý: lúc này nó sẽ sinh ra rất nhiều graph KHÔNG LIÊN THÔNG VỚI NHAU

Việc này là node classification

Cái này chỉ tạo ra một đồ thị thôi, tuy nhiên có rất nhiều đồ thị “nhỏ” và không liên thông với nhau.

Sau đó, sử dụng StellarGraph này để thực hiện các bài toán về Node classification hoặc các bài toán về Link Prediction.

Việc Graph classification đang hơi phức tạp.

Bài Graph classification: nên tham khảo và code trực tiếp ở đây: https://github.com/ailabteam/MAppGraph/blob/gh-pages/mappgraph/notebooks/train_GNN.ipynb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from stellargraph import StellarGraph

cora_no_subject = StellarGraph({"paper": cora_content_no_subject}, {"cites": cora_cites})
print(cora_no_subject.info())

cora_subject = cora_content_str_subject["subject"]
cora_subject

from sklearn import model_selection

cora_train, cora_test = model_selection.train_test_split(
    cora_subject, train_size=0.25, random_state=123
)
cora_train
cora_test

cora_content_one_hot_subject = pd.get_dummies(
    cora_content_str_subject, columns=["subject"]
)
cora_content_one_hot_subject

cora_one_hot_subject = StellarGraph(
    {"paper": cora_content_one_hot_subject}, {"cites": cora_cites}
)
print(cora_one_hot_subject.info())

Tài liệu tham khảo

Internet

Hết.