{"nbformat":4,"nbformat_minor":0,"metadata":{"colab":{"name":"2022-01-23-hers.ipynb","provenance":[{"file_id":"https://github.com/recohut/nbs/blob/main/raw/T229879%20%7C%20HERS%20Cold-start%20Recommendations%20on%20LastFM%20dataset.ipynb","timestamp":1644663073840}],"collapsed_sections":[],"authorship_tag":"ABX9TyNKM79xlwT5GDZoyK65u8Xw"},"kernelspec":{"name":"python3","display_name":"Python 3"},"language_info":{"name":"python"}},"cells":[{"cell_type":"markdown","metadata":{"id":"uazyzsOz3cvK"},"source":["# HERS Cold-start Recommendations on LastFM dataset\n","\n","> Modeling Influential Contexts with Heterogeneous Relations for Sparse and Cold-Start Recommendation."]},{"cell_type":"markdown","metadata":{"id":"f91qUW98GVIi"},"source":["HERS consists of three heterogeneous relations: user-user, item-item, and user-item. Each user’s choice is relevant to the corresponding user’s and item’s influential contexts."]},{"cell_type":"markdown","metadata":{"id":"YH6hSPByyc9J"},"source":["![](https://github.com/recohut/coldstart-recsys/raw/da72950ca514faee94f010a2cb6e99a373044ec1/docs/_images/T229879_1.png)"]},{"cell_type":"markdown","metadata":{"id":"wx2zMNhRGLND"},"source":["### Model Architecture"]},{"cell_type":"markdown","metadata":{"id":"qByNsRigGTDG"},"source":["The architecture of HERS for modeling user-item interaction with user’s and item’s influential contexts."]},{"cell_type":"markdown","metadata":{"id":"WHmX_cCgygwp"},"source":["![](https://github.com/recohut/coldstart-recsys/raw/da72950ca514faee94f010a2cb6e99a373044ec1/docs/_images/T229879_2.png)"]},{"cell_type":"markdown","metadata":{"id":"Dt4u_t3qGav9"},"source":["Influential-Context Aggregation Unit (ICAU): A two-stage aggregation model to construct ICE."]},{"cell_type":"markdown","metadata":{"id":"RBySJCXQyjt2"},"source":["![](https://github.com/recohut/coldstart-recsys/raw/da72950ca514faee94f010a2cb6e99a373044ec1/docs/_images/T229879_3.png)"]},{"cell_type":"markdown","metadata":{"id":"V4GXZQBdGEhZ"},"source":["## CLI Run"]},{"cell_type":"code","metadata":{"id":"O5TFa17hynTk"},"source":["!pip install fastFM==0.2.9"],"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"0peCFDE_215A","executionInfo":{"status":"ok","timestamp":1635692303792,"user_tz":-330,"elapsed":1742,"user":{"displayName":"Sparsh Agarwal","photoUrl":"https://lh3.googleusercontent.com/a/default-user=s64","userId":"13037694610922482904"}},"outputId":"eca4468e-e757-451a-e489-c862538eca07"},"source":["%tensorflow_version 1.x"],"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["TensorFlow 1.x selected.\n"]}]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"nOi-m36_yTaO","executionInfo":{"status":"ok","timestamp":1635691954353,"user_tz":-330,"elapsed":8921,"user":{"displayName":"Sparsh Agarwal","photoUrl":"https://lh3.googleusercontent.com/a/default-user=s64","userId":"13037694610922482904"}},"outputId":"1b1a7fa8-273f-46d2-e8db-10d089002223"},"source":["!apt-get -qq install tree"],"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["Selecting previously unselected package tree.\n","(Reading database ... 155062 files and directories currently installed.)\n","Preparing to unpack .../tree_1.7.0-5_amd64.deb ...\n","Unpacking tree (1.7.0-5) ...\n","Setting up tree (1.7.0-5) ...\n","Processing triggers for man-db (2.8.3-2ubuntu0.1) ...\n"]}]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"VEGCLgXxyZ1q","executionInfo":{"status":"ok","timestamp":1635691957026,"user_tz":-330,"elapsed":2684,"user":{"displayName":"Sparsh Agarwal","photoUrl":"https://lh3.googleusercontent.com/a/default-user=s64","userId":"13037694610922482904"}},"outputId":"fee4e6b0-4059-4c2c-b5a5-8c8b73305aff"},"source":["!git clone https://github.com/rainmilk/aaai19hers.git"],"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["Cloning into 'aaai19hers'...\n","remote: Enumerating objects: 70, done.\u001b[K\n","remote: Counting objects: 100% (13/13), done.\u001b[K\n","remote: Compressing objects: 100% (10/10), done.\u001b[K\n","remote: Total 70 (delta 3), reused 9 (delta 3), pack-reused 57\u001b[K\n","Unpacking objects: 100% (70/70), done.\n"]}]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"HJ3vn2Rhyxb7","executionInfo":{"status":"ok","timestamp":1635692305929,"user_tz":-330,"elapsed":7,"user":{"displayName":"Sparsh Agarwal","photoUrl":"https://lh3.googleusercontent.com/a/default-user=s64","userId":"13037694610922482904"}},"outputId":"a57301a7-09db-453e-9f32-16ed0f334b22"},"source":["%cd aaai19hers"],"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["/content/aaai19hers\n"]}]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"WW_bdf-s1n9l","executionInfo":{"status":"ok","timestamp":1635691970090,"user_tz":-330,"elapsed":604,"user":{"displayName":"Sparsh Agarwal","photoUrl":"https://lh3.googleusercontent.com/a/default-user=s64","userId":"13037694610922482904"}},"outputId":"c06d2ab4-884d-4301-afcd-b7e579c05753"},"source":["!tree --du -h -C ."],"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["\u001b[01;34m.\u001b[00m\n","├── [ 40M] \u001b[01;34mdatasets\u001b[00m\n","│   ├── [ 23M] \u001b[01;34mbook\u001b[00m\n","│   │   ├── [7.6M] book_itemNet.txt\n","│   │   ├── [1.2M] book_rating_test_cold_item_neg.txt\n","│   │   ├── [1.3M] book_rating_test_cold_item.txt\n","│   │   ├── [573K] book_rating_test_cold_user_neg.txt\n","│   │   ├── [490K] book_rating_test_cold_user.txt\n","│   │   ├── [1014K] book_rating_test.txt\n","│   │   ├── [757K] book_rating_train_cold_item_reverse.txt\n","│   │   ├── [757K] book_rating_train_cold_item.txt\n","│   │   ├── [4.5M] book_rating_train_cold_user.txt\n","│   │   ├── [4.0M] book_rating_train.txt\n","│   │   ├── [1022K] book_rating.txt\n","│   │   └── [134K] book_userNet.txt\n","│   └── [ 17M] \u001b[01;34mlastfm\u001b[00m\n","│   ├── [1.2M] lastfm_itemNet.txt\n","│   ├── [2.3M] lastfm_rating_test_cold_item_neg.txt\n","│   ├── [2.9M] lastfm_rating_test_cold_item.txt\n","│   ├── [792K] lastfm_rating_test_cold_user_neg.txt\n","│   ├── [864K] lastfm_rating_test_cold_user.txt\n","│   ├── [844K] lastfm_rating_test.txt\n","│   ├── [230K] lastfm_rating_train_cold_item_reverse.txt\n","│   ├── [230K] lastfm_rating_train_cold_item.txt\n","│   ├── [3.3M] lastfm_rating_train_cold_user.txt\n","│   ├── [3.3M] lastfm_rating_train.txt\n","│   ├── [749K] lastfm_rating.txt\n","│   └── [219K] lastfm_userNet.txt\n","├── [ 18K] \u001b[01;34mevaluation\u001b[00m\n","│   ├── [ 0] __init__.py\n","│   ├── [3.9K] test_FM.py\n","│   └── [9.9K] test_hers.py\n","├── [ 79K] \u001b[01;34mmodel\u001b[00m\n","│   ├── [ 25K] attentionlayer.py\n","│   ├── [8.3K] batch_generator_np.py\n","│   ├── [10.0K] construct_RS_train.py\n","│   ├── [ 626] data_utilities.py\n","│   ├── [1.4K] graph_utilities.py\n","│   ├── [ 0] __init__.py\n","│   ├── [ 515] losses.py\n","│   ├── [ 905] masklayers.py\n","│   ├── [1.5K] mlmr.py\n","│   ├── [2.7K] ranking.py\n","│   ├── [4.1K] RSbatch.py\n","│   ├── [2.5K] scorer.py\n","│   ├── [2.6K] socialRC.py\n","│   ├── [8.3K] srs_model.py\n","│   └── [6.2K] timedistributed.py\n","└── [ 119] README.md\n","\n"," 40M used in 5 directories, 43 files\n"]}]},{"cell_type":"code","metadata":{"id":"LBV41lkB10Mw"},"source":["import sys\n","sys.path.insert(0,'.')"],"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"TTZRdXwGyccq","outputId":"b6c2bd7a-34e0-4407-df40-5267cf07e997"},"source":["from model.graph_utilities import read_graph\n","from model.losses import infinite_margin_loss, max_margin_loss\n","from keras.regularizers import l2\n","from model.srs_model import NetworkRS\n","import numpy as np\n","import math\n","from model.RSbatch import ItemGenerator,TripletGenerator\n","from sklearn.utils import shuffle\n","from model.socialRC import test_recommendation\n","from model.mlmr import mlmf\n","from model.scorer import nn_scoremodel, inner_prod_scoremodel, fm_scoremodel\n","\n","\n","data_name='lastfm'\n","user_net_path='datasets/%s/%s_userNet.txt'%(data_name,data_name)\n","ui_net_path ='datasets/%s/%s_rating.txt'%(data_name,data_name)\n","item_path = 'datasets/%s/%s_itemNet.txt'%(data_name,data_name)\n","#\n","# train_path = \"networkRS/%s_rating_train.txt\"%data_name\n","# test_path = \"networkRS/%s_rating_test.txt\"%data_name\n","# neg_test_path = \"networkRS/%s_rating_test_neg.csv\"%data_name\n","\n","# item_rep_path = \"networkRS/%s_item_rep_user.txt\"%data_name\n","# user_rep_path = \"networkRS/%s_user_rep_user.txt\"%data_name\n","\n","neg_test_path= \"datasets/%s/%s_rating_test_cold_user_neg.txt\"%(data_name,data_name)\n","train_path = \"datasets/%s/%s_rating_train_cold_user.txt\"%(data_name,data_name)\n","test_path = \"datasets/%s/%s_rating_test_cold_user.txt\"%(data_name,data_name)\n","\n","item_rep_path = \"datasets/%s/%s_item_rep_user_cold.txt\"%(data_name,data_name)\n","user_rep_path = \"datasets/%s/%s_user_rep_user_cold.txt\"%(data_name,data_name)\n","\n","#\n","# neg_test_path= \"networkRS/%s_rating_test_cold_item_neg.txt\"%data_name\n","# train_path = \"networkRS/%s_rating_train_cold_item.txt\"%data_name\n","# test_path = \"networkRS/%s_rating_test_cold_item.txt\"%data_name\n","#\n","# item_rep_path = \"networkRS/%s_item_rep_item_cold.txt\"%data_name\n","# user_rep_path = \"networkRS/%s_user_rep_item_cold.txt\"%data_name\n","\n","\n","def get_user_rep(model, nx_G, embed_len, user_rep_path, batch_size=100, save=False):\n"," node_size = nx_G.number_of_nodes()\n"," memory_output = np.zeros((node_size + 1, embed_len))\n","\n"," node_list = list(nx_G.nodes())\n"," num_node=len(node_list)\n"," nb_batch = math.ceil(len(node_list) / batch_size)\n"," for j in range(nb_batch):\n"," batch_node = node_list[j * batch_size:min(num_node, (j + 1) * batch_size)]\n"," first_batch_data, second_batch_data = batchGenerator.get_batch_data_topk(batch_node=batch_node, topK=topK)\n"," memory_out = model.user_model.predict_on_batch([np.array(batch_node), first_batch_data, second_batch_data])\n"," memory_output[batch_node, :] = memory_out\n","\n"," if save:\n"," np.savetxt(user_rep_path, memory_output[1:])\n"," print(\"save memory successfully\")\n","\n"," return memory_output[1:]\n","\n","def get_cold_start_user_rep(model, embed_len, test_users, batch_size=100):\n"," memory_output = np.zeros((user_size + 1, embed_len))\n","\n"," node_list = test_users\n"," num_node=len(node_list)\n"," nb_batch = math.ceil(len(node_list) / batch_size)\n"," for j in range(nb_batch):\n"," batch_node = node_list[j * batch_size:min(num_node, (j + 1) * batch_size)]\n"," first_batch_data, second_batch_data = batchGenerator.get_batch_data_topk(batch_node=batch_node, topK=topK)\n"," memory_out = model.first_model.predict_on_batch([np.array(batch_node), first_batch_data, second_batch_data])\n"," memory_output[batch_node, :] = np.squeeze(memory_out, axis=1)\n","\n"," return memory_output[1:]\n","\n","\n","def get_item_rep(model, G_item, embed_len, item_rep_path, batch_size=100, save=False):\n"," node_list = list(G_item.nodes())\n"," node_size = len(node_list)\n"," memory_output = np.zeros((node_size + 1, embed_len))\n"," nb_batch = math.ceil(len(node_list) / batch_size)\n","\n"," for j in range(nb_batch):\n"," batch_node = node_list[j * batch_size:min(node_size, (j + 1) * batch_size)]\n"," first_batch_data, _ = batchGenerator.itemGenerate.get_batch_data_topk(batch_node=batch_node, topK=topK, predict_batch_size=100, order=1)\n","\n"," memory_out = model.item_model.predict_on_batch([np.array(batch_node), first_batch_data])\n"," memory_output[batch_node, :] = memory_out\n","\n"," # embedding_nodeset = embedding_matrix[node_set]\n"," # np.savetxt(config.embedding_path, embedding_matrix[1:])\n"," # np.savetxt(config.memory_path, memory_output)\n"," if save:\n"," np.savetxt(item_rep_path, memory_output[1:])\n"," print(\"save item representation successfully\")\n","\n"," return memory_output[1:]\n","\n","def model_testembed_zero(model, test_path):\n"," test_data=np.loadtxt(test_path,dtype=np.int32)\n"," test_user_list=list(set(test_data[:,0]))\n"," user_embed = model.user_emb.get_weights()[0]\n"," user_embed[test_user_list] = 0\n"," model.user_embed.set_weights(user_embed)\n","\n","test_data=np.loadtxt(test_path,dtype=np.int32)\n","test_user_list = list(set(test_data[:,0]))\n","\n","G_user=read_graph(user_net_path)\n","G_item=read_graph(item_path)\n","G_ui= np.loadtxt(train_path, dtype=np.int32)\n","\n","\n","\n","directed=False\n","user_list=list(G_user.nodes())\n","item_list=list(G_item.nodes())\n","\n","user_size=len(user_list)\n","item_size = len(item_list)\n","edges = G_ui\n","num_edges = len(edges)\n","\n","\n","\n","embed_len=128\n","topK=10\n","fliter_theta=16\n","aggre_theta=64\n","batch_size = 400\n","samples = 3\n","margin=20\n","iter_without_att = 5\n","iter_with_att = 25\n","max_iter = iter_without_att + iter_with_att\n","batch_num = math.ceil(num_edges / batch_size)\n","\n","loss = max_margin_loss\n","\n","# score_model = nn_scoremodel((embed_len,), embed_len, score_act=None)\n","score_model = inner_prod_scoremodel((embed_len,), score_rep_norm=False)\n","# score_model = fm_scoremodel((embed_len,), score_rep_norm=False, score_act=None)\n","\n","pretrain_model=mlmf(nb_user=user_size+1, nb_item=item_size+1, embed_dim=embed_len,\n"," score_model=score_model, reg=l2(1e-7))\n","pretrain_model.contrast_model.compile(loss=loss, optimizer='adam')\n","pretrain_model.contrast_model.summary()\n","\n","pretrain_samples = 3\n","pretrain_batch_sz = 200\n","pretrain_batch_num = math.ceil(num_edges / pretrain_batch_sz)\n","pretrain_iter = 3\n","\n","for i in range(pretrain_iter):\n"," shuffle(edges)\n"," train_loss = 0\n"," # print(\"Running on iteration %d/%d:\"%(i, max_iter))\n"," for s in range(pretrain_samples):\n"," for j in range(pretrain_batch_num):\n"," edge_batch = np.array(edges[j * pretrain_batch_sz:min(num_edges, (j + 1) * pretrain_batch_sz)])\n"," batch_node_array, positive_batch_array, negative_batch_array = \\\n"," (edge_batch[:,0], edge_batch[:,1], np.random.randint(low=1,high=item_size,size=len(edge_batch)))\n"," train_loss_temp = pretrain_model.contrast_model.train_on_batch(\n"," x=[batch_node_array, positive_batch_array, negative_batch_array,], y=margin * np.ones([len(edge_batch)]))\n"," train_loss += train_loss_temp\n","\n"," print(\"Training on sample %d and iter %d\" % (s + 1, i + 1))\n"," print(\"Finish iteration %d/%d with loss: %f\" % (i + 1, pretrain_iter, train_loss / (pretrain_batch_num * pretrain_samples)))\n"," user_rep = pretrain_model.user_emb.get_weights()[0][1:]\n"," item_rep = pretrain_model.item_emb.get_weights()[0][1:]\n"," test_recommendation(user_rep, item_rep, pretrain_model.score_model, test_path, neg_test_path)\n"," #test_recommendation(item_rep, user_rep, test_path, neg_test_path) #for cold start item\n","\n","\n","model = NetworkRS(user_size, item_size, embed_len, score_model,\n"," topK, topK, embed_regularizer=l2(5e-7), directed=directed,\n"," mem_filt_alpha=fliter_theta, mem_agg_alpha=aggre_theta,\n"," user_mask=None)\n","model.triplet_model.compile(loss=loss, optimizer='adam')\n","model.triplet_model.summary()\n","\n","if pretrain_iter > 0:\n"," model.user_embed.set_weights(pretrain_model.user_emb.get_weights())\n"," model.item_embed.set_weights(pretrain_model.item_emb.get_weights())\n","\n","\n","batchGenerator = TripletGenerator(G_user, model, G_ui, G_item)\n","\n","\n","# model.user_embed.set_weights([user_embed])\n","\n","for i in range(max_iter):\n"," edges = shuffle(edges)\n"," train_loss = 0\n"," # print(\"Running on iteration %d/%d:\"%(i, max_iter))\n","\n"," spl = samples if i < iter_without_att else samples\n"," for s in range(spl):\n"," for j in range(batch_num):\n"," edge_batch = edges[j * batch_size:min(num_edges, (j + 1) * batch_size)]\n"," batch_node, positive_batch, negative_batch, \\\n"," first_batch_data, second_batch_data, \\\n"," positive_first_batch, \\\n"," negative_first_batch = \\\n"," batchGenerator.generate_triplet_batch(edge_batch=edge_batch, topK=topK,\n"," attention_sampling=i >= iter_without_att)\n","\n"," batch_node_array = np.asarray(batch_node)\n"," positive_batch_array = np.asarray(positive_batch)\n"," negative_batch_array = np.asarray(negative_batch)\n"," train_loss_temp = model.triplet_model.train_on_batch(\n"," x=[batch_node_array, first_batch_data, second_batch_data,\n"," positive_batch_array, positive_first_batch,\n"," negative_batch_array, negative_first_batch],\n"," y=margin * np.ones((len(batch_node),)))\n"," train_loss += train_loss_temp\n","\n"," if (j + 1) % 100 == 0:\n"," print(\"Training on batch %d/%d sample %d and iter %d on dataset %s\" % (j + 1, batch_num, s + 1, i + 1, data_name))\n"," print(\"Finish iteration %d/%d with loss: %f\" % (i + 1, max_iter, train_loss / (batch_num * spl)))\n","\n"," batchGenerator.clear_node_cache()\n","\n"," saveMem = (i + 1) % 5 == 0 or i == max_iter - 1\n"," item_rep= get_item_rep(model, G_item, embed_len, item_rep_path, batch_size=batch_size, save=saveMem)\n","\n"," # user_rep = get_cold_start_user_rep(model, embed_len, test_user_list, batch_size=batch_size)\n"," # test_recommendation(user_rep, item_rep, test_path, neg_test_path)\n","\n"," user_rep = get_user_rep(model, G_user, embed_len, user_rep_path, batch_size=batch_size, save=saveMem)\n"," test_recommendation(user_rep, item_rep, model.score_model, test_path, neg_test_path)\n"," #test_recommendation(item_rep, user_rep, test_path, neg_test_path) # for cold start item\n","\n","#\n","# from model.construct_RS_train import get_attention_graph_RS\n","# att_graph_path=\"./%s_att_graph.csv\"%data_name\n","# edge=[41,2589]\n","# get_attention_graph_RS(model, G_user, G_item, edge, topK, att_graph_path, order=2)\n","\n","# model_save_path=\"./%s_model.h5\"%data_name\n","# model.triplet_model.save(model_save_path)\n","# print(\"save triplet model successfully\")"],"execution_count":null,"outputs":[{"output_type":"stream","name":"stderr","text":["Using TensorFlow backend.\n"]},{"output_type":"stream","name":"stdout","text":["WARNING:tensorflow:From /tensorflow-1.15.2/python3.7/tensorflow_core/python/ops/resource_variable_ops.py:1630: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.\n","Instructions for updating:\n","If using Keras pass *_constraint arguments to layers.\n","Model: \"contrastive_model\"\n","__________________________________________________________________________________________________\n","Layer (type) Output Shape Param # Connected to \n","==================================================================================================\n","user_input (InputLayer) (None, 1) 0 \n","__________________________________________________________________________________________________\n","pos_item_input (InputLayer) (None, 1) 0 \n","__________________________________________________________________________________________________\n","neg_item_input (InputLayer) (None, 1) 0 \n","__________________________________________________________________________________________________\n","user_embedding (Embedding) (None, 1, 128) 242304 user_input[0][0] \n","__________________________________________________________________________________________________\n","item_embedding (Embedding) (None, 1, 128) 1581952 pos_item_input[0][0] \n"," neg_item_input[0][0] \n","__________________________________________________________________________________________________\n","lambda_1 (Lambda) (None, 128) 0 user_embedding[0][0] \n"," item_embedding[0][0] \n"," item_embedding[1][0] \n","__________________________________________________________________________________________________\n","score_model (Model) (None, 1) 0 lambda_1[0][0] \n"," lambda_1[1][0] \n"," lambda_1[0][0] \n"," lambda_1[2][0] \n","__________________________________________________________________________________________________\n","contrastive_score (Concatenate) (None, 2) 0 score_model[1][0] \n"," score_model[2][0] \n","==================================================================================================\n","Total params: 1,824,256\n","Trainable params: 1,824,256\n","Non-trainable params: 0\n","__________________________________________________________________________________________________\n","WARNING:tensorflow:From /tensorflow-1.15.2/python3.7/tensorflow_core/python/ops/math_grad.py:1424: where (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.\n","Instructions for updating:\n","Use tf.where in 2.0, which has the same broadcast rule as np.where\n","WARNING:tensorflow:From /tensorflow-1.15.2/python3.7/keras/backend/tensorflow_backend.py:422: The name tf.global_variables is deprecated. Please use tf.compat.v1.global_variables instead.\n","\n","Training on sample 1 and iter 1\n","Training on sample 2 and iter 1\n","Training on sample 3 and iter 1\n","Finish iteration 1/3 with loss: 18.241182\n","the MAP at\n","[0.10525066 0.0872151 0.07567542 0.068401 0.06283624 0.05824598\n"," 0.05463924 0.05170926 0.0496745 0.04895933]\n","the mean recall at \n","[0.0182748 0.03368914 0.04729032 0.06166572 0.0743528 0.08638901\n"," 0.0984089 0.10993599 0.12167688 0.13167849]\n","the mean ndcg at\n","[0.15023066 0.14890209 0.14392312 0.14235024 0.13911982 0.13628249\n"," 0.13438462 0.13275857 0.132171 0.13357852]\n","Training on sample 1 and iter 2\n","Training on sample 2 and iter 2\n","Training on sample 3 and iter 2\n","Finish iteration 2/3 with loss: 8.765345\n","the MAP at\n","[0.08685136 0.07197921 0.0628175 0.0567766 0.0524198 0.04882929\n"," 0.04610379 0.043686 0.04215434 0.04212455]\n","the mean recall at \n","[0.0168401 0.03020062 0.0425496 0.05502262 0.06809384 0.07972486\n"," 0.09124271 0.10185474 0.1125887 0.12428723]\n","the mean ndcg at\n","[0.12904449 0.12753073 0.12488705 0.12343631 0.12321759 0.12169319\n"," 0.12068633 0.1194807 0.11922531 0.12245477]\n","Training on sample 1 and iter 3\n","Training on sample 2 and iter 3\n","Training on sample 3 and iter 3\n","Finish iteration 3/3 with loss: 5.985732\n","the MAP at\n","[0.08126649 0.0675802 0.0598328 0.0548443 0.05030018 0.04711405\n"," 0.04437393 0.04241969 0.04094197 0.04086823]\n","the mean recall at \n","[0.01551918 0.02886323 0.0416366 0.05463804 0.06596641 0.07809979\n"," 0.08893671 0.10060455 0.11160765 0.12215893]\n","the mean ndcg at\n","[0.11808492 0.12025033 0.12024766 0.12048602 0.11854225 0.11812849\n"," 0.11669326 0.11661063 0.11676213 0.11934721]\n","Model: \"triplet_model\"\n","__________________________________________________________________________________________________\n","Layer (type) Output Shape Param # Connected to \n","==================================================================================================\n","target_input (InputLayer) (None, 1) 0 \n","__________________________________________________________________________________________________\n","target_first_input (InputLayer) (None, 10) 0 \n","__________________________________________________________________________________________________\n","target_second_input (InputLayer (None, 10, 10) 0 \n","__________________________________________________________________________________________________\n","positive_input (InputLayer) (None, 1) 0 \n","__________________________________________________________________________________________________\n","positive_first_input (InputLaye (None, 10) 0 \n","__________________________________________________________________________________________________\n","negative_input (InputLayer) (None, 1) 0 \n","__________________________________________________________________________________________________\n","negative_first_input (InputLaye (None, 10) 0 \n","__________________________________________________________________________________________________\n","user_model (Model) (None, 128) 291972 target_input[0][0] \n"," target_first_input[0][0] \n"," target_second_input[0][0] \n","__________________________________________________________________________________________________\n","item_model (Model) (None, 128) 1606786 positive_input[0][0] \n"," positive_first_input[0][0] \n"," negative_input[0][0] \n"," negative_first_input[0][0] \n","__________________________________________________________________________________________________\n","score_model (Model) (None, 1) 0 user_model[1][0] \n"," item_model[1][0] \n"," user_model[1][0] \n"," item_model[2][0] \n","__________________________________________________________________________________________________\n","contrastive_score (Concatenate) (None, 2) 0 score_model[3][0] \n"," score_model[4][0] \n","==================================================================================================\n","Total params: 1,898,758\n","Trainable params: 1,898,758\n","Non-trainable params: 0\n","__________________________________________________________________________________________________\n","Training on batch 100/172 sample 1 and iter 1 on dataset lastfm\n","Training on batch 100/172 sample 2 and iter 1 on dataset lastfm\n","Training on batch 100/172 sample 3 and iter 1 on dataset lastfm\n","Finish iteration 1/30 with loss: 5.635064\n","the MAP at\n","[0.22272647 0.18670666 0.16461287 0.15177528 0.1401979 0.12925662\n"," 0.1209762 0.11374372 0.10803256 0.10594346]\n","the mean recall at \n","[0.03084107 0.06147762 0.08677184 0.11261106 0.13533306 0.15546178\n"," 0.17478276 0.19213053 0.2077343 0.22380648]\n","the mean ndcg at\n","[0.297442 0.28639218 0.27565113 0.27016327 0.26246969 0.25434639\n"," 0.24773193 0.24141381 0.23614692 0.23696483]\n","Training on batch 100/172 sample 1 and iter 2 on dataset lastfm\n","Training on batch 100/172 sample 2 and iter 2 on dataset lastfm\n","Training on batch 100/172 sample 3 and iter 2 on dataset lastfm\n","Finish iteration 2/30 with loss: 4.760596\n","the MAP at\n","[0.27255937 0.2214915 0.19454094 0.17665937 0.16201014 0.14929053\n"," 0.13920971 0.13047091 0.12350605 0.12078478]\n","the mean recall at \n","[0.03570137 0.06554486 0.09525043 0.1212082 0.14425527 0.16494801\n"," 0.18483454 0.2039537 0.2208235 0.23820965]\n","the mean ndcg at\n","[0.34373792 0.32286684 0.30855118 0.29816215 0.28769292 0.27742483\n"," 0.26905321 0.26214813 0.25619899 0.25651924]\n","Training on batch 100/172 sample 1 and iter 3 on dataset lastfm\n","Training on batch 100/172 sample 2 and iter 3 on dataset lastfm\n","Training on batch 100/172 sample 3 and iter 3 on dataset lastfm\n","Finish iteration 3/30 with loss: 4.170074\n","the MAP at\n","[0.25850484 0.21837637 0.19161314 0.17420808 0.15983544 0.14886259\n"," 0.13885896 0.13045848 0.12387013 0.12106817]\n","the mean recall at \n","[0.0347768 0.06725711 0.09320374 0.11939323 0.14213045 0.16360747\n"," 0.18313954 0.20073852 0.21866584 0.23455916]\n","the mean ndcg at\n","[0.32949986 0.31400003 0.29867472 0.28971258 0.27982352 0.27166466\n"," 0.26370649 0.25613718 0.25132485 0.25118102]\n","Training on batch 100/172 sample 1 and iter 4 on dataset lastfm\n","Training on batch 100/172 sample 2 and iter 4 on dataset lastfm\n","Training on batch 100/172 sample 3 and iter 4 on dataset lastfm\n","Finish iteration 4/30 with loss: 3.683889\n","the MAP at\n","[0.27147757 0.22222578 0.19223141 0.17430309 0.16066627 0.14936223\n"," 0.14034241 0.1326905 0.12613214 0.12428094]\n","the mean recall at \n","[0.0387941 0.06790382 0.09499372 0.1208624 0.14601645 0.16823789\n"," 0.18969912 0.21026749 0.22825787 0.24726625]\n","the mean ndcg at\n","[0.34616364 0.32171579 0.30627825 0.2958496 0.28811596 0.27976426\n"," 0.2729372 0.26703786 0.26152012 0.26310554]\n","Training on batch 100/172 sample 1 and iter 5 on dataset lastfm\n","Training on batch 100/172 sample 2 and iter 5 on dataset lastfm\n","Training on batch 100/172 sample 3 and iter 5 on dataset lastfm\n","Finish iteration 5/30 with loss: 3.332913\n","save item representation successfully\n","save memory successfully\n","the MAP at\n","[0.23755497 0.200826 0.17411452 0.15809933 0.14601762 0.13604498\n"," 0.12853867 0.12246192 0.1172684 0.11549145]\n","the mean recall at \n","[0.03456201 0.06227569 0.08672343 0.11114177 0.13400808 0.15473667\n"," 0.17558321 0.1956089 0.21396345 0.2317678 ]\n","the mean ndcg at\n","[0.3042486 0.28998448 0.27695444 0.2691055 0.26218003 0.25516614\n"," 0.25017115 0.24607019 0.24236405 0.24389987]\n","Training on batch 100/172 sample 1 and iter 6 on dataset lastfm\n","Training on batch 100/172 sample 2 and iter 6 on dataset lastfm\n","Training on batch 100/172 sample 3 and iter 6 on dataset lastfm\n","Finish iteration 6/30 with loss: 3.017033\n","the MAP at\n","[0.30626209 0.25481352 0.22328453 0.20141359 0.18325239 0.16898384\n"," 0.15620385 0.14655656 0.13887434 0.13569403]\n","the mean recall at \n","[0.04220384 0.07383557 0.10216575 0.12894536 0.15304636 0.17516488\n"," 0.19454146 0.21364018 0.23261608 0.25069024]\n","the mean ndcg at\n","[0.37789034 0.35147161 0.33302959 0.31987234 0.30788797 0.29728847\n"," 0.28683243 0.27880649 0.27319241 0.27346335]\n","Training on batch 100/172 sample 1 and iter 7 on dataset lastfm\n","Training on batch 100/172 sample 2 and iter 7 on dataset lastfm\n","Training on batch 100/172 sample 3 and iter 7 on dataset lastfm\n","Finish iteration 7/30 with loss: 2.761373\n","the MAP at\n","[0.28737907 0.23977164 0.21232614 0.18720858 0.17027161 0.1560692\n"," 0.14477297 0.13582319 0.12833658 0.12551523]\n","the mean recall at \n","[0.0398102 0.07022699 0.09873408 0.12217624 0.14644166 0.16835766\n"," 0.18810265 0.2078854 0.2260577 0.24430567]\n","the mean ndcg at\n","[0.35974147 0.33515181 0.32088719 0.30417715 0.29399527 0.28445681\n"," 0.27549809 0.26888653 0.26327119 0.26377186]\n","Training on batch 100/172 sample 1 and iter 8 on dataset lastfm\n","Training on batch 100/172 sample 2 and iter 8 on dataset lastfm\n","Training on batch 100/172 sample 3 and iter 8 on dataset lastfm\n","Finish iteration 8/30 with loss: 2.519779\n","the MAP at\n","[0.25593668 0.20735572 0.1817019 0.16258274 0.14947434 0.13703792\n"," 0.12728549 0.11946924 0.11303752 0.1107409 ]\n","the mean recall at \n","[0.03362044 0.06378493 0.08879778 0.11286946 0.13549632 0.15545845\n"," 0.17478091 0.19265355 0.20889323 0.22536967]\n","the mean ndcg at\n","[0.32451431 0.30247467 0.28776008 0.27698124 0.26857394 0.25985634\n"," 0.25287661 0.24679682 0.24161056 0.24225384]\n","Training on batch 100/172 sample 1 and iter 9 on dataset lastfm\n","Training on batch 100/172 sample 2 and iter 9 on dataset lastfm\n","Training on batch 100/172 sample 3 and iter 9 on dataset lastfm\n","Finish iteration 9/30 with loss: 2.351650\n","the MAP at\n","[0.25324538 0.19760031 0.17231283 0.15344305 0.13937447 0.12881417\n"," 0.11924113 0.11143542 0.10548039 0.10282508]\n","the mean recall at \n","[0.03372707 0.05907113 0.08629609 0.10927638 0.12903035 0.14958907\n"," 0.16698803 0.18436671 0.20104376 0.21638212]\n","the mean ndcg at\n","[0.32711054 0.29632793 0.28280124 0.27154773 0.26036307 0.25311439\n"," 0.24493126 0.23887481 0.23446399 0.23445968]\n","Training on batch 100/172 sample 1 and iter 10 on dataset lastfm\n","Training on batch 100/172 sample 2 and iter 10 on dataset lastfm\n","Training on batch 100/172 sample 3 and iter 10 on dataset lastfm\n","Finish iteration 10/30 with loss: 2.213068\n","save item representation successfully\n","save memory successfully\n","the MAP at\n","[0.26776605 0.21782437 0.18787246 0.16778486 0.15312793 0.14203968\n"," 0.13228501 0.12306069 0.11654155 0.11367439]\n","the mean recall at \n","[0.03593744 0.06472916 0.0920411 0.11557171 0.13756059 0.15920119\n"," 0.17836887 0.19447762 0.21185864 0.22823893]\n","the mean ndcg at\n","[0.34035604 0.3154945 0.2978132 0.28517721 0.27472339 0.26721048\n"," 0.25948749 0.25112593 0.24619955 0.24607255]\n","Training on batch 100/172 sample 1 and iter 11 on dataset lastfm\n","Training on batch 100/172 sample 2 and iter 11 on dataset lastfm\n","Training on batch 100/172 sample 3 and iter 11 on dataset lastfm\n","Finish iteration 11/30 with loss: 2.049977\n","the MAP at\n","[0.25583113 0.20507266 0.1802549 0.16081145 0.1462962 0.13534861\n"," 0.12682628 0.11920289 0.11318884 0.11090376]\n","the mean recall at \n","[0.03486257 0.06155943 0.09029582 0.11311628 0.13462271 0.15513749\n"," 0.17546979 0.19428764 0.21189049 0.22895547]\n","the mean ndcg at\n","[0.33006603 0.3034149 0.29126745 0.27869606 0.26859612 0.26048915\n"," 0.25427608 0.24863362 0.24408893 0.24462987]\n","Training on batch 100/172 sample 1 and iter 12 on dataset lastfm\n","Training on batch 100/172 sample 2 and iter 12 on dataset lastfm\n","Training on batch 100/172 sample 3 and iter 12 on dataset lastfm\n","Finish iteration 12/30 with loss: 1.940037\n","the MAP at\n","[0.25922603 0.2100511 0.18532501 0.16448848 0.14976868 0.13851862\n"," 0.12853499 0.12086081 0.1148144 0.1131881 ]\n","the mean recall at \n","[0.03486234 0.06197616 0.09103478 0.11338199 0.13554359 0.15644586\n"," 0.17510304 0.19402452 0.21247467 0.23097315]\n","the mean ndcg at\n","[0.33120488 0.30498386 0.29256551 0.27894538 0.26975689 0.26189511\n"," 0.25389984 0.24839298 0.24465479 0.24644975]\n","Training on batch 100/172 sample 1 and iter 13 on dataset lastfm\n","Training on batch 100/172 sample 2 and iter 13 on dataset lastfm\n","Training on batch 100/172 sample 3 and iter 13 on dataset lastfm\n","Finish iteration 13/30 with loss: 1.809631\n","the MAP at\n","[0.25720317 0.21096955 0.18442228 0.16627673 0.15169154 0.1393995\n"," 0.12997507 0.12219363 0.11646076 0.1143801 ]\n","the mean recall at \n","[0.033904 0.0620167 0.09062036 0.11501597 0.13782259 0.1579188\n"," 0.17784078 0.19714789 0.21513915 0.23274233]\n","the mean ndcg at\n","[0.33137395 0.30835894 0.29439567 0.28380531 0.27473124 0.26517046\n"," 0.2581782 0.25260677 0.24813933 0.24912551]\n","Training on batch 100/172 sample 1 and iter 14 on dataset lastfm\n","Training on batch 100/172 sample 2 and iter 14 on dataset lastfm\n","Training on batch 100/172 sample 3 and iter 14 on dataset lastfm\n","Finish iteration 14/30 with loss: 1.701791\n","the MAP at\n","[0.25397537 0.20204873 0.17975512 0.16304339 0.14795512 0.13680931\n"," 0.12693788 0.11940866 0.113457 0.1111581 ]\n","the mean recall at \n","[0.0334876 0.05986583 0.08949628 0.11357236 0.13411029 0.15488265\n"," 0.17356544 0.19187672 0.21028328 0.22693466]\n","the mean ndcg at\n","[0.32315626 0.29762914 0.28869415 0.27855411 0.26740752 0.25949753\n"," 0.25174072 0.24579463 0.24194455 0.24270333]\n","Training on batch 100/172 sample 1 and iter 15 on dataset lastfm\n","Training on batch 100/172 sample 2 and iter 15 on dataset lastfm\n","Training on batch 100/172 sample 3 and iter 15 on dataset lastfm\n","Finish iteration 15/30 with loss: 1.630384\n","save item representation successfully\n","save memory successfully\n","the MAP at\n","[0.2182058 0.18113509 0.16019778 0.14506571 0.13280463 0.12137789\n"," 0.11388569 0.10751192 0.10217517 0.10111828]\n","the mean recall at \n","[0.02967468 0.05503142 0.08118111 0.10378638 0.12433406 0.1417488\n"," 0.16105635 0.17909831 0.19588391 0.21382027]\n","the mean ndcg at\n","[0.2855451 0.26991778 0.25986712 0.25209454 0.24425917 0.23550627\n"," 0.23049601 0.22604128 0.22252292 0.22492766]\n","Training on batch 100/172 sample 1 and iter 16 on dataset lastfm\n","Training on batch 100/172 sample 2 and iter 16 on dataset lastfm\n","Training on batch 100/172 sample 3 and iter 16 on dataset lastfm\n","Finish iteration 16/30 with loss: 1.566339\n","the MAP at\n","[0.20591909 0.17341092 0.15532148 0.14095635 0.12978597 0.1204427\n"," 0.11257745 0.10647815 0.10179339 0.1002338 ]\n","the mean recall at \n","[0.02819758 0.05358144 0.07893282 0.10020005 0.12179601 0.14099291\n"," 0.15892562 0.17652275 0.19388226 0.2104588 ]\n","the mean ndcg at\n","[0.26798143 0.25808928 0.2496284 0.24157542 0.23629948 0.23025325\n"," 0.22456234 0.22013443 0.21733429 0.21911362]\n","Training on batch 100/172 sample 1 and iter 17 on dataset lastfm\n","Training on batch 100/172 sample 2 and iter 17 on dataset lastfm\n","Training on batch 100/172 sample 3 and iter 17 on dataset lastfm\n","Finish iteration 17/30 with loss: 1.493484\n","the MAP at\n","[0.16306069 0.13660008 0.11944043 0.10751592 0.09974598 0.09202424\n"," 0.08637625 0.081895 0.07796739 0.0766401 ]\n","the mean recall at \n","[0.0228597 0.04449086 0.0665177 0.08430162 0.10325818 0.11937424\n"," 0.13494307 0.15120494 0.16521616 0.17949766]\n","the mean ndcg at\n","[0.22580028 0.21885995 0.21154837 0.20463799 0.20129841 0.1957813\n"," 0.19131689 0.18867335 0.1856005 0.18696221]\n","Training on batch 100/172 sample 1 and iter 18 on dataset lastfm\n","Training on batch 100/172 sample 2 and iter 18 on dataset lastfm\n","Training on batch 100/172 sample 3 and iter 18 on dataset lastfm\n","Finish iteration 18/30 with loss: 1.423724\n","the MAP at\n","[0.13813544 0.11872304 0.10353435 0.09447171 0.0876722 0.08154195\n"," 0.07724628 0.07282223 0.06946746 0.06828121]\n","the mean recall at \n","[0.0201383 0.0431395 0.05994607 0.07727967 0.09362966 0.10893769\n"," 0.12517866 0.13821757 0.15203621 0.16449533]\n","the mean ndcg at\n","[0.19702241 0.19635344 0.18825263 0.18405342 0.18001654 0.17621656\n"," 0.17420998 0.1704177 0.16864232 0.16962136]\n","Training on batch 100/172 sample 1 and iter 19 on dataset lastfm\n","Training on batch 100/172 sample 2 and iter 19 on dataset lastfm\n","Training on batch 100/172 sample 3 and iter 19 on dataset lastfm\n","Finish iteration 19/30 with loss: 1.366675\n","the MAP at\n","[0.14432718 0.11400804 0.09842052 0.08892525 0.08152314 0.07550994\n"," 0.07037349 0.06630479 0.06376948 0.0631296 ]\n","the mean recall at \n","[0.02436324 0.04249572 0.0595887 0.07587341 0.09087383 0.10546706\n"," 0.11948694 0.13284822 0.14776192 0.16194132]\n","the mean ndcg at\n","[0.20678944 0.19404984 0.18645651 0.18119955 0.17596929 0.17164038\n"," 0.16807869 0.16515024 0.16459408 0.16720269]\n","Training on batch 100/172 sample 1 and iter 20 on dataset lastfm\n"]}]},{"cell_type":"markdown","metadata":{"id":"7MzbkGTy2NW5"},"source":["## Citations\n","\n","HERS: Modeling Influential Contexts with Heterogeneous Relations for Sparse and Cold-Start Recommendation. Hu et. al.. 2019. arXiv. [https://ojs.aaai.org//index.php/AAAI/article/view/4270](https://ojs.aaai.org//index.php/AAAI/article/view/4270)"]}]}