<jupyter_start><jupyter_text>Reading Rating Dataset<jupyter_code>rating_dataset = pd.read_csv("Electronics.csv")
rating_dataset.columns = ["item", "user", "rating", "timestamp"]
rating_dataset.head()
# total number of items
len(set(rating_dataset.item))
# total number of users
len(set(rating_dataset.user))
# total number of connections
rating_dataset.shape
rating_dataset['rating'].plot.hist()

a = rating_dataset[['user', 'item']].groupby(['user'])['item'].count()
a.hist(bins=[10, 20, 30, 50, 100, 200, 300, 400, 500, 600], log=True)
b = rating_dataset[['user', 'item']].groupby(['item'])['user'].count()

b.hist(bins=20, log=True)
b.describe()<jupyter_output><empty_output><jupyter_text>Reading Metadata<jupyter_code>### load the meta data

metadata = []
with gzip.open('meta_Electronics.json.gz') as f:
    for l in f:
        metadata.append(json.loads(l.strip()))
    
# total length of list, this number equals total number of products
print(len(metadata))

# first row of the list
print(metadata[0])<jupyter_output><empty_output><jupyter_text>Reading Review Dataset! wget http://deepyeti.ucsd.edu/jianmo/amazon/categoryFiles/Electronics.json.gz<jupyter_code>dict_item_meta = {meta['asin']: meta for meta in metadata}
dict_item_meta['0060009810']<jupyter_output><empty_output><jupyter_text>Feature Engineering<jupyter_code>rating_dataset.shape
rating_dataset.dropna(inplace = True)
print(rating_dataset.shape)
len(dict_item_meta)
### Remove item that does not exist in metadata
items_with_metadata = set(rating_dataset.item).intersection(set(dict_item_meta.keys()))
rating_dataset = rating_dataset[rating_dataset.item.isin(items_with_metadata)]
rating_dataset.shape
print("edges, users, items ={} {} {}".format(rating_dataset.shape[0], len(set(rating_dataset.item)), len(set(rating_dataset.user))))
df_user_item = rating_dataset.loc[rating_dataset.rating >= 3]
edges = df_user_item
edges.head()
print("edges, users, items ={} {} {}".format(df_user_item.shape[0], len(set(df_user_item.item)), len(set(df_user_item.user))))
len(set(df_user_item.item))
x = df_user_item.groupby(['user'])['item'].count() >= 20
users = list(x[x == True].index)
print(len(users))

# Keep users having more than 20 item
df_user_item = df_user_item.loc[df_user_item['user'].isin(users)]
print("edges, items, users ={} {} {}".format(df_user_item.shape[0], len(set(df_user_item.item)), len(set(df_user_item.user))))
## Reduce users
users = users[0:5000]

