GNN

图神经网络。

分类器

属性 labels_ 为图的每个节点分配一个标签。

class sknetwork.gnn.GNNClassifier(dims: int | Iterable | None = None, layer_types: str | Iterable = 'Conv', activations: str | Iterable = 'ReLu', use_bias: bool | list = True, normalizations: str | Iterable = 'both', self_embeddings: bool | Iterable = True, sample_sizes: int | list = 25, loss: BaseLoss | str = 'CrossEntropy', layers: Iterable | None = None, optimizer: BaseOptimizer | str = 'Adam', learning_rate: float = 0.01, early_stopping: bool = True, patience: int = 10, verbose: bool = False)[source]

用于节点分类的图神经网络。

参数:
  • dims (iterable or int) – 每一层输出的维度(在正向方向)。如果为整数,则为输出层的维度(没有隐藏层)。如果指定了 layers,则可选。

  • layer_types (iterable or str) – 层类型(在正向方向)。如果为字符串,则在每一层使用相同的类型。可以为 'Conv',图卷积层(默认)或 'Sage'(GraphSage)。

  • activations (iterable or str) – 激活函数(在正向方向)。如果为字符串,则在每一层使用相同的激活函数。可以是 'Identity''Relu''Sigmoid''Softmax'(默认 = 'Relu')。

  • use_bias (iterable or bool) – 是否在每一层添加偏置项(在正向方向)。如果为 True,则在每一层使用偏置项。

  • normalizations (iterable or str) – 用于消息传递的邻接矩阵的规范化(在正向方向)。如果为字符串,则在每一层使用相同类型的规范化。可以是 'left'(按度进行左规范化),'right'(按度进行右规范化),'both'(按度的平方根进行对称规范化,默认)或 None(不规范化)。

  • self_embeddings (iterable or str) – 是否为消息传递添加每个节点的嵌入(在正向方向)。如果为 True,则在每一层添加自嵌入。

  • sample_sizes (iterable or int) – 为每个节点采样的邻域的大小(在正向方向)。如果为整数,则在每一层使用相同的采样大小。仅用于 'Sage' 层类型。

  • loss (str (default = 'CrossEntropy') or BaseLoss) – 损失函数的名称或自定义损失函数。

  • layers (iterable or None) – 自定义层(在正向方向)。如果使用,则忽略之前的参数。

  • optimizer (str or optimizer) –

    • 'Adam',基于随机梯度的优化器(默认)。

    • 'GD',梯度下降。

  • learning_rate (float) – 学习率。

  • early_stopping (bool (default = True)) – 是否使用提前停止来结束训练。如果为 True,则当验证分数在 patience 个 epoch 内没有改善时,训练就会终止。

  • patience (int (default = 10)) – 在停止拟合之前等待没有改进的迭代次数。

  • verbose (bool) – 详细模式。

变量:
  • conv1 (conv2, ...,) – 图卷积层。

  • output (np.ndarray) – GNN 的输出。

  • labels (np.ndarray) – 预测的节点标签。

  • history (dict) – 每个 epoch 的训练历史:{'embedding''loss''train_accuracy''val_accuracy'}。

示例

>>> from sknetwork.gnn.gnn_classifier import GNNClassifier
>>> from sknetwork.data import karate_club
>>> from numpy.random import randint
>>> graph = karate_club(metadata=True)
>>> adjacency = graph.adjacency
>>> labels_true = graph.labels
>>> labels = {i: labels_true[i] for i in [0, 1, 33]}
>>> features = adjacency.copy()
>>> gnn = GNNClassifier(dims=1, early_stopping=False)
>>> labels_pred = gnn.fit_predict(adjacency, features, labels, random_state=42)
>>> round(np.mean(labels_pred == labels_true), 2)
0.88
backward(features: csr_matrix, labels: ndarray, mask: ndarray)

计算反向传播。

参数:
  • features (sparse.csr_matrix) – 特征,形状为 (n_nodes, n_features) 的数组。

  • labels (np.ndarray) – 标签,形状为 (n_nodes,) 的数组。

  • mask (np.ndarray) – 布尔掩码,形状为 (n_nodes,) 的数组。

