使用机器学习或深度学习在两个节点之间进行链接概率预测,其中给出了节点到节点的映射

Des*_*wal 2 machine-learning scikit-learn deep-learning keras tensorflow

有人可以请我指导一个教程,为下面给出的问题提供一个初步的想法。

我有一个作者到共同作者的映射,如下所示:

mapping
>>
{0: [2860, 3117],
 1: [318, 1610, 1776, 1865, 2283, 2507, 3076, 3108, 3182, 3357, 3675, 4040],
 2: [164, 413, 1448, 1650, 3119, 3238],
} # this is just sample


link_attributes.iloc[:5,:7]
>>

first   id  keyword_0   keyword_10  keyword_13  keyword_15  keyword_2
0        4      0        1.0             1.0    1.0         1.0
1        9      1        1.0             1.0    1.0         1.0
2        7      2        1.0             NaN    1.0         1.0
3        6      3        1.0             1.0    NaN         1.0
4        9      4        1.0             1.0    1.0         1.0

Run Code Online (Sandbox Code Playgroud)

我必须预测在 aSourceSink

例如,如果给我一个Source=13 和Sink=31,那么我必须找到在 13 和 31 之间有链接的概率。所有链接都是无向的。

TaQ*_*gTu 5

import json
import numpy
from keras import Sequential
from keras.layers import Dense

def get_keys(data, keys):  # get all keys from json file
    if isinstance(data, list):
        for item in data:
            get_keys(item, keys)
    if isinstance(data, dict):
        sub_keys = data.keys()
        for sub_key in sub_keys:
            keys.append(sub_key)

# get all keys, each key is a feature of instances
json_data = open("nodes.json")  # read 4016 instances
jdata = json.load(json_data)
keys = []
get_keys(jdata, keys)
keys = set(keys)
print(set(keys))

def build_instance(json_object):  # use to build instance from json object, ex: instance = [f0,f1,f2,f3,....f404]
    features = []
    features.append(json_object.get('id'))
    for key in keys:
        value = json_object.get(key)
        if value is None:
            value = 0
        elif key == 'id':
            continue
        features.append(value)
    return features

# read all instances and format them, each instance will be [f0,f1, f2,...], as i read from json file, each instance will have 405 features
instances = []
num_of_instances = 0
for item in jdata:
    features = build_instance(item)
    instances.append(features)
    num_of_instances = num_of_instances + 1
    print(num_of_instances)

# read "author_id - co author ids" file
traintxt = open('train.txt', 'r')
lines = traintxt.readlines()

au_vs_co_auth_list = []
for line in lines:
    line = line.split('\t', 200)
    print(line)
    # convert value from string to int
    string = line[0]  # example line[0] = '14 445'
    id_vs_coauthor = string.split(" ", 200)
    id = id_vs_coauthor[0]
    co_author = id_vs_coauthor[1]

    line[0:1] = [int(id), int(co_author)]
    for i in range(2, len(line)):
        line[i] = int(line[i])
    au_vs_co_auth_list.append(line)

print(len(au_vs_co_auth_list))  # we have 4016 authors

X_train = []
Y_train = []
generated_train_pairs = []
train_num = 30000  # choose 30000 random training instances
for i in range(train_num):
    print(i)
    index1 = numpy.random.randint(0, len(au_vs_co_auth_list), 1)[0]
    co_authors_of_index1 = au_vs_co_auth_list[index1]
    author_id_of_index_1 = au_vs_co_auth_list[index1][0]

    if index1 % 2 == 0:  # try to create a sample that two author is not related
        index2 = numpy.random.randint(0, len(au_vs_co_auth_list), 1)[0]
        author_id_of_index_2 = au_vs_co_auth_list[index2][0]

        # make sure id1 != id2 and auth 1 and auth2 are not related
        while (index1 == index2) or (author_id_of_index_2 in co_authors_of_index1):
            index2 = numpy.random.randint(0, len(au_vs_co_auth_list), 1)[0]
            author_id_of_index_2 = au_vs_co_auth_list[index2][0]
        y = [0, 1]  # [relative=FALSE,non-related = TRUE]
    else:  # try to create a sample that two author is related
        author_id_of_index_2 = numpy.random.randint(1, len(co_authors_of_index1),size=1)[0]
        y = [1, 0]  # [relative=TRUE,non-related = FALSE]

    x = instances[author_id_of_index_1][1:] + instances[author_id_of_index_2][
                                              1:]  # x = [feature1, feature2,...feature404',feature1', feature2',...feature404']
    X_train.append(x)
    Y_train.append(y)
X_train = numpy.asarray(X_train)
Y_train = numpy.asarray(Y_train)
print(X_train.shape)
print(Y_train.shape)

# now we have x_train, y_train, build model right now
model = Sequential()
model.add(Dense(512, input_shape=X_train[0].shape, activation='relu'))
model.add(Dense(128, activation='relu'))
model.add(Dense(32, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(2, activation='sigmoid'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X_train, Y_train, batch_size=512, epochs=3, verbose=2)
model.save("model.h5")
# now to predict probability of linking between two author ids

id1 = 11  # just random
id2 = 732  # just random

author1 = None
author2 = None
for item in jdata:
    if item.get('id') == id1:
        author1 = build_instance(item)
    if item.get('id') == id2:
        author2 = build_instance(item)
    if author1 is not None and author2 is not None:
        break

x_test = author1[1:] + author2[1:]
x_test = numpy.expand_dims(numpy.asarray(x_test), axis=0)
probability = model.predict(x_test)

print("author id ", id1, " and author id ", id2, end=" ")
if probability[0][1] > probability[0][0]:
    print("Not related")
else:
    print("Related")
print(probability)
Run Code Online (Sandbox Code Playgroud)

输出:

author id  11  and author id  732 related
Run Code Online (Sandbox Code Playgroud)