# Keep users having more than 20 item
df_user_item = df_user_item.loc[df_user_item['user'].isin(users)]
df_user_item.shape
print("edges, items, users ={} {} {}".format(df_user_item.shape[0], len(set(df_user_item.item)), len(set(df_user_item.user))))
edge = df_user_item<jupyter_output><empty_output><jupyter_text>Produce all rating file for these subset of users and items<jupyter_code>df_rating_dataset_for_users = rating_dataset.loc[rating_dataset['user'].isin(set(df_user_item.user))]
df_rating_dataset_for_user_items = df_rating_dataset_for_users.loc[df_rating_dataset_for_users['item'].isin(set(df_user_item.item))]
print("edges, items, users ={} {} {}".format(df_rating_dataset_for_user_items.shape[0], len(set(df_rating_dataset_for_user_items.item)), len(set(df_rating_dataset_for_user_items.user))))
# df_rating_dataset_for_user_items[["item", "user", "rating"]].to_csv("/Users/msinghal/SourceCodes/Personal/LightGCN/Data/amazon-electronics-v3/user-item-rating.csv", index=False)<jupyter_output><empty_output><jupyter_text>Creating integer id for users and items to reduce memory footprint<jupyter_code>user_id_map = {}
item_id_map = {}
users = list(set(df_user_item.user))
items = list(set(df_user_item.item))
user_id_map = {users[index]:index for index in range(0, len(users))}
item_id_map = {items[index]:index for index in range(0, len(items))}
df_user_item['user_id'] = df_user_item['user'].apply(lambda x:user_id_map[x])
df_user_item['item_id'] = df_user_item['item'].apply(lambda x:item_id_map[x])
train_df, test_df = train_test_split(df_user_item, test_size=0.32)
print("train edges {}".format(train_df.shape))
print("test edges {}".format(test_df.shape))
print("users in training data  {}".format(len(set(train_df.user))))
print("users in test data {}".format(len(set(test_df.user))))
print("items in training data  {}".format(len(set(train_df.item))))
print("items in test data {}".format(len(set(test_df.item))))<jupyter_output><empty_output><jupyter_text>Combining metadata with edge rating  Create users, items and training and testing dataset<jupyter_code># df_user_item_list = pd.DataFrame(columns = ['user', 'items'])
# for i in set(df_user_item['user']):
#     items = " ".join(list(df_user_item.loc[df_user_item['user'] == i]['item']))
#     df_user_item_list = df_user_item_list.append({'user':i, 'items':items}, ignore_index = True)

df_user_item_list_train = pd.DataFrame(columns = ['user', 'items'])
for i in set(train_df['user']):
    items = " ".join(list(train_df.loc[train_df['user'] == i]['item']))
    df_user_item_list_train = df_user_item_list_train.append({'user':i, 'items':items}, ignore_index = True)

df_user_item_list_test = pd.DataFrame(columns = ['user', 'items'])
for i in set(test_df['user']):
    items = " ".join(list(test_df.loc[test_df['user'] == i]['item']))
    df_user_item_list_test = df_user_item_list_test.append({'user':i, 'items':items}, ignore_index = True)

df_user_item_list_train['user_id'] = df_user_item_list_train['user'].apply(lambda x:user_id_map[x])
df_user_item_list_train['item_ids'] = df_user_item_list_train['items'].apply(lambda x:" ".join([str(item_id_map[item]) for item in x.split(" ")]))
df_user_item_list_test['user_id'] = df_user_item_list_test['user'].apply(lambda x:user_id_map[x])
df_user_item_list_test['item_ids'] = df_user_item_list_test['items'].apply(lambda x:" ".join([str(item_id_map[item]) for item in x.split(" ")]))
df_user_item_list_train.shape<jupyter_output><empty_output><jupyter_text>Exporting data<jupyter_code>df_user_item_list_test.shape

# with open("/Users/msinghal/SourceCodes/Personal/LightGCN/Data/amazon-electronics-v3/train.txt", 'w') as f:
#     lines = [str(row['user_id']) + " " + row['item_ids'] for index, row in df_user_item_list_train.iterrows()]
#     f.writelines("\n".join(lines))

# with open("/Users/msinghal/SourceCodes/Personal/LightGCN/Data/amazon-electronics-v3/test.txt", 'w') as f:
#     lines = [str(row['user_id']) + " " + row['item_ids'] for index, row in df_user_item_list_test.iterrows()]
#     f.writelines("\n".join(lines))

# with open("/Users/msinghal/SourceCodes/Personal/LightGCN/Data/amazon-electronics-v3/user_list.txt", 'w') as f:
#     lines = [str(user) + " " + str(user_id) for user, user_id in user_id_map.items()]
#     f.writelines("\n".join(lines))
categories = set()
for item, item_id in item_id_map.items():
    categories = categories | set(dict_item_meta[item]['category'])