fit(adjacency: csr_matrix | ndarray, features: csr_matrix | ndarray, labels: ndarray, n_epochs: int = 100, validation: float = 0, reinit: bool = False, random_state: int | None = None) GNNClassifier[source]

将模型拟合到数据并存储训练参数。

参数:
  • adjacency (sparse.csr_matrix) – 图的邻接矩阵。

  • features (sparse.csr_matrix, np.ndarray) – 输入特征,形状为 \((n, d)\),其中 \(n\) 是图中节点的数量,\(d\) 是特征空间的大小。

  • labels (dict, np.ndarray) – 已知标签。负值被忽略。

  • n_epochs (int (default = 100)) – 迭代次数(遍历整个图的次数)。

  • validation (float) – 用于验证的训练集比例(介于 0 和 1 之间)。

  • reinit (bool (default = False)) – 如果为 True,则重新初始化 GNN 的可训练参数(权重和偏差)。

  • random_state (int) – 随机种子,用于在多次运行中获得可重复的结果。

fit_predict(*args, **kwargs) ndarray

将算法拟合到数据并返回标签。与 fit 方法的参数相同。

返回值:

labels – 节点的标签。

返回类型:

np.ndarray

fit_predict_proba(*args, **kwargs) ndarray

将算法拟合到数据并返回标签的分布。与 fit 方法的参数相同。

返回值:

probs – 标签的概率分布。

返回类型:

np.ndarray

fit_transform(*args, **kwargs) ndarray

将算法拟合到数据并返回节点的嵌入。与 fit 方法的参数相同。

返回值:

embedding – 节点的嵌入。

返回类型:

np.ndarray

forward(adjacency: list | csr_matrix, features: csr_matrix | ndarray) ndarray[source]

在图上执行前向传递并返回输出。

参数:
  • adjacency (Union[list, sparse.csr_matrix]) – 邻接矩阵或采样邻接矩阵列表。

  • features (sparse.csr_matrix, np.ndarray) – 特征,形状为 (n_nodes, n_features) 的数组。

返回值:

output – GNN 的输出。

返回类型:

np.ndarray

get_params()

以字典形式获取参数。

返回值:

params – 算法的参数。

返回类型:

dict

predict()

返回预测的标签。

predict_proba()

返回标签的概率分布。

print_log(*args)

用文本填充日志。

set_params(params: dict) Algorithm

设置算法的参数。

参数:

params (dict) – 算法的参数。

返回值:

self

返回类型:

Algorithm

transform()

返回节点的嵌入。

卷积层

class sknetwork.gnn.Convolution(layer_type: str, out_channels: int, activation: BaseActivation | str | None = 'Relu', use_bias: bool = True, normalization: str = 'both', self_embeddings: bool = True, sample_size: int | None = None, loss: BaseLoss | str | None = None)[source]

图卷积层。

将以下函数应用于嵌入 \(X\)

\(\sigma(\bar AXW + b)\),

其中 \(\bar A\) 是归一化的邻接矩阵(可能包含插入的自嵌入),\(W\)\(b\) 是可训练参数,\(\sigma\) 是激活函数。

