Графикҳо як роҳи пурқудрати муаррифии додаҳо мебошанд, ки муносибатҳои байни объектҳоро дар доираи барномаҳои гуногун ба таври беназир сабт мекунанд. Новобаста аз он ки шумо шабакаҳои иҷтимоӣ, мутақобилаи сафедаҳо, системаҳои нақлиётӣ ё муҳаррикҳои тавсияшавандаро моделсозӣ мекунед, графикҳо табиатан ин вобастагии мураккаби мутақобиларо муаррифӣ ва таҳлил мекунанд. Дар ҷаҳони имрӯза, ки ба маълумот асос ёфтааст, фаҳмидани муносибатҳои байни субъектҳо одатан ба мисли фаҳмидани худи субъектҳо муҳим аст - дар ин ҷо графикҳо воқеан дурахшон мешаванд. яке аз вазифаҳои асосии таҳлили графикӣ мебошад, ки пешгӯии робитаҳо (ё пайвандҳо) байни гиреҳҳоро (объектҳое, ки дар график нишон дода шудаанд) дар бар мегирад. Тасаввур кунед, ки тавсия додани дӯстони нав дар шабакаи иҷтимоӣ, пешгӯии ҳамкориҳои эҳтимолӣ дар графики иқтибосҳои академӣ ё пешгӯии ҳамкории ояндаи байни корбарон ва маҳсулот дар муҳити тиҷорати электронӣ - ин ҳама намунаҳои пешгӯии пайванд дар амал мебошанд. Ин вазифа барои васеъ кардани шабакаҳо, хулоса баровардани маълумоти нопурра ва ошкор кардани аномалияҳо кӯмак мекунад. Барои барномаҳое, ки аз такмил додани таҷрибаи корбар то беҳтар кардани ошкорсозии қаллобӣ иборатанд, пешгӯии истинод ҷузъи калидии муваффақият аст. Пешгӯии пайванд Барои нишон додани пешгӯии истинод, мо аз Лоиҳаи таҳлили шабакаи Стэнфорд (SNAP) истифода хоҳем кард. Ин маҷмӯаи маълумот робитаҳои иҷтимоии байни корбаронро дар платформаи ҷараёнҳои Twitch сабт мекунад, ки дар он гиреҳҳо корбарони Twitch ва кунҷҳо дӯстии байни онҳоро ифода мекунанд. Маҷмӯи додаҳо сохтори хуб дорад, ки коркарди пешакӣ ва кор бо он осон аст. маҷмӯи додаҳои шабакаи иҷтимоии Twitch Бо пайравӣ, шумо чӣ гуна сохтани лоиҳа, коркарди пешакии маълумот, сохтани модел ва баҳодиҳии онро барои пешгӯии истинод дар маҷмӯаи додаҳои воқеиро меомӯзед. Шабакаҳои нейронии графикӣ ва китобхонаи амиқи графикӣ Кор бо додаҳои аз рӯи график сохташуда мушкилоти беназиреро пеш меорад ва дар ин ҷо ворид мешаванд. GNNҳо як намуди шабакаи нейронӣ мебошанд, ки махсус барои кор бо маълумоти графикӣ тарҳрезӣ шудаанд. Баръакси шабакаҳои нейронии анъанавӣ, ки дар вуруди андозаи собит кор мекунанд, GNNҳо метавонанд андозаи графикҳои ихтиёриро идора кунанд ва намунаҳои пайвастшавӣ дар дохили маълумотро истифода баранд. Бо ҷамъ овардани иттилоот аз ҳамсояҳои гиреҳ, GNNҳо намояндагиҳоро меомӯзанд, ки ҳам атрибутҳои гиреҳ ва ҳам сохтори графикро мегиранд ва онҳоро барои вазифаҳое ба мисли таснифоти гиреҳ, пешгӯии пайвандҳо ва таснифоти графикӣ самаранок мегардонанд. Шабакаҳои Neural Graph (GNNs) як абзорест, ки барои сохтани GNN-ҳо бо осонӣ ва муассир аст. Бо DGL, таҳиягарон метавонанд аз меъмории муосири GNN истифода баранд, то вазифаҳои гуногунро ҳал кунанд, аз ҷумла пешгӯии пайванд. DGL як қатор хидматҳоро барои кор бо графикҳои якхела ва гетерогенӣ таъмин мекунад, ки онро барои муҳаққиқон ва таҷрибаомӯзон як абзори ҳамаҷониба месозад. Бо содда кардани татбиқи GNNs, DGL ба шумо имкон медиҳад, ки бештар ба таҳияи қарорҳои инноватсионӣ диққат диҳед, на ба мушкилиҳои асосии техникӣ дучор шудан. Китобхонаи Deep Graph ( ) DGL.ai Бо дарназардошти ин асос, биёед бо истифода аз GNNs ва модели пешгӯии истинодро бунёд кунем. DGL.ai Ташкили лоиҳа Қадами аввал ин таъсис додани лоиҳаи мо тавассути ворид кардани китобхонаҳои зарурӣ мебошад: import json import numpy as np import pandas as pd import dgl from dgl.data import DGLDataset from dgl.nn import SAGEConv import torch import torch.nn as nn from torch.nn.functional import binary_cross_entropy_with_logits, relu, dropout from torch.nn.utils import clip_grad_norm_ from torch.optim.lr_scheduler import ReduceLROnPlateau import itertools import scipy.sparse as sp from sklearn.metrics import roc_auc_score Коркарди пешакии маълумот ва тақсимоти тестӣ Барои омода кардани маълумот барои омӯзиш, мо аввал маҷмӯи додаҳои Twitch-ро бор мекунем, онро ҳамчун график муаррифӣ мекунем ва сипас онро ба маҷмӯаҳои омӯзишӣ ва санҷишӣ тақсим мекунем. Мо синфи фармоиширо эҷод мекунем, ки аз мерос мегирад, ки ба сохтори раванди боркунии маълумот ва ба тартиб даровардани амалиёти марбут ба график кӯмак мекунад. DGLDataset : Дар функсияи раванд, мо аз хондани рӯйхати кунҷҳо аз маҷмӯи додаҳо оғоз мекунем. Азбаски кунҷҳои маҷмӯаи маълумоти аслӣ самтнашавандаанд (намояндагии дӯстии мутақобила), мо кунҷҳои баръакс илова мекунем, то боварӣ ҳосил кунем, ки пайвастҳо дар графики мо дуҷониба бошанд. Боркунии маълумотҳои графикӣ : Баъдан, мо хусусиятҳои гиреҳро аз файли JSON бор мекунем. Ҳар як гиреҳ дорои рӯйхати хусусиятҳое мебошад, ки дарозии онҳо метавонанд фарқ кунанд, аз ин рӯ мо рӯйхати хусусиятҳои кӯтоҳтарро бо сифрҳо мегузорем, то дарозии доимиро дар тамоми гиреҳҳо нигоҳ дорем. Боркунии хусусиятҳои гиреҳ Ин аст код барои эҷод ва пеш аз коркарди маҷмӯи додаҳо: # create a dataset that inherits DGLDataset class SocialNetworkDataset(DGLDataset): def __init__(self): super().__init__(name='social_network') def process(self): # load edges edges_df = pd.read_csv('./twitch/ENGB/musae_ENGB_edges.csv') # ensure edges are bidirectional edges_df_rev = edges_df.copy() edges_df_rev.columns = ['to', 'from'] edges_df_rev = edges_df_rev[['from', 'to']] edges_df = pd.concat([edges_df, edges_df_rev], ignore_index=True) edges_df.drop_duplicates(inplace=True) # create a graph using DGL max_node_id = max(edges_df['from'].max(), edges_df['to'].max()) edges_src = torch.from_numpy(edges_df['from'].to_numpy()) edges_dst = torch.from_numpy(edges_df['to'].to_numpy()) self.graph = dgl.graph( (edges_src, edges_dst), num_nodes=max_node_id + 1, ) # load and node features with open('./twitch/ENGB/musae_ENGB_features.json') as f: node_features_dict = json.load(f) # feature lists have various lengths, pad them with zeros max_feature_list_len = max([len(l) for l in node_features_dict.values()]) for k in node_features_dict: if len(node_features_dict[k]) < max_feature_list_len: node_features_dict[k] += [0] * (max_feature_list_len - len(node_features_dict[k])) # set node features in graph node_features_df = pd.DataFrame.from_dict(node_features_dict).T.astype('float64') node_features_np = node_features_df.to_numpy() self.graph.ndata['feat'] = torch.from_numpy(node_features_np).float() def __len__(self): return 1 # only the whole graph is returned def __getitem__(self, idx): return self.graph Ҳоло мо маҷмӯи додаҳои худро барои бор кардани маълумоти графикӣ оғоз мекунем. # init the dataset dataset = SocialNetworkDataset() g = dataset[0] Қадами навбатӣ мебошад. Мо кунҷҳоро ба барои омӯзиш ва озмоиш тақсим мекунем. Мо барои ҳарду маҷмӯа ҳам намунаҳои ва ҳам манфӣ тавлид мекунем. Барои графикҳои калонтар, утилитаҳои DGL метавонанд муфид бошанд, аммо дар ин ҷо тамоми график ба хотира мувофиқат мекунад. Ин аст код барои сохтани маҷмӯаҳои омӯзишӣ ва санҷишӣ: эҷоди маҷмӯаҳои омӯзишӣ ва санҷишӣ таносуби 80/20 мусбат (кунҷҳои мавҷуда) (кунҷҳои мавҷуда) dgl.sampling # pick edges for train and test sets (80/20 split) # (for larger graphs, we can use dgl.sampling.negative etc) u, v = g.edges() edge_ids = np.random.permutation(g.num_edges()) test_set_size = int(len(edge_ids) * 0.2) train_set_size = len(edge_ids) - test_set_size # positive samples: existing edges test_positive_u, test_positive_v = u[edge_ids[:test_set_size]], v[edge_ids[:test_set_size]] train_positive_u, train_positive_v = u[edge_ids[test_set_size:]], v[edge_ids[test_set_size:]] # negative samples: nonexistent edges adj = sp.coo_matrix((np.ones(len(u)), (u.numpy(), v.numpy()))) adj_negative = 1 - adj.todense() - np.eye(g.num_nodes()) negative_u, negative_v = np.where(adj_negative != 0) negative_edge_ids = np.random.choice(len(negative_u), g.num_edges()) test_negative_u, test_negative_v = ( negative_u[negative_edge_ids[:test_set_size]], negative_v[negative_edge_ids[:test_set_size]], ) train_negative_u, train_negative_v = ( negative_u[negative_edge_ids[test_set_size:]], negative_v[negative_edge_ids[test_set_size:]], ) # create a training graph by copying the original graph and removing test edges train_g = dgl.remove_edges(g, edge_ids[:test_set_size]) # define positive and negative graphs for train and test sets train_positive_g = dgl.graph((train_positive_u, train_positive_v), num_nodes=g.num_nodes()) train_negative_g = dgl.graph((train_negative_u, train_negative_v), num_nodes=g.num_nodes()) test_positive_g = dgl.graph((test_positive_u, test_positive_v), num_nodes=g.num_nodes()) test_negative_g = dgl.graph((test_negative_u, test_negative_v), num_nodes=g.num_nodes()) Модели: Layers Convolutional GraphSAGE ва Predictor MLP Мо як шабакаи нейронии конволюционии истифода мебарем, то муаррифии гиреҳҳо, ки бо номи маъруфанд, ҳам сохтор ва ҳам хусусиятҳои ҳар як гиреҳро дар дохили график сабт мекунанд. GraphSAGE бо ҷамъ кардани иттилооти хусусиятҳо аз ҳамсояҳои ҳар як гиреҳ барои эҷоди намояндагии пурмазмун барои ҳар як гиреҳ амал мекунад. Ин раванд, ки бо номи маълум аст, ба модел имкон медиҳад, ки намунаҳои бой ва маҳаллиро дар график омӯзад. График Намуна ва Агрегатсияро (GraphSAGE) embeddings агрегатсияи ҳамсоя Дар ҳар як қабати GraphSAGE, модел барои ҷамъоварии иттилоот аз гиреҳҳои ҳамсоя, ки баъдан бо хусусиятҳои худи гиреҳ муттаҳид карда мешавад татбиқ мекунад. Ҷойгир кардани ба модел имкон медиҳад, ки ва назари ҳар як гиреҳро дар дохили график ба таври муассир васеъ кунад. , функсияи ҷамъкуниро (дар ин ҳолат, функсияи "миёна") қабатҳои сершумори конволютсионӣ маълумотро аз гиреҳҳои торафт дуртар ба даст орад Барои баланд бардоштани самаранокии модел ва кам кардани фишурдани изофа, мо пас аз ҳар як қабат татбиқ мекунем. тарки таркро Акнун биёед модели GraphSAGE-ро бо дар якҷоягӣ бо функсияи созем, то муайян кунад, ки чӣ гуна маълумот тавассути он мегузарад: се қабати конволютсионӣ forward # define the GraphSAGE model with 3 convolutional layers class GraphSAGE(nn.Module): def __init__( self, input_features, hidden_features, output_features, dropout_probability=0.3, ): super(GraphSAGE, self).__init__() self.conv_layer_1 = SAGEConv(input_features, hidden_features, "mean") self.conv_layer_2 = SAGEConv(hidden_features, hidden_features, "mean") self.conv_layer_3 = SAGEConv(hidden_features, output_features, "mean") self.dropout_probability = dropout_probability def forward(self, graph, input_features): # first layer with ReLU activation and dropout h = relu(self.conv_layer_1(graph, input_features)) h = dropout(h, p=self.dropout_probability) # second layer with ReLU activation and dropout h = relu(self.conv_layer_2(graph, h)) h = dropout(h, p=self.dropout_probability) # third layer without dropout h = self.conv_layer_3(graph, h) return h Натиҷаи пас аз қабати сеюм ( ) дохилкунии гиреҳро дар бар мегирад. Барои пешгӯии эҳтимолияти канори (ё пайванд) байни ҳар ду гиреҳ, мо истифода мебарем. Ин ҳисоб мекунад, ки эҳтимолияти мавҷудияти канори байни онҳоро нишон медиҳад. h пешгӯии бисёрқабатаи Персептрон (MLP) -ро MLP ҷойгиркунии ду гиреҳро ҳамчун вуруд мегирад ва холеро # define the MLP predictor class MLPPredictor(nn.Module): def __init__(self, hidden_features): super().__init__() # first linear layer to combine node embeddings self.W1 = nn.Linear(hidden_features * 2, hidden_features) # second linear layer to produce a single score output self.W2 = nn.Linear(hidden_features, 1) def apply_edges(self, edges): # concatenate source and destination node embeddings h = torch.cat([edges.src["h"], edges.dst["h"]], dim=1) # pass through MLP layers to get the edge score score = self.W2(relu(self.W1(h))).squeeze(1) return {'score': score} def forward(self, g, h): with g.local_scope(): g.ndata["h"] = h g.apply_edges(self.apply_edges) return g.edata["score"] чунин кор мекунад: Пешгӯии MLP Андозаи вуруди пешгӯикунанда ба ҷобаҷогузории гиреҳҳои омӯхташуда асос ёфтааст. Азбаски ҳар як канор ду гиреҳро мепайвандад, , ки дар натиҷа андозаи вуруди hidden_features * 2 мешавад. Андозаи вуруд: мо ҷойгиркунии онҳоро (ҳар як андозаи hidden_features) муттаҳид мекунем Ин қабат дохилкуниҳои муттаҳидшударо коркард мекунад ва ва иттилооти муҳими муносибатӣ байни гиреҳҳоро нигоҳ медорад. Қабати 1 (W1): андозаи баромадро дубора ба hidden_features коҳиш медиҳад Ин қабати ниҳоӣ барои ҳар як ҷуфт гиреҳҳо як тавлид мекунад, ки байни онҳоро ифода мекунад. Қабати 2 (W2): холҳои скалярӣ эҳтимолияти мавҷудияти канори Ин равиши қабатӣ ба пешгӯӣ имкон медиҳад, ки муносибатҳои мураккаби байни ҷуфтҳои гиреҳҳоро ба даст оранд ва холҳои канориро ҳисоб кунанд, ки онро ҳамчун эҳтимолияти мавҷудияти канор шарҳ додан мумкин аст. Функсияи талафот ва AUC Барои самаранок омӯзонидани модели мо, ба мо функсияи талафот лозим аст, ки метавонад . Азбаски ин вазифа як аст - дар он ҷо ҳар як пайванд вуҷуд дорад ё вуҷуд надорад - мо ҳамчун функсияи талафоти худ истифода мебарем истифода мебарем. Кросс-энтропияи бинарӣ ихтилофи байни холҳои пешбинишудаи модел ва тамғакоғазҳои воқеиро чен мекунад (1 барои истиноди мавҷуда, 0 барои бе пайванд). Мо версияи ро истифода мебарем, зеро модели мо ба ҷои эҳтимолият холҳои хом (логитҳо) медиҳад. Ин версияи BCE ҳангоми кор бо логитҳо устувортар аст, зеро он функсияи сигмоид ва кросс-энтропияро дар як қадам муттаҳид мекунад. иҷрои моделро дар пешгӯии истинод муайян кунад масъалаи таснифоти дуӣ , кросс-энтропияи бинариро (BCE) _with_logits Ин аст коде, ки талафотро ҳисоб мекунад: def compute_loss(positive_logits, negative_logits): # concatenate positive and negative scores y_predicted = torch.cat([positive_logits, negative_logits]) # create true labels (1 for existing links, 0 for nonexistent) y_true = torch.cat([torch.ones(positive_logits.shape[0]), torch.zeros(negative_logits.shape[0])]) return binary_cross_entropy_with_logits(y_predicted, y_true) Барои арзёбии модел, мо метрикаи истифода мебарем. AUC барои пешгӯии истинод хеле мувофиқ аст, зеро он , дар он ҷо намунаҳои манфӣ (кунҷҳои мавҷуда) нисбат ба намунаҳои мусбӣ бештар маъмуланд. Холи AUC ба мо ҳис мекунад, ки то чӣ андоза модел истинодҳои мавҷударо нисбат ба истинодҳои мавҷуда болотар мегузорад. майдони зери каҷи ROC (AUC) -ро маълумоти нобаробарро самаранок коркард мекунад Ин аст код барои ҳисоб кардани AUC: def compute_auc(positive_logits, negative_logits): y_predicted = torch.cat([positive_logits, negative_logits]).detach().numpy() y_true = torch.cat([torch.ones(positive_logits.shape[0]), torch.zeros(negative_logits.shape[0])]).detach().numpy() return roc_auc_score(y_true, y_predicted) Эзоҳ: Мо барои хориҷ кардани тензорҳо аз графики ҳисобкунӣ истифода мебарем, ки ба мо имкон медиҳад, ки AUC-ро бидуни таъсир ба градиентҳо ҳисоб кунем. detach() Омӯзиши модел Ҳоло мо омодаем моделро омӯзем. Барои оғоз кардан, мо . Мо инчунин дар байни дигар гиперпараметрҳо суръати омӯзиш, андозаи қабати пинҳонӣ ва суръати тарки таркро муайян хоҳем кард. Дар ҳоле, ки , , агар платоҳои талафот коҳиш ёбад, яъне он барои шумораи муайяни давраҳо коҳиш меёбад (дар ин ҳолат, 25). Банақшагир суръати омӯзишро ду маротиба коҳиш медиҳад, ки ин метавонад ба модели самараноктар муттаҳид шавад. модел, пешгӯӣ ва оптимизаторро эҷод мекунем ва ҳалқаи омӯзишро муайян мекунем мо оптимизатсияи гиперпараметрро дар ин ҷо фаро намегирем мо як ҷадвалбандии суръати омӯзишро барои танзими суръати омӯзиш истифода мебарем Ин аст код барои оғоз кардани модел ва танзими омӯзиш: # init the model num_hidden_features = 32 model = GraphSAGE( train_g.ndata['feat'].shape[1], num_hidden_features, num_hidden_features, ) predictor = MLPPredictor(num_hidden_features) # create an optimizer and a learning rate scheduler learning_rate = 0.01 optimizer = torch.optim.Adam( itertools.chain(model.parameters(), predictor.parameters()), lr=learning_rate, ) lr_scheduler = ReduceLROnPlateau(optimizer, mode='min', factor=0.5, patience=25) # train the model num_epochs = 1000 for epoch in range(num_epochs + 1): # forward h = model(train_g, train_g.ndata['feat']) positive_logits = predictor(train_positive_g, h) negative_logits = predictor(train_negative_g, h) loss = compute_loss(positive_logits, negative_logits) # backward optimizer.zero_grad() loss.backward() # clip gradients clip_grad_norm_(model.parameters(), 1.0) optimizer.step() # adjust learning rate based on the loss lr_scheduler.step(loss) # print loss, current learning rate, and AUC if epoch % 100 == 0: last_lr = lr_scheduler.get_last_lr()[0] train_auc = compute_auc(positive_logits, negative_logits) print(f'Epoch: {epoch}, learning rate: {last_lr}, loss: {loss}, AUC: {train_auc}') Биёед кодро иҷро кунем ва натиҷаро тафтиш кунем: Epoch: 0, learning rate: 0.01, loss: 262.4156188964844, AUC: 0.4934097124994463 Epoch: 100, learning rate: 0.01, loss: 0.5642552375793457, AUC: 0.7473735298706314 Epoch: 200, learning rate: 0.01, loss: 0.4622882306575775, AUC: 0.8431058751115716 Epoch: 300, learning rate: 0.01, loss: 0.40566185116767883, AUC: 0.8777374138645864 Epoch: 400, learning rate: 0.01, loss: 0.38118976354599, AUC: 0.8944719038039551 Epoch: 500, learning rate: 0.01, loss: 0.3690297603607178, AUC: 0.9039401673234729 Epoch: 600, learning rate: 0.005, loss: 0.3579995930194855, AUC: 0.9112366798940639 Epoch: 700, learning rate: 0.005, loss: 0.3557407557964325, AUC: 0.9128097572016495 Epoch: 800, learning rate: 0.005, loss: 0.3510144352912903, AUC: 0.9152937255697913 Epoch: 900, learning rate: 0.00125, loss: 0.3425179123878479, AUC: 0.9202487786553115 Epoch: 1000, learning rate: 0.00015625, loss: 0.3432360589504242, AUC: 0.9198250134354529 Тавре ки мо мебинем, модел ба . Аҳамият диҳед, ки суръати омӯзиш дар байни давраҳои 500 ва 600 ҳангоми мӯътадил шудани талафот коҳиш меёбад. Ин тасҳеҳ имкон медиҳад, ки дурусттар танзим карда шавад, ки боиси кам шудани талафот мегардад. Пас аз як нуқтаи муайян, талафот ва AUC мӯътадил мешаванд, ки ин нишон медиҳад, ки модел шудааст. AUC тақрибан 0,92 мерасад, ки ин нишондиҳандаи қавии пешгӯишаванда мебошад муттаҳид Биёед (ки ҳангоми омӯзиш истифода нашуда буд) ва бубинем, ки оё он хуб ҷамъбаст шудааст: моделро аз рӯи маълумоти санҷишӣ арзёбӣ кунем # evaluate the model on the test data with torch.no_grad(): test_positive_scores = predictor(test_positive_g, h) test_negative_scores = predictor(test_negative_g, h) test_loss = compute_loss(test_positive_scores, test_negative_scores) test_auc = compute_auc(test_positive_scores, test_negative_scores) print(f'Test loss: {test_loss}, Test AUC: {test_auc}') Натиҷа ин аст: Test loss: 0.675215482711792, Test AUC: 0.866213400711374 . Танзими минбаъдаи гиперпараметрҳо метавонад умумиятро беҳтар созад, хусусан агар аз ҳад зиёд мувофиқат кардан боиси ташвиш бошад. AUC-и санҷишӣ нисбат ба AUC-и омӯзишӣ каме пасттар аст, ки аз ҳад зиёд фишурдани ночизро нишон медиҳад. Аммо, AUC аз 0.866 нишон медиҳад, ки модел ҳоло ҳам дар маълумоти ноаён хуб кор мекунад Истифодаи модели омӯзонидашуда барои пешгӯии пайвандҳои нав Бо модели омӯзонидаи худ, . Мо тавлид мекунем, ки ба мо имкон медиҳад, ки пайвастҳои эҳтимолии навро муайян кунем. мо ҳоло метавонем эҳтимолияти пайвандҳо байни гиреҳҳои графикиро пешгӯӣ кунем барои ҳамаи ҷуфтҳои имконпазири гиреҳ пешгӯиҳо : Мо аввал ҳама ҷуфтҳои имконпазири гиреҳҳоро тавлид мекунем, ба истиснои ҳалқаҳои худ (пайвастшавӣ аз гиреҳ ба худ). Ин ба мо ҷуфтҳои гиреҳи номзадҳоро медиҳад, ки мо мехоҳем эҳтимолияти пайвандро пешгӯӣ кунем. Эҷоди ҷуфтҳои гиреҳи номзад Мо баъдан бо ин кунҷҳои номзад графи DGL эҷод мекунем ва моделро бо ҷобаҷогузории гиреҳ аз графики аслӣ истифода мебарем. Ин ҷобаҷогузорӣ, ки дар атрибути графики номзад нигоҳ дошта мешаванд, ҳамчун саҳм барои пешгӯии пайванд хидмат хоҳанд кард. Эҷоди графикаи номзад: ndata['h'] Ин аст рамзи ин қадамҳо: # build node pairs, avoid self-loops (with_replacement=False) node_pairs = torch.combinations(torch.arange(g.num_nodes()), r=2, with_replacement=False) candidate_u = node_pairs[:, 0] candidate_v = node_pairs[:, 1] # build a graph with all node pairs candidate_graph = dgl.graph((candidate_u, candidate_v)) candidate_graph_node_embeddings = model(g, g.ndata['feat']) # we use embeddings from the original graph candidate_graph.ndata['h'] = candidate_graph_node_embeddings # use the predictor to predict the existence of links between nodes predicted_scores = predictor(candidate_graph, candidate_graph_node_embeddings) Ҳоло, ки . Масалан, биёед хол ва эҳтимолияти алоқаи байни гиреҳҳои 1773 ва 7005-ро, ки бевосита дар маҷмӯи маълумоти ибтидоӣ пайваст нестанд, тафтиш кунем: мо барои ҳамаи ҷуфтҳои номзадҳо пешгӯиҳо дорем, мо метавонем эҳтимолияти пайвандро байни ҳама гиреҳҳои мушаххас тафтиш кунем # find the index of the node pair (1773, 7005) pair_index = torch.where((candidate_u == 1773) & (candidate_v == 7005))[0] print(f'Pair index: {pair_index}') # get the logit score for this pair and compute probability of link existence pair_link_score = predicted_scores[pair_index].item() # logit score print(f'Pair link score: {pair_link_score}') link_probability = torch.sigmoid(torch.tensor(pair_link_score)).item() # apply sigmoid to convert score into probability print(f'Link probability: {link_probability * 100}%') Ин аст натиҷа: Pair index: tensor([11066978]) Pair link score: 0.7675977945327759 Link probability: 68.30010414123535% Мувофиқи модели мо, вуҷуд дорад. эҳтимолияти пайванди байни корбари 1773 ва 7005 68,3% Хулоса Дар ин паём, , ки истифодаи Шабакаҳои Neural Graph ва DGL-ро барои пешгӯии истинод нишон медиҳад. Аммо, вақте ки графикҳо то миллионҳо ё миллиардҳо гиреҳҳо ва кунҷҳо миқёс доранд, коркарди онҳо ҳалли пешрафтаро талаб мекунад, ба монанди омӯзиши тақсимшуда дар кластерҳои GPU. мо бомуваффақият моделеро барои пешгӯии истинодҳои нав дар графики иҷтимоӣ сохтем Истифодаи маҷмӯи маълумоти нисбатан хурд ба мо имкон дод, ки дар мошини маҳаллӣ самаранок кор кунем. Ҳамчун қадами навбатӣ, мо равишҳои коркарди графикҳои калонҳаҷм ва татбиқи пешгӯии пайвандро дар муҳити абрӣ меомӯзем, ки ба шумо имкон медиҳад, ки ин усулҳоро ба маҷмӯи додаҳои сатҳи истеҳсолот татбиқ кунед.