categories = list(set(categories))
categories = list(set(categories))
dict_item_meta[item]
len(categories)
# with open("/Users/msinghal/SourceCodes/Personal/LightGCN/Data/amazon-electronics-v3/categories.txt", 'w') as f:
#     lines = []
#     for i in range(0, len(categories)):
#         lines.append(str(i) + "|" + categories[i])
#     f.writelines("\n".join(lines))
# with open("/Users/msinghal/SourceCodes/Personal/LightGCN/Data/amazon-electronics-v3/item_meta_list.txt", 'w') as f:
#     lines = []
#     for item, item_id in item_id_map.items():
#         x = str(item) + " " + str(item_id)  
#         y = ""
#         for category in categories:
#             y = y + " " + '1' if category in dict_item_meta[item]['category'] else y + " " + '0'
#         lines.append(x + y)
#     f.writelines("\n".join(lines))<jupyter_output><empty_output><jupyter_text>Done   Model Analaysis and Model Training  graphsage model<jupyter_code>keys = list(set(df_user_item['user']) | set(df_user_item['item']))
nodes_features = [[0 for i in range(0, len(keys))] for j in range(0, len(keys))]
for i in range(0,len(keys)):
    nodes_features[i][i] = 1

import networkx as nx
def generate_nx_graph_port_as_node_features(rating_dataset, node_features):
    G = nx.Graph()
    # Add nodes
    for i in range (0, len(keys)):
        feature = node_features[i]
        if keys[i] in users:
            G.add_node(keys[i], feature=feature, label="u")
        else:
            G.add_node(keys[i], feature=feature, label="i")
    for index, row in rating_dataset.iterrows():
        src_node_id = row['user']
        dst_node_id = row['item']
        G.add_edge(src_node_id, dst_node_id, rating=row['rating'])
    return G
g = generate_nx_graph_port_as_node_features(df_user_item, nodes_features)
from stellargraph import StellarGraph
G = StellarGraph.from_networkx(g, node_features="feature")<jupyter_output><empty_output><jupyter_text>Graphsage<jupyter_code>nodes = G.nodes()
gsWalks = 20
gsWalkLength = 20
batch_size = 50
epochs = 1
num_samples = [5, 5]

G.nodes()
unsupervised_samples = UnsupervisedSampler(
    G, nodes=nodes, length=gsWalkLength, number_of_walks=gsWalks
)
??UnsupervisedSampler
# nodes = G.nodes()
# gsWalks = 10
# gsWalkLength = 5
# batch_size = 20
# epochs = 1
# num_samples = [20,20]
# layer_sizes = [50,50]

# unsupervised_samples = UnsupervisedSampler(
#     G, nodes=nodes, length=gsWalkLength, number_of_walks=gsWalks
# )
# generator = HinSAGELinkGenerator(G, batch_size, num_samples, head_node_types=('u','i'))
# train_gen = generator.flow(unsupervised_samples)
# graphsage = HinSAGE(
#     layer_sizes=layer_sizes, generator=generator, bias=True, dropout=0.0, normalize="l2"
# )
# x_inp, x_out = graphsage.in_out_tensors()
# prediction = link_classification(
#     output_dim=1, output_act="sigmoid", edge_embedding_method="ip"
# )(x_out)
# model = keras.Model(inputs=x_inp, outputs=prediction)
# model.compile(
#     optimizer=keras.optimizers.Adam(lr=1e-3),
#     loss=keras.losses.binary_crossentropy,
#     metrics=[keras.metrics.binary_accuracy],
# )

# history = model.fit(
#     train_gen,
#     epochs=epochs,
#     verbose=1,
#     use_multiprocessing=False,
#     workers=4,
#     shuffle=True,
# )


from stellargraph.mapper import GraphSAGENodeGenerator, HinSAGENodeGenerator
??GraphSAGENodeGenerator
def get_embeddings(G, nodes):
    x_inp_src = x_inp[0::2]
    x_out_src = x_out[0]
    embedding_model = keras.Model(inputs=x_inp_src, outputs=x_out_src)
    node_ids = nodes
    #node_gen = HinSAGENodeGenerator(G, batch_size, num_samples).flow(node_ids)

    node_embeddings = model.predict(test_gen, workers=4, verbose=1)
    
    return node_embeddings
