GithubHelp home page GithubHelp logo

cripac-dig / sr-gnn Goto Github PK

View Code? Open in Web Editor NEW
810.0 11.0 272.0 130 KB

[AAAI 2019] Source code and datasets for "Session-based Recommendation with Graph Neural Networks"

Python 100.00%
session-based-recommendation recommender-systems graph-neural-networks machine-learning

sr-gnn's Introduction

SR-GNN

Paper data and code

This is the code for the AAAI 2019 Paper: Session-based Recommendation with Graph Neural Networks. We have implemented our methods in both Tensorflow and Pytorch.

Here are two datasets we used in our paper. After downloaded the datasets, you can put them in the folder datasets/:

There is a small dataset sample included in the folder datasets/, which can be used to test the correctness of the code.

We have also written a blog explaining the paper.

Usage

You need to run the file datasets/preprocess.py first to preprocess the data.

For example: cd datasets; python preprocess.py --dataset=sample

usage: preprocess.py [-h] [--dataset DATASET]

optional arguments:
  -h, --help         show this help message and exit
  --dataset DATASET  dataset name: diginetica/yoochoose/sample

Then you can run the file pytorch_code/main.py or tensorflow_code/main.py to train the model.

For example: cd pytorch_code; python main.py --dataset=sample

You can add the suffix --nonhybrid to use the global preference of a session graph to recommend instead of the hybrid preference.

You can also change other parameters according to the usage:

usage: main.py [-h] [--dataset DATASET] [--batchSize BATCHSIZE]
               [--hiddenSize HIDDENSIZE] [--epoch EPOCH] [--lr LR]
               [--lr_dc LR_DC] [--lr_dc_step LR_DC_STEP] [--l2 L2]
               [--step STEP] [--patience PATIENCE] [--nonhybrid]
               [--validation] [--valid_portion VALID_PORTION]

optional arguments:
  -h, --help            show this help message and exit
  --dataset DATASET     dataset name:
                        diginetica/yoochoose1_4/yoochoose1_64/sample
  --batchSize BATCHSIZE
                        input batch size
  --hiddenSize HIDDENSIZE
                        hidden state size
  --epoch EPOCH         the number of epochs to train for
  --lr LR               learning rate
  --lr_dc LR_DC         learning rate decay rate
  --lr_dc_step LR_DC_STEP
                        the number of epochs after which the learning rate
                        decay
  --l2 L2               l2 penalty
  --step STEP           gnn propogation steps
  --patience PATIENCE   the number of epoch to wait before early stop
  --nonhybrid           only use the global preference to predict
  --validation          validation
  --valid_portion VALID_PORTION
                        split the portion of training set as validation set

Requirements

  • Python 3
  • PyTorch 0.4.0 or Tensorflow 1.9.0

Other Implementation for Reference

There are other implementation available for reference:

  • Implementation based on PaddlePaddle by Baidu [Link]
  • Implementation based on PyTorch Geometric [Link]
  • Another implementation based on Tensorflow [Link]
  • Yet another implementation based on Tensorflow [Link]

Citation

Please cite our paper if you use the code:

@inproceedings{Wu:2019ke,
title = {{Session-based Recommendation with Graph Neural Networks}},
author = {Wu, Shu and Tang, Yuyuan and Zhu, Yanqiao and Wang, Liang and Xie, Xing and Tan, Tieniu},
year = 2019,
booktitle = {Proceedings of the Twenty-Third AAAI Conference on Artificial Intelligence},
location = {Honolulu, HI, USA},
month = jul,
volume = 33,
number = 1,
series = {AAAI '19},
pages = {346--353},
url = {https://aaai.org/ojs/index.php/AAAI/article/view/3804},
doi = {10.1609/aaai.v33i01.3301346},
editor = {Pascal Van Hentenryck and Zhi-Hua Zhou},
}

sr-gnn's People

Contributors

sxkdz avatar tangrizzly avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sr-gnn's Issues

'GAT' in tensorlfow code

What's the purpose of 'GAT' in utils.py in tensorflow code?
Did you provide the version that contains GAT before?

数据处理问题

作者您好,非常感谢您的开源,请教两个问题:

  1. 请问为什么在diginetica数据集下,论文中报的STAMP的实验结果(P@20 45.64)与STAMP自己的结果(P@20 62.03)降低那么多呢?
  2. Yoochoose 1/4 数据集的clicks用您的代码处理后是7911603并不是论文中报的8,326,407,请问我是哪里出问题了吗?

Statistics of items in Yoochoose(both) data not matching.

We processed data as you mentioned and the number of train and test sessions are matched.

with open('../yoochoose1_64/train.txt','rb')as f:
    train=cPickle.load(f)
print("len of train",len(train[0]))
with open('../yoochoose1_64/test.txt','rb')as f:
    test=cPickle.load(f)
print("len of test",len(test[0]))

len of train 369859
len of test 55898

But, you reported that count of all items in yoochoose1/64 data as 16766. We are getting a different number. Same problem with Yoocooose1/4 data also. Please find our code.
#train sequences and labels
train_seq=train[0]
train_y=train[1]
#test sequences and labels
test_seq=test[0]
test_y=test[1]
# find unique items in the train sequences
full_train = [j for sub in train_seq for j in sub]
print("count of items ",len(set(full_train)))

`count of items16373`

Can you please mention the code to find count of items?

Softmax function not being applied? : PyTorch Code

In the paper it is mentioned that the softmax function is being applied to the outputs after computing scores for each candidate item (equation 9), however, the PyTroch Implemention (compute_scores method) doesn't seem to be doing that. Is there a reason why it isn't used?

I have tested the model with the softmax function (default hyperparameters), and the evaulation metrics peformance has drastically decreased. I suspect if it has anything to do with the low output values after softmax. Any thoughts on this?

Inconsistent data descriptions

In the paper, it's reported that yoochoose 1/64 and 1/4 have 16,766 and 29,618 items respectively. However, using preprocess.py to process data results in 17,377 and 30,444 items respectively. Where are the missing items?

关于GNN实现部分的一个部分

根据我的理解,如果每批的大小是batch_size最终定的节点数是max_n_node的话,则送到GNN中的A应该是(batch_size,max_n_node,max_n_node*2)的size,而那个GNNCell代码中第一行的地方matmul的是(batch_size,max_n_node,max_n_node)和(hidden_size,hidden_size)的LinearLayer,这就很困惑了,max_n_node和hidden_size不一样的时候咋办。请问我的理解是否有误。。。

User clicks within every user session in the DIGENTICA is ordered, the timeframe is the time spent on browsing

I see that you have revised the results of the experiment in the latest version. The reason is that the user clicks within every user session in the DIGENTICA dataset are still out of order. But actually user clicks within every user session in the DIGENTICA dataset is ordered, the timeframe is the time spent on browsing.
Please see the train-item-views.csv file. The data in timeframe column is in range(1,000, 2,000,000). It's not possible to say click time because if the dataset use the Unix timestamp, the range for a day should be (0,86,400), otherwise it should be (0,86,400,000).
And if the order after changing is correct, why do the results of all the experiments go down?

论文示意图与代码不符?

看论文的model overview,用于训练和预测的应该是经过了GNN之后得到的item embedding,但是代码里是用的第0层的item embedding?作者求解释一下?

In Tensorflow code: last_h(last item embedding) instead of last (last_h * w1) when concatenate with Sg

Tensorflow code/model.py line no. 46
ma = tf.concat([tf.reduce_sum(tf.reshape(coef, [self.batch_size, -1, 1]) * seq_h, 1), tf.reshape(last, [-1, self.out_size])], -1)
I think 'last' should be 'last_h' in above line, as in code:
last_h = tf.gather_nd(re_embedding, tf.stack([tf.range(self.batch_size), last_id], axis=1))
last = tf.matmul(last_h, self.nasr_w1)
According to paper Sg should be concatenate with last item embedding.
Please clarify.

关于每次输入的hidden

image
作者您好,关于这段代码每次输入的hidden,它的shape是batch_sizeseq_lengthlatent_size。这里的seq_length应该是会话序列中的最大长度吧?我不知道理解的对不对。也就是说,您把长度不一的序列都进行了处理对吗?

如何对数据集中的session进行排序?

作者您好:
感谢您的工作,我对数据集的预处理有一些疑问:
在Yoochoose数据集中,模型需要截取最近1/64和1/47以方便实验。在对session排序的时候,是依据一个session中最后一次点击的时间还是最开始点击的时间进行排序?我从代码中理解,是否只是取了读入数据的最后一个时间,而没有对session内部先进行排序?
谢谢!
If it is not convenient to use Chinese, I can restate my question in English. Thank you very much

ggnn函数代码疑问

感谢提供基于session的图网络的推荐想法!我在复现代码的过程中,对于tensorflow_code文件下的model.py中ggn定义有点疑问,如果self.step>1,当i=0时,经过tf.nn.dynamic_rnn输出的fin_stateshape:(batch_size, out_size), 而当i = 1时, self.adj_inshape: (batch_size, max_uniq_len, max_uniq_len).对于tf.matmul(self.adj_in, fin_state_in), 按照shape来看,(batch_size, max_uniq_len, max_uniq_len) * (batch_size, 1, out_size)根本无法矩阵运算,麻烦解答~多谢!

preprocessed file data format

Could you please explain the format of data written to the files.
train.txt, test.txt and all_train_seq.txt.
And what are yoochoose1_4 and yoochoose1_64 files (importance of 4 and 64)?

去掉GGNN后测试集效果更好

作者您好,非常感谢您的开源,有个问题想请教一下:

对于tensorflow 的代码,我在diginetica数据集上做了两个实验:

  1. 正常运行,在第三个3epoch 达到最好,Recall@20: 50.0131 | MMR@20: 16.3228
  2. 去掉GGNN部分,在第三个3epoch 达到最好,Recall@20: 50.4795 | MMR@20: 16.9137
    从实验结果上看,加入GGNN后反而会降低实验效果,请问我是哪里出了问题吗?

Should we add a transpose for the connection matrix?

u_sum_in = np.sum(u_A, 0)
u_sum_in[np.where(u_sum_in == 0)] = 1
u_A_in = np.divide(u_A, u_sum_in)
u_sum_out = np.sum(u_A, 1)
u_sum_out[np.where(u_sum_out == 0)] = 1
u_A_out = np.divide(u_A.transpose(), u_sum_out)

It seems we should add a transpose for u_A_in and u_A_out for normalization. Does it matter?

The source of small dataset 'sample'

Thanks for sharing this awesome project! I want to know where this small dataset 'sample' with 310 nodes comes from? Is it a subset from yoochoose or diginetica, or is just generated manually?

Inconsistent experimental results and descripitions

Please check Figure 4 in the STAMP paper.
The data reported in Table 3 in your paper is quite different with the data reported in Figure 4 even with the same experimental settings. To be specific, in Table 3, the P@20 of STAMP on Diginetica is 47.26 and 40.39 for short sessions and long sessions respectively. However, the data reported in Figure 4 is around 61 and 65 respectively. STAMP actually performs better with long seesions on Diginetica. Why the big difference between your experiments and Qiao Liu's?

Problem of preprocess.py

1552403425(1)
For diginetica, I run it sucessfully, but for yoochoose, I can't.In yoochoose-clicks.dat, there are no titles like "item_id", "Session_id", so I want to know how to revise it.Thank you.

preprocess.py doesn't work on yoochoose-clicks.dat

Running python preprocess.py --dataset=yoochoose assumes a CSV header, which is not available in the standard yoochoose-clicks.dat downloaded from the source in the README. The assumed formatting of the timestamp data is also not correct.

n_node 的提问

代码里面n_node是怎么得到的,是人为设定的还是算出来的?

数据集统计问题

你好,想请教一下,你们的论文中数据集统计的那张表of clicks是怎么统计的呢,我这边按照你们的数据处理方法,统计列表中除了of clicks外基本都对的上,只有of clicks,差距较大,特别是Yoochoose 1/4的of clicks,训练集+测试及合在一起的clicks也只有7911599条

Are you make it along with the original paper?

I have visited the original paper.But I find confusion in this code where GNN Class is implemented.Are you make it along with the original paper?In original paper,it users Gated Graph Neural Network.Do you do it in a common GNN style?

For Yoochoose dataset, why split train-test then get 1/4 and 1/64

Hi,

Thank you for sharing your code.

I have a question about the data preprocessing for Yoochoose dataset. In the code, you first split the train-test sets based on time, and make sure there is no item in test set that does not appear in training set, then you use the current training data to get most recent 1/4 and 1/64 sessions to be the final training set. By this, the final test set still has items that do not appear in the training set. Is that a problem?

GGNN function in tensorflow code

In ggnn function, the input shape of dynamic_rnn will be (self.batch_size * max_n_node, 1, 2 * hidden_size) = (# of all items in a batch, 1, 2 * hidden_size) and initial states' shape will be (self.batch_size * max_n_node, hidden_size) = (# of all items in a batch, hidden_size).

So there's only one time step for each sequence (the second element max_time in inputs = 1), which mean the first item vector in inputs (shape = (2 * hidden_size,)) will get the embedding after interacting with the first initial hidden state (shape = ( hidden_size,)) in only one time step. And for the second item vector in inputs will also get it's embedding with the second initial hidden state in one time step. Is that right ? If so, then there is no recurrent meaning in this RNN ?

Cause in my understanding, item should be fed into RNN time step by time step for a session, which means the hidden state (embedding) will be affected by the previous click item. I wonder why the inputs shape is (# of all items in a batch, 1, 2 * hidden_size) instead of (self.batch_size, max_n_node, 2 * hidden_size). What is the meaning of this setting in dynamic_rnn function ?

The difference in 5 equation in paper and code

In original paper the last rule of update node vector is: $v_i^t = (1 - z_{s, i}^t) \odot v_i^{t-1} + z_{s, I}^t \odot v_i^t$. But following the code, the rules is not the same:
https://github.com/CRIPAC-DIG/SR-GNN/blob/90123c88850eec8c574518fee6e46aefb42acb94/pytorch_code/model.py#L45-L47
Code's rule is: $v_i^t = (1 - z_{s, i}^t) \odot v_i^t + z_{s, I}^t \odot v_i^{t-1}$. The difference is swap v_i^t and v_i^{t-1}.

Is it mistake in paper or in code?

about the connection matrix

hi,dear
paper中的连接矩阵是指左边的吗?还是说全部啊,右边的部分没看懂啊?咋理解啊?
多谢
image

Why take 1 away from targets?

Hi,

In your model's loss calculation, you feed the labels in but take 1 away from them:
tf.nn.sparse_softmax_cross_entropy_with_logits(labels=self.tar - 1, logits=logits))

Why is that?

The code is inconsistent with the one described in paper

In your paper, it's mentioned that the graph is constructed by all the session.

In https://arxiv.org/pdf/1811.00855.pdf, page 6 the first paragraph under subtitle Comparison with Variants of Connection Schemes
Firstly, we aggregate all session sequences together and model them as a directed whole item graph, which is termed as the global graph hereafter.

But in your code, both your tensorflow and pytorch version, your code comment the build_graph function and model each session sequence as one small directed graph.

New hidden vector computation in GNNCell of PyTorch code

Question 1:

The naming of variables in the GNNCell is a little bit frustrating such as there no inputgate in the origin paper. And the computation of the final hidden vectors is different from the origin paper.

In the paper, Eq(5) is like
image

While in the code,

hy = newgate + inputgate * (hidden - newgate) 

newgate stands for Eq(4) according to this line of code. hidden stands for the hidden vector representation of the former layers. And the inputgate stands for the z in Eq(5). It seems that code and paper are not matched.

Question 2:

In the computation code of softmax along all items, why is the 0th embedding left out? After leaving out this embedding, the shape is no longer [n_nodes, latent_size] but [n_nodes - 1, latent_size].

image

@SXKDZ @tangrizzly

Inconsistent performance of POP

In the paper, it reported that the performance of POP in yoochoose1_64 is 6.71 (P@20). However, when I reimplement POP, I got different result 7.36. Could you open the source code and the parameter setting of baselines?

Tensorflow and PyTorch code have different performance

I tried to do experiments on the Diginetica dataset with the Tensorflow code, but I don't know why the P@20 can only reach 49.8. However, P@20 in PyTorch code can achieve the same performance as the paper, 50.7, and the hyperparameters and model look the same as Tensorflow. I am confused and hope to find a solution. Thank you very much.

GPU使用率低怎么破

GPU使用率均值只有10%不到,感觉是构建图的过程占用cpu时间过长,如何改呢

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.