参数:
  • layer_type (str) – 层类型。可以是 'Conv',卷积运算符如 [1] 中所述,或 'Sage',如 [2] 中所述。

  • out_channels (int) – 输出的维度。

  • 激活函数 (str (默认 = 'Relu') 或自定义激活函数。) – 激活函数。如果为字符串,可以是 'Identity''Relu''Sigmoid''Softmax'

  • 使用偏差 (bool (默认 = True)) – 如果 True,则添加偏差向量。

  • 归一化 (str (默认 = 'both')) – 用于消息传递的邻接矩阵的归一化。可以是 ‘left’` (根据度进行左归一化)、'right' (根据度进行右归一化)、'both' (根据度的平方根进行对称归一化,默认) 或 None (不进行归一化)。

  • 自嵌入 (bool (默认 = True)) – 如果 True,则除了图中每个节点的邻居嵌入之外,还要考虑自嵌入。

  • 样本大小 (int (默认 = 25)) – 每个节点采样的邻域的大小。仅用于 'Sage' 层。

变量:
  • 权重 (np.ndarray,) – 可训练的权重矩阵。

  • 偏差 (np.ndarray) – 偏差向量。

  • 嵌入 (np.ndarray) – 节点的嵌入 (在激活之前)。

  • 输出 (np.ndarray) – 层的输出 (在激活之后)。

参考资料

[1] Kipf, T., & Welling, M. (2017). 使用图卷积网络进行半监督分类。 第五届国际学习表征大会。

[2] Hamilton, W. Ying, R., & Leskovec, J. (2017) 大型图上的归纳式表示学习。 NIPS

forward(adjacency: csr_matrix | ndarray, features: csr_matrix | ndarray) ndarray[source]

计算图卷积。

参数:
  • 邻接矩阵 – 图的邻接矩阵。

  • features (sparse.csr_matrix, np.ndarray) – 输入特征,形状为 \((n, d)\),其中 \(n\) 是图中节点的数量,\(d\) 是特征空间的大小。

返回值:

输出 – 层的输出。

返回类型:

np.ndarray

激活函数

class sknetwork.gnn.BaseActivation(name: str = 'custom')[source]

激活函数的基类。:param name: 激活函数的名称。:type name: str

static gradient(signal: ndarray, direction: ndarray) ndarray[source]

激活函数的梯度。

参数:
  • 信号 (np.ndarray, shape (n_samples, n_channels)) – 输入信号。

  • 方向 (np.ndarray, shape (n_samples, n_channels)) – 获取梯度的方向。

返回值:

梯度 – 梯度。

返回类型:

np.ndarray,shape (n_samples, n_channels)

static output(signal: ndarray) ndarray[source]

激活函数的输出。

参数:

信号 (np.ndarray, shape (n_samples, n_channels)) – 输入信号。

返回值:

输出 – 输出信号。

返回类型:

np.ndarray,shape (n_samples, n_channels)

class sknetwork.gnn.ReLu[source]

ReLu (修正线性单元) 激活函数

\(\sigma(x) = \max(0, x)\)

static gradient(signal: ndarray, direction: ndarray) ndarray[source]

ReLu 函数的梯度。

static output(signal: ndarray) ndarray[source]

ReLu 函数的输出。

class sknetwork.gnn.Sigmoid[source]

Sigmoid 激活函数

\(\sigma(x) = \frac{1}{1+e^{-x}}\) 也称为逻辑函数。

static gradient(signal: ndarray, direction: ndarray) ndarray[source]

sigmoid 函数的梯度。

static output(signal: ndarray) ndarray[source]

sigmoid 函数的输出。

class sknetwork.gnn.Softmax[source]

Softmax 激活函数

\(\sigma(x) = (\frac{e^{x_1}}{\sum_{i=1}^N e^{x_i})},\ldots,\frac{e^{x_N}}{\sum_{i=1}^N e^{x_i})})\)

其中 \(N\) 是通道数。

static gradient(signal: ndarray, direction: ndarray) ndarray[source]

softmax 函数的梯度。

static output(signal: ndarray) ndarray[source]

softmax 函数的输出 (行和为 1)。

损失函数

class sknetwork.gnn.BaseLoss(name: str = 'custom')[source]

损失函数的基类。

static gradient(signal: ndarray, direction: ndarray) ndarray

激活函数的梯度。

参数:
  • 信号 (np.ndarray, shape (n_samples, n_channels)) – 输入信号。

  • 方向 (np.ndarray, shape (n_samples, n_channels)) – 获取梯度的方向。

返回值:

梯度 – 梯度。

返回类型:

np.ndarray,shape (n_samples, n_channels)

static loss(signal: ndarray, labels: ndarray) float[source]

获取损失值。

参数:
  • signal (np.ndarray, shape (n_samples, n_channels)) – 输入信号(激活前)。

  • labels (np.ndarray, shape (n_samples)) – 真实标签。

static loss_gradient(signal: ndarray, labels: ndarray) ndarray[source]

损失函数的梯度。

参数:
  • 信号 (np.ndarray, shape (n_samples, n_channels)) – 输入信号。

  • labels (np.ndarray, shape (n_samples,)) – 真实标签。

返回值:

梯度 – 梯度。

返回类型:

np.ndarray,shape (n_samples, n_channels)

static output(signal: ndarray) ndarray

激活函数的输出。

参数:

信号 (np.ndarray, shape (n_samples, n_channels)) – 输入信号。

返回值:

输出 – 输出信号。

返回类型:

np.ndarray,shape (n_samples, n_channels)

class sknetwork.gnn.CrossEntropy[source]

带softmax激活的交叉熵损失。

对于一个值为 \(x\)、真实标签为 \(y\) 的单个样本,交叉熵损失为

\(-\sum_i 1_{\{y=i\}} \log (p_i)\)

其中

\(p_i = e^{x_i} / \sum_j e^{x_j}\).

对于 \(n\) 个样本,返回平均损失。

static gradient(signal: ndarray, direction: ndarray) ndarray

softmax 函数的梯度。

static loss(signal: ndarray, labels: ndarray) float[source]

获取损失值。

参数:
  • signal (np.ndarray, shape (n_samples, n_channels)) – 输入信号(激活前)。通道数必须至少为2。

  • labels (np.ndarray, shape (n_samples)) – 真实标签。

返回值:

value – 损失值。

返回类型:

float

static loss_gradient(signal: ndarray, labels: ndarray) ndarray[source]

获取损失函数的梯度(包括激活)。

参数:
  • signal (np.ndarray, shape (n_samples, n_channels)) – 输入信号(激活前)。

  • labels (np.ndarray, shape (n_samples)) – 真实标签。

返回值:

gradient – 损失函数的梯度。

返回类型:

float

static output(signal: ndarray) ndarray

softmax 函数的输出 (行和为 1)。

class sknetwork.gnn.BinaryCrossEntropy[source]

带sigmoid激活的二元交叉熵损失。

对于一个真实标签为 \(y\)、预测概率为 \(p\) 的单个样本,二元交叉熵损失为

\(-y \log (p) - (1-y) \log (1 - p).\)

对于 \(n\) 个样本,返回平均损失。

static gradient(signal: ndarray, direction: ndarray) ndarray

sigmoid 函数的梯度。

static loss(signal: ndarray, labels: ndarray) float[source]

获取损失值。

参数:
  • signal (np.ndarray, shape (n_samples, n_channels)) – 输入信号(激活前)。通道数必须至少为2。

  • labels (np.ndarray, shape (n_samples)) – 真实标签。

返回值:

value – 损失值。

返回类型:

float

static loss_gradient(signal: ndarray, labels: ndarray) ndarray[source]

获取损失函数的梯度(包括激活)。

参数:
  • signal (np.ndarray, shape (n_samples, n_channels)) – 输入信号(激活前)。

  • labels (np.ndarray, shape (n_samples)) – 真实标签。

返回值:

gradient – 损失函数的梯度。

返回类型:

float

static output(signal: ndarray) ndarray

sigmoid 函数的输出。

优化器

class sknetwork.gnn.BaseOptimizer(learning_rate)[source]

优化器的基类。

参数:

learning_rate (float (default = 0.01)) – 用于更新权重的学习率。

step(gnn: BaseGNN)[source]

根据梯度值更新模型参数。

参数:

gnn (BaseGNNClassifier) – 包含要更新的参数的模型。

class sknetwork.gnn.ADAM(learning_rate: float = 0.01, beta1: float = 0.9, beta2: float = 0.999, eps: float = 1e-08)[source]

Adam 优化器。

参数:
  • learning_rate (float (default = 0.01)) – 用于更新权重的学习率。

  • beta1 (float) – 用于计算梯度运行平均值的系数。

  • beta2 (float) – 用于计算梯度运行平均值的系数。

  • eps (float (默认值 = 1e-8)) – 添加到分母的项,以提高稳定性。

参考资料

Kingma, D. P. 和 Ba, J. (2014)。Adam: 一种随机优化方法。 第 3 届国际学习表征会议。

step(gnn: BaseGNN)[source]

根据梯度值和参数更新模型参数。

参数:

gnn (BaseGNNClassifier) – 包含要更新的参数的模型。

class sknetwork.gnn.GD(learning_rate: float = 0.01)[source]

梯度下降优化器。

参数:

learning_rate (float (default = 0.01)) – 用于更新权重的学习率。

step(gnn: BaseGNN)[source]

根据梯度值更新模型参数。

参数:

gnn (BaseGNNClassifier) – 包含要更新的参数的模型。