new_embeddings = get_embeddings(G, G.nodes())
from sklearn.metrics.pairwise import cosine_similarity
latest_node_embeddings = pd.DataFrame(data=new_embeddings, index=nodes)
df_latest_similarity_matrix = create_similarity_matrix(latest_node_embeddings)
df_latest_similarity_matrix.head()
df_latest_similarity_matrix.loc[users, users]<jupyter_output><empty_output><jupyter_text>HinSage  on Amazon Dataset<jupyter_code>import json
import pandas as pd
import numpy as np
from sklearn import preprocessing, feature_extraction, model_selection
from sklearn.metrics import mean_absolute_error, mean_squared_error

import stellargraph as sg
from stellargraph.mapper import HinSAGELinkGenerator
from stellargraph.layer import HinSAGE, link_regression
from tensorflow.keras import Model, optimizers, losses, metrics

import multiprocessing
from stellargraph import datasets
from stellargraph import StellarGraph
from IPython.display import display, HTML
import matplotlib.pyplot as plt
import numpy as np
import networkx as nx
from stellargraph import datasets
class Amz_Dataset():
    def load(self, metadata=False):
        """
        Load this dataset into an undirected heterogeneous graph, downloading it if required.

        The graph has two types of nodes (``user`` and ``movie``) and one type of edge (``rating``).

        The dataset includes some node features on both users and movies: on users, they consist of
        categorical features (``gender`` and ``job``) which are one-hot encoded into binary
        features, and an ``age`` feature that is scaled to have mean = 0 and standard deviation = 1.

        Returns:
            A tuple where the first element is a :class:`.StellarGraph` instance containing the graph
            data and features, and the second element is a pandas DataFrame of edges, with columns
            ``user_id``, ``movie_id`` and ``rating`` (a label from 1 to 5).
        """
        rating_file = "/Users/msinghal/SourceCodes/Personal/LightGCN/Data/amazon-electronics-v2/user-item-rating.csv"
        user_file = "/Users/msinghal/SourceCodes/Personal/LightGCN/Data/amazon-electronics-v2/user_list.txt"
        item_file = "/Users/msinghal/SourceCodes/Personal/LightGCN/Data/amazon-electronics-v2/item_meta_list.txt"
        category_file = "/Users/msinghal/SourceCodes/Personal/LightGCN/Data/amazon-electronics-v2/categories.txt"

        edges = pd.read_csv(rating_file)

        users = pd.read_csv(
            user_file,
            sep=" ",
            header=None,
            names=["user", "user_id"]
        )

        categories = pd.read_csv(
            category_file,
            sep="|",
            header=None,
            names=["category_id", "category"]
        )

        items = pd.read_csv(
            item_file,
            sep=" ",
            header=None,
            names=["item", "item_id"] + list(categories["category"])
        )

        # manage the IDs
        def u(users):
            return "u_" + users.astype(str)

        def m(movies):
            return "i_" + movies.astype(str)

        edges = edges.merge(users, on="user").merge(items, on="item")[["user_id", "item_id", "rating"]]

        users["user_id"] = u(users["user_id"])
        users.set_index("user_id", inplace=True)

        #
        items["item_id"] = m(items["item_id"])
        items.set_index("item_id", inplace=True)
        items.drop("item", inplace=True, axis=1)
        #
        edges["user_id"] = u(edges["user_id"])
        edges["item_id"] = m(edges["item_id"])

        # convert categorical user features to numeric, and normalize age
        # feature_encoding = preprocessing.OneHotEncoder(sparse=False)
        # onehot = feature_encoding.fit_transform(users[["user"]])
        # scaled_age = preprocessing.scale(users["age"])
        values = np.zeros((len(users.index), len(users.index)))
        np.fill_diagonal(values, 1)
        encoded_users = pd.DataFrame(values, index=users.index, columns=users.index)
        if not metadata:
            values = np.zeros((len(items.index), len(items.index)))
            np.fill_diagonal(values, 1)
            encoded_items = pd.DataFrame(values, index=items.index, columns=items.index)
            return self.generate_nx_graph_with_features(edges, encoded_users, encoded_items), edges
        return self.generate_nx_graph_with_features(edges, encoded_users, items), edges

    def generate_nx_graph_with_features(self, edges, users, items):
        G = nx.Graph()
        # Add nodes
        for user_id in users.index:
            G.add_node(user_id, feature=users.loc[user_id, :], label="user")
        for item_id in items.index:
            G.add_node(item_id, feature=items.loc[item_id, :], label="item")

        for index, row in edges.iterrows():
            src_node_id = row['user_id']
            dst_node_id = row['item_id']
            G.add_edge(src_node_id, dst_node_id, rating=row['rating'])
        return StellarGraph.from_networkx(G, node_features="feature")

