| Node Embedding Attack and Defense |
| ======================= |
| In this section, we introduce the node embedding attack algorithms and |
| corresponding victim models provided in DeepRobust. |
|
|
| .. contents:: |
| :local: |
|
|
|
|
| Node Embedding Attack |
| ----------------------- |
| Node embedding attack aims to fool node embedding models produce bad-quality embeddings. |
| Specifically, DeepRobust provides the following node attack algorithms: |
|
|
| - :class:`deeprobust.graph.global_attack.NodeEmbeddingAttack` |
| - :class:`deeprobust.graph.global_attack.OtherNodeEmbeddingAttack` |
|
|
| They only take the adjacency matrix as input and the adjacency |
| matrix is in the format of :obj:`scipy.sparse.csr_matrix`. You can specify the attack_type |
| to either add edges or remove edges. Let's take a look at an example: |
|
|
| .. code-block:: python |
|
|
| from deeprobust.graph.data import Dataset |
| from deeprobust.graph.global_attack import NodeEmbeddingAttack |
| data = Dataset(root='/tmp/', name='cora_ml', seed=15) |
| adj, features, labels = data.adj, data.features, data.labels |
| model = NodeEmbeddingAttack() |
| model.attack(adj, attack_type="remove") |
| modified_adj = model.modified_adj |
| model.attack(adj, attack_type="remove", min_span_tree=True) |
| modified_adj = model.modified_adj |
| model.attack(adj, attack_type="add", n_candidates=10000) |
| modified_adj = model.modified_adj |
| model.attack(adj, attack_type="add_by_remove", n_candidates=10000) |
| modified_adj = model.modified_adj |
|
|
| The :obj:`OtherNodeEmbeddingAttack` contains the baseline methods reported in the paper |
| Adversarial Attacks on Node Embeddings via Graph Poisoning. Aleksandar Bojchevski and |
| Stephan Günnemann, ICML 2019. We can specify the type (chosen from |
| `["degree", "eigencentrality", "random"]`) to generate corresponding attacks. |
|
|
| .. code-block:: python |
|
|
| from deeprobust.graph.data import Dataset |
| from deeprobust.graph.global_attack import OtherNodeEmbeddingAttack |
| data = Dataset(root='/tmp/', name='cora_ml', seed=15) |
| adj, features, labels = data.adj, data.features, data.labels |
| model = OtherNodeEmbeddingAttack(type='degree') |
| model.attack(adj, attack_type="remove") |
| modified_adj = model.modified_adj |
| |
| model = OtherNodeEmbeddingAttack(type='eigencentrality') |
| model.attack(adj, attack_type="remove") |
| modified_adj = model.modified_adj |
| |
| model = OtherNodeEmbeddingAttack(type='random') |
| model.attack(adj, attack_type="add", n_candidates=10000) |
| modified_adj = model.modified_adj |
|
|
| Node Embedding Victim Models |
| ----------------------- |
| DeepRobust provides two node embedding victim models, DeepWalk and Node2Vec: |
|
|
| - :class:`deeprobust.graph.defense.DeepWalk` |
| - :class:`deeprobust.graph.defense.Node2Vec` |
|
|
| There are three major functions in the two classes: :obj:`fit()`, :obj:`evaluate_node_classification()` |
| and :obj:`evaluate_link_prediction`. The function :obj:`fit()` will train the node embdding models |
| and store the embedding in :obj:`self.embedding`. For example, |
|
|
| .. code-block:: python |
|
|
| from deeprobust.graph.data import Dataset |
| from deeprobust.graph.defense import DeepWalk |
| from deeprobust.graph.global_attack import NodeEmbeddingAttack |
| import numpy as np |
|
|
| dataset_str = 'cora_ml' |
| data = Dataset(root='/tmp/', name=dataset_str, seed=15) |
| adj, features, labels = data.adj, data.features, data.labels |
| idx_train, idx_val, idx_test = data.idx_train, data.idx_val, data.idx_test |
|
|
| print("Test DeepWalk on clean graph") |
| model = DeepWalk(type="skipgram") |
| model.fit(adj) |
| print(model.embedding) |
|
|
| After we trained the model, we can then test its performance on node classification and link prediction: |
|
|
| .. code-block:: python |
|
|
| print("Test DeepWalk on node classification...") |
| |
| model.evaluate_node_classification(labels, idx_train, idx_test) |
| print("Test DeepWalk on link prediciton...") |
| model.evaluate_link_prediction(adj, np.array(adj.nonzero()).T) |
|
|
| We can then test its performance on the attacked graph: |
|
|
| .. code-block:: python |
|
|
| |
| attacker = NodeEmbeddingAttack() |
| attacker.attack(adj, attack_type="remove", n_perturbations=1000) |
| modified_adj = attacker.modified_adj |
| print("Test DeepWalk on attacked graph") |
| model.fit(modified_adj) |
| model.evaluate_node_classification(labels, idx_train, idx_test) |
|
|
|
|