dataset = Amz_Dataset()
G, edges_with_ratings = dataset.load(metadata=True)

G.nodes()
edges_with_ratings.shape

from sklearn import model_selection
edges_train, edges_test = model_selection.train_test_split(
    edges_with_ratings, train_size=0.7, test_size=0.3
)
edgelist_train = list(edges_train[["user_id", "item_id"]].itertuples(index=False))
edgelist_test = list(edges_test[["user_id", "item_id"]].itertuples(index=False))

labels_train = edges_train["rating"]
labels_test = edges_test["rating"]
print(edges_train.shape)
print(edges_test.shape)
batch_size = 200
epochs = 20
num_samples = [8, 4]
generator = HinSAGELinkGenerator(
    G, batch_size, num_samples, head_node_types=["user", "item"]
)
train_gen = generator.flow(edgelist_train, labels_train, shuffle=True)
test_gen = generator.flow(edgelist_test, labels_test)
generator.schema.type_adjacency_list(generator.head_node_types, len(num_samples))
generator.schema.schema
hinsage_layer_sizes = [32, 32]
assert len(hinsage_layer_sizes) == len(num_samples)

hinsage = HinSAGE(
    layer_sizes=hinsage_layer_sizes, generator=generator, bias=True, dropout=0.0
)
len(num_samples)
# Expose input and output sockets of hinsage:
x_inp, x_out = hinsage.in_out_tensors()
# Final estimator layer
score_prediction = link_regression(edge_embedding_method="concat")(x_out)
import tensorflow.keras.backend as K


def root_mean_square_error(s_true, s_pred):
    return K.sqrt(K.mean(K.pow(s_true - s_pred, 2)))


model = Model(inputs=x_inp, outputs=score_prediction)
model.compile(
    optimizer=optimizers.Adam(lr=1e-2),
    loss=losses.mean_squared_error,
    metrics=[root_mean_square_error, metrics.mae],
)
model.summary()
# Specify the number of workers to use for model training
num_workers = 4
model.metrics_names
generator = HinSAGELinkGenerator(
    G, batch_size, num_samples, head_node_types=["user", "item"]
)
train_gen = generator.flow(edgelist_train, labels_train, shuffle=True)
test_gen = generator.flow(edgelist_test, labels_test)
from stellargraph.mapper import GraphSAGENodeGenerator, HinSAGENodeGenerator
def get_embeddings(G, nodes):
    x_inp_src = x_inp[0::2]
    x_out_src = x_out[0]
    embedding_model = keras.Model(inputs=x_inp_src, outputs=x_out_src)
    node_ids = nodes
    #egd = HinSAGENodeGenerator(G, batch_size, num_samples, head_node_types=["user", "item"]).flow(node_ids)

    node_embeddings = model.predict(test_gen, workers=4, verbose=1)
    
    return node_embeddings
new_embeddings = get_embeddings(G, G.nodes())
test_metrics = model.evaluate(
    test_gen, verbose=1, use_multiprocessing=False, workers=num_workers
)

print("Untrained model's Test Evaluation:")
for name, val in zip(model.metrics_names, test_metrics):
    print("\t{}: {:0.4f}".format(name, val))
history = model.fit(
    train_gen,
    validation_data=test_gen,
    epochs=epochs,
    verbose=1,
    shuffle=False,
    use_multiprocessing=False,
    workers=num_workers,
)
test_metrics = model.evaluate(
    test_gen, use_multiprocessing=False, workers=num_workers, verbose=1
)

print("Test Evaluation:")
for name, val in zip(model.metrics_names, test_metrics):
    print("\t{}: {:0.4f}".format(name, val))
y_true = labels_test
# Predict the rankings using the model:
y_pred = model.predict(test_gen)
# Mean baseline rankings = mean movie ranking:
y_pred_baseline = np.full_like(y_pred, np.mean(y_true))

rmse = np.sqrt(mean_squared_error(y_true, y_pred_baseline))
mae = mean_absolute_error(y_true, y_pred_baseline)
print("Mean Baseline Test set metrics:")
print("\troot_mean_square_error = ", rmse)
print("\tmean_absolute_error = ", mae)

rmse = np.sqrt(mean_squared_error(y_true, y_pred))
mae = mean_absolute_error(y_true, y_pred)
print("\nModel Test set metrics:")
print("\troot_mean_square_error = ", rmse)
print("\tmean_absolute_error = ", mae)
h_true = plt.hist(y_true, bins=30, facecolor="green", alpha=0.5)
h_pred = plt.hist(y_pred, bins=30, facecolor="blue", alpha=0.5)
plt.xlabel("ranking")
plt.ylabel("count")
plt.legend(("True", "Predicted"))
plt.show()
y_pred.shape<jupyter_output><empty_output><jupyter_text>With Metadata "category"<jupyter_code>dataset = Amz_Dataset()
G, edges_with_ratings = dataset.load(metadata=True)


from sklearn import model_selection
edges_train, edges_test = model_selection.train_test_split(
    edges_with_ratings, train_size=0.7, test_size=0.3
)


edgelist_train = list(edges_train[["user_id", "item_id"]].itertuples(index=False))
edgelist_test = list(edges_test[["user_id", "item_id"]].itertuples(index=False))

labels_train = edges_train["rating"]
labels_test = edges_test["rating"]

batch_size = 200
epochs = 20

num_samples = [8, 4]

generator = HinSAGELinkGenerator(
    G, batch_size, num_samples, head_node_types=["user", "item"]
)
train_gen = generator.flow(edgelist_train, labels_train, shuffle=True)
test_gen = generator.flow(edgelist_test, labels_test)
generator.schema.type_adjacency_list(generator.head_node_types, len(num_samples))


hinsage_layer_sizes = [32, 32]
assert len(hinsage_layer_sizes) == len(num_samples)

hinsage = HinSAGE(
    layer_sizes=hinsage_layer_sizes, generator=generator, bias=True, dropout=0.0
)


# Expose input and output sockets of hinsage:
x_inp, x_out = hinsage.in_out_tensors()


# Final estimator layer
score_prediction = link_regression(edge_embedding_method="concat")(x_out)


import tensorflow.keras.backend as K


def root_mean_square_error(s_true, s_pred):
    return K.sqrt(K.mean(K.pow(s_true - s_pred, 2)))


model = Model(inputs=x_inp, outputs=score_prediction)
model.compile(
    optimizer=optimizers.Adam(lr=1e-2),
    loss=losses.mean_squared_error,
    metrics=[root_mean_square_error, metrics.mae],
)

# Specify the number of workers to use for model training
num_workers = 4


generator = HinSAGELinkGenerator(
    G, batch_size, num_samples, head_node_types=["user", "item"]
)
train_gen = generator.flow(edgelist_train, labels_train, shuffle=True)
test_gen = generator.flow(edgelist_test, labels_test)

from stellargraph.mapper import GraphSAGENodeGenerator, HinSAGENodeGenerator


def get_embeddings(G, nodes):
    x_inp_src = x_inp[0::2]
    x_out_src = x_out[0]
    embedding_model = keras.Model(inputs=x_inp_src, outputs=x_out_src)
    node_ids = nodes
    # egd = HinSAGENodeGenerator(G, batch_size, num_samples, head_node_types=["user", "item"]).flow(node_ids)

    node_embeddings = model.predict(test_gen, workers=4, verbose=1)

    return node_embeddings


new_embeddings = get_embeddings(G, G.nodes())


test_metrics = model.evaluate(
    test_gen, verbose=1, use_multiprocessing=False, workers=num_workers
)

print("Untrained model's Test Evaluation:")
for name, val in zip(model.metrics_names, test_metrics):
    print("\t{}: {:0.4f}".format(name, val))



history = model.fit(
    train_gen,
    validation_data=test_gen,
    epochs=epochs,
    verbose=1,
    shuffle=False,
    use_multiprocessing=False,
    workers=num_workers,
)



test_metrics = model.evaluate(
    test_gen, use_multiprocessing=False, workers=num_workers, verbose=1
)

print("Test Evaluation:")
for name, val in zip(model.metrics_names, test_metrics):
    print("\t{}: {:0.4f}".format(name, val))

y_true = labels_test
# Predict the rankings using the model:
y_pred = model.predict(test_gen)
# Mean baseline rankings = mean movie ranking:
y_pred_baseline = np.full_like(y_pred, np.mean(y_true))

rmse = np.sqrt(mean_squared_error(y_true, y_pred_baseline))
mae = mean_absolute_error(y_true, y_pred_baseline)
print("Mean Baseline Test set metrics:")
print("\troot_mean_square_error = ", rmse)
print("\tmean_absolute_error = ", mae)

rmse = np.sqrt(mean_squared_error(y_true, y_pred))
mae = mean_absolute_error(y_true, y_pred)
print("\nModel Test set metrics:")
print("\troot_mean_square_error = ", rmse)
print("\tmean_absolute_error = ", mae)
dataset = Amz_Dataset()
G, edges_with_ratings = dataset.load(metadata=False)


from sklearn import model_selection
edges_train, edges_test = model_selection.train_test_split(
    edges_with_ratings, train_size=0.7, test_size=0.3
)


edgelist_train = list(edges_train[["user_id", "item_id"]].itertuples(index=False))
edgelist_test = list(edges_test[["user_id", "item_id"]].itertuples(index=False))

labels_train = edges_train["rating"]
labels_test = edges_test["rating"]

batch_size = 200
epochs = 20

num_samples = [8, 4]

generator = HinSAGELinkGenerator(
    G, batch_size, num_samples, head_node_types=["user", "item"]
)
train_gen = generator.flow(edgelist_train, labels_train, shuffle=True)
test_gen = generator.flow(edgelist_test, labels_test)
generator.schema.type_adjacency_list(generator.head_node_types, len(num_samples))


hinsage_layer_sizes = [32, 32]
assert len(hinsage_layer_sizes) == len(num_samples)

hinsage = HinSAGE(
    layer_sizes=hinsage_layer_sizes, generator=generator, bias=True, dropout=0.0
)


# Expose input and output sockets of hinsage:
x_inp, x_out = hinsage.in_out_tensors()


# Final estimator layer
score_prediction = link_regression(edge_embedding_method="concat")(x_out)


import tensorflow.keras.backend as K


def root_mean_square_error(s_true, s_pred):
    return K.sqrt(K.mean(K.pow(s_true - s_pred, 2)))


model = Model(inputs=x_inp, outputs=score_prediction)
model.compile(
    optimizer=optimizers.Adam(lr=1e-2),
    loss=losses.mean_squared_error,
    metrics=[root_mean_square_error, metrics.mae],
)

# Specify the number of workers to use for model training
num_workers = 4


generator = HinSAGELinkGenerator(
    G, batch_size, num_samples, head_node_types=["user", "item"]
)
train_gen = generator.flow(edgelist_train, labels_train, shuffle=True)
test_gen = generator.flow(edgelist_test, labels_test)

from stellargraph.mapper import GraphSAGENodeGenerator, HinSAGENodeGenerator


def get_embeddings(G, nodes):
    x_inp_src = x_inp[0::2]
    x_out_src = x_out[0]
    embedding_model = keras.Model(inputs=x_inp_src, outputs=x_out_src)
    node_ids = nodes
    # egd = HinSAGENodeGenerator(G, batch_size, num_samples, head_node_types=["user", "item"]).flow(node_ids)

    node_embeddings = model.predict(test_gen, workers=4, verbose=1)

    return node_embeddings


new_embeddings = get_embeddings(G, G.nodes())


test_metrics = model.evaluate(
    test_gen, verbose=1, use_multiprocessing=False, workers=num_workers
)

print("Untrained model's Test Evaluation:")
for name, val in zip(model.metrics_names, test_metrics):
    print("\t{}: {:0.4f}".format(name, val))



history = model.fit(
    train_gen,
    validation_data=test_gen,
    epochs=epochs,
    verbose=1,
    shuffle=False,
    use_multiprocessing=False,
    workers=num_workers,
)



test_metrics = model.evaluate(
    test_gen, use_multiprocessing=False, workers=num_workers, verbose=1
)

print("Test Evaluation:")
for name, val in zip(model.metrics_names, test_metrics):
    print("\t{}: {:0.4f}".format(name, val))

y_true = labels_test
# Predict the rankings using the model:
y_pred = model.predict(test_gen)
# Mean baseline rankings = mean movie ranking:
y_pred_baseline = np.full_like(y_pred, np.mean(y_true))

rmse = np.sqrt(mean_squared_error(y_true, y_pred_baseline))
mae = mean_absolute_error(y_true, y_pred_baseline)
print("Mean Baseline Test set metrics:")
print("\troot_mean_square_error = ", rmse)
print("\tmean_absolute_error = ", mae)

rmse = np.sqrt(mean_squared_error(y_true, y_pred))
mae = mean_absolute_error(y_true, y_pred)
print("\nModel Test set metrics:")
print("\troot_mean_square_error = ", rmse)
print("\tmean_absolute_error = ", mae)<jupyter_output><empty_output><jupyter_text>Normalization or laplacian of adjcency matrix<jupyter_code>A = nx.to_numpy_matrix(g)
import numpy as np
A_mode = A + np.eye(g.number_of_nodes())
D_mode = np.zeros_like(A_mode)
A_mode.shape

np.asarray(A_mode.sum(axis=1)).flatten()
np.fill_diagonal(D_mode, np.asarray(A_mode.sum(axis=1)).flatten())
D_mode
from scipy.linalg import sqrtm
from numpy.linalg import inv

D_mod_inv_root = inv(sqrtm(D_mode))
grpah_matrix = D_mod_inv_root @ A_mode @ D_mod_inv_root
a = np.array([[1, 0],
              [0, 1]])
b = np.array([[5, 0],
              [1, 1]])
a * b
a @ b
D_mod_inv_root[].sum()
grpah_matrix
def isDiag(M):
    i, j = np.nonzero(M)
    return np.all(i == j)
isDiag(D_mod_inv_root)
isDiag(A_mode)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13287015371323663, 'fraction_numerical': 0.008639619856726304, 'mean_word_length': 5.392084675563737, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '13', 'dir': 'jupyter-structured-clean-dedup', 'id': '213754', 'license': 'MIT', 'n_tokens_mistral': 10152, 'n_tokens_neox': 9852, 'n_words': 1808, 'path': 'notebook/Dataset_preparation.ipynb', 'repo_name': 'madansinghal/graphranko', 'size': '27779'}