From 0bfa8ea4c37c417c66c0fc6efb95b1a6d9778079 Mon Sep 17 00:00:00 2001 From: dong zhihong Date: Mon, 15 May 2017 19:43:38 +0800 Subject: [PATCH] "update README, add more comment to code" --- ltr/README.md | 347 +++++++++++++++++++++++++++++++++- ltr/lambdaRank.py | 171 +++++++++-------- ltr/lambdarank.jpg | Bin 0 -> 26644 bytes ltr/learningToRank.jpg | Bin 0 -> 36496 bytes ltr/metrics.py | 30 +++ ltr/ranknet.jpg | Bin 0 -> 35950 bytes ltr/ranknet.py | 199 +++++++++++-------- ltr/search-engine-example.png | Bin 0 -> 81260 bytes 8 files changed, 579 insertions(+), 168 deletions(-) create mode 100644 ltr/lambdarank.jpg create mode 100644 ltr/learningToRank.jpg create mode 100644 ltr/metrics.py create mode 100644 ltr/ranknet.jpg create mode 100644 ltr/search-engine-example.png diff --git a/ltr/README.md b/ltr/README.md index a0990367..8d78c220 100644 --- a/ltr/README.md +++ b/ltr/README.md @@ -1 +1,346 @@ -TBD +## 排序学习(LearningToRank) + +排序学习技术[1] 是构建排序模型的机器学习方法,在信息检索,自然语言处理,数据挖掘等机器学场景中具有重要作用。排序学习的主要目的是对给定一组文档,对任意查询请求给出反映相关性的文档排序。在本例子中,利用标注过的语料库训练两种经典排序模型RankNet[4]和LamdaRank[6],分别可以生成对应的排序模型,能够对任意查询请求,给出相关性文档排序。 + +用户可以使用 `python ranknet.py` 或者 `python lambdaRank.py`命令就完成排序模型的训练和预测,程序会自动下载内置数据集,无需手动下载。 + + + +## 背景介绍 + +排序学习技术随着互联网的快速增长而受到越来越多关注,是机器学习中的常见任务。一方面人工排序规则不能处理海量规模的候选数据,另一方面无法为不同渠道的候选数据给于合适的权重,因此排序学习在日常生活中应用非常广泛。排序学习起源于信息检索领域,目前仍然是许多信息检索场景中的核心模块,例如搜索引擎搜索结果排序,推荐系统候选集排序,在线广告排序等等。在本例子中,采用文档检索阐述排序学习模型。 + +

+ + + +
图1 排序模型在文档检索的典型应用搜索引擎中的作用

+ +假定有一组文档S,文档检索任务是依据和请求的相关性,给出文档排列顺序。查询引擎根据查询请求,排序模型会给每个文档打出分数,依据打分情况倒序排列文档,得到查询结果。在训练模型时,给定一条查询,并给出对应的文档最佳排序和得分。在预测时候,给出查询请求,排序模型生成文档排序。传统的排序学习方法划分为以下三类: + +- Pointwise 方法 + + Pointwise方法是通过近似为回归问题解决排序问题,输入的单条样本为得分-文档,将每个查询-文档对的相关性得分作为实数分数或者序数分数,使得单个查询-文档对作为样本点(Pointwise的由来),训练排序模型。预测时候对于指定输入,给出查询-文档对的相关性得分 + +- Pairwise方法 + + Pairwise方法是通过近似为分类问题解决排序问题,输入的单条样本为标签-文档对。对于一次查询的多个结果文档,组合任意两个文档形成文档对作为输入样本。即学习一个二分类器,对输入的一对文档对AB(Pairwise的由来),根据A相关性是否比B好,二分类器给出分类标签+1或-1。对所有文档对进行分类,就可以得到一组偏序关系,从而构造文档全集的排序关系。该类方法的原理是对给定的文档全集S,降低排序中的逆序文档对的个数来降低排序错误,从而达到优化排序结果的目的。 + +- Listwise方法 + + Listwise方法是直接优化排序列表,输入为单条样本为一个文档排列。通过构造合适的度量函数衡量当前文档排序和最优排序差值,优化度量函数得到排序模型。由于度量函数很多具有非连续性,优化困难。 + +

+ + + +
图2 排序模型三类构造方法

+ + ​ + +## 实验数据 + +本例子中的实验数据采用了排序学习中的基准数据[LETOR]([http://research.microsoft.com/en-us/um/beijing/projects/letor/LETOR4.0/Data/MQ2007.rar](http://research.microsoft.com/en-us/um/beijing/projects/letor/LETOR4.0/Data/MQ2007.rar))中语料库,部分来自于Gov2网站的查询请求结果,包含了约1700条查询请求结果文档列表,并对文档相关性做出了人工标注。其中,一条查询含有唯一的查询id,对应于多个具有相关性的文档,构成了一次查询请求结果文档列表。每个文档由一个一维数组的特征向量表示,并对应一个人工标注与查询的相关性分数。 + +[文档与查询相关性分数] :[查询id] : [文档的特征向量] + +score : query id : feature1, feature2, …., featureN. + +本样例在第一次运行的时候会自动下载LETOR MQ2007数据集并缓存,用户无需手动下载。 + +`mq2007`数据集分别提供了三种类型排序模型的生成格式,需要指定生成格式`format` + +例如 + +```python +pairwise_train_dataset = functools.partial(paddle.dataset.mq2007.train, format="pairwise") +for label, left_doc, right_doc in pairwise_train_dataset(): + ... +``` + + + + + +## 模型概览 + +对于排序模型,本样例中提供了PairWise方法的模型RankNet和ListWise方法的模型LambdaRank,分别代表了两类学习方法。PointWise方法的排序模型退化为回归问题,不予赘述。 + + + +## RankNet排序模型 + +[RankNet](http://icml.cc/2015/wp-content/uploads/2015/06/icml_ranking.pdf)是一种经典的Pairwise的排序学习方法,是典型的前向神经网络排序模型。在文档集合S中的第i个文档记做`Ui`,它的文档特征向量记做`xi`,对于给定的一个文档对``,RankNet将输入的单个文档特征向量x映射到`f(x)`,得到`si=f(xi), sj=f(xj)`。将`Ui`相关性比Uj好的概率记做Pij,则 + +$$P_{i,j}=P(U_{i}>U_{j})=\frac{1}{1+e^{-\sigma (s_{i}-s_{j}))}}$$ + +由于排序度量函数大多数非连续,非光滑,因此RankNet需要一个可以优化的度量函数C。首先使用交叉熵作为度量函数衡量预测代价,将损失函数C记做 + +$$C_{i,j}=-\bar{P_{i,j}}logP_{i,j}-(1-\bar{P_{i,j}})log(1-P_{i,j})$$ + +其中代表真实概率的 + +$$\bar{P_{i,j}}=\frac{1}{2}(1+S_{i,j})$$ + +而Sij = {+1,-1},表示Ui和Uj组成的Pair的标签,即Ui相关性是否好于Uj。 + +最终得到了可求导的度量损失函数 + +$$C=\frac{1}{2}(1-S_{i,j})\sigma (s_{i}-s{j})+log(1+e^{-\sigma (s_{i}-s_{j})})$$ + +可以使用常规的梯度下降方法进行优化。细节见[RankNet](http://icml.cc/2015/wp-content/uploads/2015/06/icml_ranking.pdf) + +同时,得到文档Ui在排序优化过程的梯度信息为 + +\lambda _{i,j}=\frac{\partial C}{\partial s_{i}} = \frac{1}{2}(1-S_{i,j})-\frac{1}{1+e^{\sigma (s_{i}-s_{j})}} + +表示的含义是本轮排序优化过程中上升或者下降量。 + + + +根据以上推论构造RankNet网络结构,由若干层隐藏层和全连接层构成,如图所示,将文档特征使用隐藏层,全连接层逐层变换,完成了底层特征空间到高层特征空间的变换。其中docA和docB结构对称,分别输入到最终的RankCost层中。 + +

+ + + +
图3 RankNet网络结构示意图

+ + + +- 全连接层(fully connected layer) : 指上一层中的每个节点都连接到下层网络。本例子中同样使用paddle.layer.fc实现,注意输入到RankCost层的全连接层输出为1x1的层结构 +- RankCost层: RankCost层是排序网络RankNet的核心,度量docA相关性是否比docB好,给出预测值并和label比较。使用了交叉熵(cross enctropy)作为度量损失函数,使用梯度下降方法进行优化。细节可见[RankNet](http://icml.cc/2015/wp-content/uploads/2015/06/icml_ranking.pdf)[4] + +由于Pairwise中的网络结构是左右对称,可定义一半网络结构,另一半共享网络参数。使用PaddlePaddle实现RankNet排序模型,定义网络结构的示例代码如下: + +```python +import paddle.v2 as paddle + +def half_ranknet(name_prefix, input_dim): + """ + parameter in same name will be shared in paddle framework, + these parameters in ranknet can be used in shared state, e.g. left network and right network + shared parameters in detail + https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/api.md + """ + # data layer + data = paddle.layer.data(name_prefix+"/data", paddle.data_type.dense_vector(input_dim)) + + # fully connect layer + hd1 = paddle.layer.fc( + input=data, + size=10, + act=paddle.activation.Tanh(), + param_attr=paddle.attr.Param(initial_std=0.01, name="hidden_w1")) + # fully connect layer/ output layer + output = paddle.layer.fc( + input=hd1, + size=1, + act=paddle.activation.Linear(), + param_attr=paddle.attr.Param(initial_std=0.01, name="output")) + return output + +def ranknet(input_dim): + # label layer + label = paddle.layer.data("label", paddle.data_type.integer_value(1)) + + # reuse the parameter in half_ranknet + output_left = half_ranknet("left", input_dim) + output_right = half_ranknet("right", input_dim) + + # rankcost layer + cost = paddle.layer.rank_cost(name="cost", left=output_left, right=output_right, label=label) + return cost +``` + +上述结构中使用了和前述图表相同的模型结构,使用了两层隐藏层,分别使用了`hidden_size=10`的全连接层和`hidden_size=1`的全连接层。本例子中的input_dim指输入**单个文档**的特征dense_vector的维度,label取值为1,-1。每条输入样本为label,\的结构,以docA为例,输入input_dim的文档特征,依次变换成10维,1维特征,最终输入到RankCost层中,比较docA和docB在RankCost输出得到预测值。 + +用户运行`python ranknet.py`将会将每个轮次的模型存下来,并在测试数据上测试效果。 + + + +## 用户自定义RankNet数据 + +上面的代码使用了paddle内置的排序数据,如果希望使用自定义格式数据。可以参考Paddle内置的`mq2007`数据集,编写一个生成器函数。例如输入数据为如下格式,只包含doc0-doc2三个文档。 + +\ \ \的格式 + +``` +query_id : 1, relevance_score:1, feature_vector 0:0.1, 1:0.2, 2:0.4 #doc0 +query_id : 1, relevance_score:2, feature_vector 0:0.3, 1:0.1, 2:0.4 #doc1 +query_id : 1, relevance_score:0, feature_vector 0:0.2, 1:0.4, 2:0.1 #doc2 +query_id : 2, relevance_score:0, feature_vector 0:0.1, 1:0.4, 2:0.1 #doc0 +..... +``` + +需要将输入样本转换为PairWise的输入格式,例如组合生成格式与mq2007 PairWise格式相同的结构 + +\ \\ + +``` +1 doc1 doc0 +1 doc1 doc2 +1 doc0 doc2 +.... +``` + +注意,一般在PairWise格式的数据中,label=1表示docA和查询的相关性好于docB,事实上label信息隐含在docA和docB组合pair中。如果存在`-1 docA docB`,交换顺序构造`1 docB docA`即可。 + +另外组合所有的pair会有训练数据冗余,因为可以从部分偏序关系恢复文档集上的全序关系。相关研究见[PairWise approach](http://www.machinelearning.org/proceedings/icml2007/papers/139.pdf)[5],本例子不予赘述。 + +```python +# self define data generator +def gen_pairwise_data(text_line_of_data): + """ + return : + ------ + label : np.array, shape=(1) + docA_feature_vector : np.array, shape=(1, feature_dimension) + docA_feature_vector : np.array, shape=(1, feature_dimension) + """ + yield label, docA_feature_vector, docB_feature_vector +``` + +对应于paddle的输入中,`integer_value`为单个整数,`dense_vector`为实数一维向量,与生成器对应,需要在训练模型之前指明输入数据对应关系。 + +```python +# Define the input data order +feeding = {"label":0, + "left/data" :1, + "right/data":2} +``` + + + +## LambdaRank排序模型 + +[LambdaRank](https://papers.nips.cc/paper/2971-learning-to-rank-with-nonsmooth-cost-functions.pdf)[6]是ListWise的排序方法,是Bugers[6]等人从RankNet发展而来,使用构造lambda函数(LambdaRank名字的由来)的方法优化度量标准NDCG(Normalized Discounted Cumulative Gain),每个查询后得到的结果文档列表都单独作为一个训练样本。NDCG是信息论中很衡量文档列表排序质量的标准之一,前K个文档的NDCG得分记做 + +$$NDCG@K=Z_{k}\sum (2^{rel_{i}})1/log(k+1)$$ + +前文中RankNet中推导出,文档排序需要的是排序错误的梯度信息。NDCG度量函数是非光滑,非连续的,不能直接求得梯度信息,因此将|delta(NDCG)|=|NDCG(new) - NDCG(old)|引入,构造lambda函数为 + +$$\lambda _{i,j}=\frac{\partial C}{\partial s_{i}}=-\frac{\sigma }{1+e^{\sigma (s_{i}-s{j})}}|\Delta NDCG|$$ + +替换RankNet中的梯度表示,得到的排序模型称为[LambdaRank](https://papers.nips.cc/paper/2971-learning-to-rank-with-nonsmooth-cost-functions.pdf) + +由以上推导可知,LambdaRank网络结构和RankNet结构非常相似。如图所示 + +

+ + + +
图4. LambdaRank的网络结构示意图

+ +一个查询得到的结果文档列表作为一条样本输入到网络中,替换RankCost为LambdaCost层,其他结构与RankNet相同。 + +- LambdaCost层 : LambdaCost层使用NDCG差值作为Lambda函数,score是一个一维的序列,对于单调训练样本全连接层输出的是1x1的序列,二者的序列长度都等于该条查询得到的文档数量。Lambda函数的构造详细见[LambdaRank](https://papers.nips.cc/paper/2971-learning-to-rank-with-nonsmooth-cost-functions.pdf) + +使用Paddle定义LambdaRank网络结构的示例代码如下: + +```python +import paddle.v2 as paddle +def lambdaRank(input_dim): + label = paddle.layer.data("label", paddle.data_type.dense_vector_sequence(1)) + data = paddle.layer.data("data", paddle.data_type.dense_vector_sequence(input_dim)) + + # hidden layer + hd1 = paddle.layer.fc( + input=data, + size=10, + act=paddle.activation.Tanh(), + param_attr=paddle.attr.Param(initial_std=0.01)) + output = paddle.layer.fc( input=hd1, + size=1, + act=paddle.activation.Linear(), + param_attr=paddle.attr.Param(initial_std=0.01)) + cost = paddle.layer.lambda_cost(input=output, + score=label, + NDCG_num=6, + max_sort_size = -1) + return cost, output +``` + +上述结构中使用了和前述图表相同的模型结构,和RankNet相似,分别使用了`hidden_size=10`的全连接层和`hidden_size=1`的全连接层。本例子中的input_dim指输入**单个文档**的特征dense_vector的维度,label取值为1,-1。每条输入样本为label,\的结构,以docA为例,输入input_dim的文档特征,依次变换成10维,1维特征,最终输入到LambdaCost层中。需要注意这里的label和data格式为**dense_vector_sequence**,表示一列文档得分或者文档特征组成的**序列**。 + +用户运行`python lambdaRank.py`将会把每个轮次的模型存下来,并在测试数据上测试效果。 + + + +## 自定义 LambdaRank数据 + +上面的代码使用了paddle内置的mq2007数据,如果希望使用自定义格式数据。可以参考Paddle内置的`mq2007`数据集,编写一个生成器函数。例如输入数据为如下格式,只包含doc0-doc2三个文档。 + +\ \ \的格式 + +``` +query_id : 1, relevance_score:1, feature_vector 0:0.1, 1:0.2, 2:0.4 #doc0 +query_id : 1, relevance_score:2, feature_vector 0:0.3, 1:0.1, 2:0.4 #doc1 +query_id : 1, relevance_score:0, feature_vector 0:0.2, 1:0.4, 2:0.1 #doc2 +query_id : 2, relevance_score:0, feature_vector 0:0.1, 1:0.4, 2:0.1 #doc0 +query_id : 2, relevance_score:2, feature_vector 0:0.1, 1:0.4, 2:0.1 #doc1 +..... +``` + +需要转换为ListWise格式,例如 + + + +```tex +1 1 0.1,0.2,0.4 +1 2 0.3,0.1,0.4 +1 0 0.2,0.4,0.1 + +2 0 0.1,0.4,0.1 +2 2 0.1,0.4,0.1 +...... +``` + +**数据格式注意** + +- 数据中每条样本对应的文档数量都必须大于Lambda_cost层的NDCG_num +- 单条样本对应的文档都为0,NDCG将会计算无效。文档相关性都为0,那么可以判定该query无效,可以过滤掉。 + + + +```python +# self define data generator +def gen_listwise_data(text_all_lines_of_data): + """ + return : + ------ + label : np.array, shape=(samples_num, ) + querylist : np.array, shape=(samples_num, feature_dimension) + """ + yield label_list, query_docs_feature_vector_matrix +``` + +对应于paddle的输入中,label的`dense_vector_sequence`为得分序列,data的`dense_vector_sequence`为特征向量的序列输入,input_dim为单个文档的一维特征向量维度,与生成器对应,需要在训练模型之前指明输入数据对应关系。 + +```python +# Define the input data order +feeding = {"label":0, + "data" : 1} +``` + + + +## 总结 + +LearningToRank是和业务场景结合非常紧密的常用机器学习方法,排序模型构造方法一般可划分为PointWise方法,PairWise方法,ListWise方法,本例子中以LETOR的mq2007数据为例,阐述了PairWise的经典方法RankNet和ListWise方法中的LambdaRank,展示如何使用Paddle框架构造对应的排序模型结构,并提供了自定义数据类型样例。Paddle提供了灵活的编程接口,并能在单机单GPU和多机分布式多GPU无缝运行,可以实现LearningToRank类型任务。 + + + +## 参考文献 + +[1] https://en.wikipedia.org/wiki/Learning_to_rank + +[2] T.Y. Liu, “Learning to rank for information retrieval,” Foundations and Trends in Information Retrieval, vol.3, no.3, pp.225–331, 2009. + +[3] H. Li, “Learning to rank for information retrieval and natural language processing,” Synthesis Lectures on Human Language Technologies, 2011, Morgan & Claypool Publishers. + +[4] Burges C, Shaked T, Renshaw E, et al. Learning to rank using gradient descent[C]// International Conference. DBLP, 2005:89-96. + +[5]Cao Z, Qin T, Liu T Y, et al. Learning to rank: from pairwise approach to listwise approach[C]// International Conference on Machine Learning. ACM, 2007:129-136. + +[6]Schölkopf B, Platt J, Hofmann T. Learning to Rank with Nonsmooth Cost Functions[C]// Conference on Advances in Neural Information Processing Systems. MIT Press, 2006:193-200. diff --git a/ltr/lambdaRank.py b/ltr/lambdaRank.py index f2301bf3..6d28be62 100644 --- a/ltr/lambdaRank.py +++ b/ltr/lambdaRank.py @@ -1,99 +1,104 @@ import os, sys import gzip +import sqlite3 import paddle.v2 as paddle import numpy as np import functools -#lambdaRank is listwise learning to rank algorithm +#lambdaRank is listwise learning to rank model -def lambdaRank(feature_dim): - label = paddle.layer.data("label", paddle.data_type.integer_value_sequence(1)) - data = paddle.layer.data("data", paddle.data_type.dense_vector(feature_dim)) - # two hidden layers - hd1 = paddle.layer.fc( - name="/hidden_1", - input=data, - size=256, - act=paddle.activation.Tanh(), - param_attr=paddle.attr.Param(initial_std=0.01, name="hidden_w1")) - hd2 = paddle.layer.fc( - name="/hidden_2", - input=hd1, - size=256, - act=paddle.activation.Tanh(), - param_attr=paddle.attr.Param(initial_std=0.01, name="hidden_w2")) - output = paddle.layer.fc( - name="/output", - input=hd2, - size=1, - act=paddle.activation.Linear(), - param_attr=paddle.attr.Param(initial_std=0.01, name="output")) - cost = paddle.layer.lambda_cost(input=output, - score=label, - NDCG_num=10) - return cost, output - +def lambdaRank(input_dim): + label = paddle.layer.data("label", + paddle.data_type.dense_vector_sequence(1)) + data = paddle.layer.data("data", + paddle.data_type.dense_vector_sequence(input_dim)) + + # hidden layer + hd1 = paddle.layer.fc( + input=data, + size=10, + act=paddle.activation.Tanh(), + param_attr=paddle.attr.Param(initial_std=0.01)) + output = paddle.layer.fc( + input=hd1, + size=1, + act=paddle.activation.Linear(), + param_attr=paddle.attr.Param(initial_std=0.01)) + cost = paddle.layer.lambda_cost( + input=output, score=label, NDCG_num=6, max_sort_size=-1) + return cost, output + def train_lambdaRank(num_passes): - fill_default_train = functools.partial(paddle.dataset.mq2007.train, format="listwise") - fill_default_test = functools.partial(paddle.dataset.mq2007.test, format="listwise") - train_reader = paddle.batch( - paddle.reader.shuffle(fill_default_train, buf_size=1000), batch_size=1000) - test_reader = paddle.batch( - paddle.reader.shuffle(fill_default_test, buf_size=1000), batch_size=1000) + # listwise input sequence + fill_default_train = functools.partial( + paddle.dataset.mq2007.train, format="listwise") + fill_default_test = functools.partial( + paddle.dataset.mq2007.test, format="listwise") + train_reader = paddle.batch( + paddle.reader.shuffle(fill_default_train, buf_size=100), batch_size=32) + test_reader = paddle.batch( + paddle.reader.shuffle(fill_default_test, buf_size=100), batch_size=32) + + # mq2007 input_dim = 46, dense format + input_dim = 46 + cost, output = lambdaRank(input_dim) + parameters = paddle.parameters.create(cost) + + trainer = paddle.trainer.SGD( + cost=cost, + parameters=parameters, + update_equation=paddle.optimizer.Adam(learning_rate=1e-4)) - # mq2007 feature_dim = 46, dense format - # fc hidden_dim = 128 - feature_dim = 46 - cost, output = lambdaRank(feature_dim) - parameters = paddle.parameters.create(cost) - - trainer = paddle.trainer.SGD( - cost=cost, - parameters=parameters, - update_equation=paddle.optimizer.Adam(learning_rate=1e-4) - ) + # Define end batch and end pass event handler + def event_handler(event): + if isinstance(event, paddle.event.EndIteration): + print "Pass %d Batch %d Cost %.9f" % (event.pass_id, event.batch_id, + event.cost) + if isinstance(event, paddle.event.EndPass): + result = trainer.test(reader=test_reader, feeding=feeding) + print "\nTest with Pass %d, %s" % (event.pass_id, result.metrics) + with gzip.open("lambdaRank_params_%d.tar.gz" % (event.pass_id), + "w") as f: + parameters.to_tar(f) + + feeding = {"label": 0, "data": 1} + trainer.train( + reader=train_reader, + event_handler=event_handler, + feeding=feeding, + num_passes=num_passes) - # Define end batch and end pass event handler - def event_handler(event): - if isinstance(event, paddle.event.EndIteration): - if event.batch_id % 100 == 0: - print "Pass %d Batch %d Cost %.9f" % ( - event.pass_id, event.batch_id, event.cost) - else: - sys.stdout.write(".") - sys.stdout.flush() - if isinstance(event, paddle.event.EndPass): - result = trainer.test(reader=test_reader, feeding=feeding) - print "\nTest with Pass %d, %s" %(event.pass_id, result.metrics) - with gzip.open("lambdaRank_params_%d.tar.gz" %(event.pass_id), "w") as f: - parameters.to_tar(f) - feeding = {"label":0, - "data": 1} - trainer.train(reader=train_reader, - event_handler=event_handler, - feeding=feeding, - num_passes=num_passes) def lambdaRank_infer(pass_id): - print "Begin to Infer..." - feature_dim = 46 - output = lambdaRnak(feature_dim) - parameters = paddle.parameters.Parameters.from_tar(gzip.open("lambdaRank_params_%d.tar.gz" %(pass_id-1))) - infer_data = [] - infer_data_num = 1000 - for label, left, right in paddle.dataset.mq2007.test(): - infer_data.append(left) - if len(infer_data) == infer_data_num: - break - predicitons = paddle.infer(output_layer=output, - parameters=parameters, - input=infer_data) - for i, score in enumerate(predicitons): - print score + """ + lambdaRank model inference interface + parameters: + pass_id : inference model in pass_id + """ + print "Begin to Infer..." + input_dim = 46 + output = lambdaRank(input_dim) + parameters = paddle.parameters.Parameters.from_tar( + gzip.open("lambdaRank_params_%d.tar.gz" % (pass_id - 1))) + + infer_query_id = None + infer_data = [] + infer_data_num = 1000 + fill_default_test = functools.partial( + paddle.dataset.mq2007.test, format="listwise") + for label, querylist in fill_default_test(): + infer_data.append(querylist) + if len(infer_data) == infer_data_num: + break + predicitons = paddle.infer( + output_layer=output, parameters=parameters, input=infer_data) + for i, score in enumerate(predicitons): + print score + if __name__ == '__main__': - paddle.init(use_gpu=False, trainer_count=4) - train_lambdaRank(2) - lambdaRank_infer(pass_id=2) + paddle.init(use_gpu=False, trainer_count=4) + train_lambdaRank(100) + lambdaRank_infer(pass_id=2) diff --git a/ltr/lambdarank.jpg b/ltr/lambdarank.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5a0b0da90eb077d63608c004ff346e7a49a467db GIT binary patch literal 26644 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
Sz73J6M6lSEAq$hBjWsRM3BAvdgL=b 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 literal 0 HcmV?d00001 diff --git a/ltr/learningToRank.jpg b/ltr/learningToRank.jpg new file mode 100644 index 0000000000000000000000000000000000000000..54083d1143dff90a3c8ff06a77d3ea354fa621ef GIT binary patch literal 36496 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 QkG1D-HUs}-?V0|60Cbk!X8-^I literal 0 HcmV?d00001 diff --git a/ltr/metrics.py b/ltr/metrics.py new file mode 100644 index 00000000..bcf6e939 --- /dev/null +++ b/ltr/metrics.py @@ -0,0 +1,30 @@ +import numpy as np +import unittest + + +def ndcg(score_list): + def dcg(score_list): + n = len(score_list) + cost = .0 + for i in range(n): + cost += float(score_list[i]) / np.log((i + 1) + 1) + return cost + + dcg_cost = dcg(score_list) + score_ranking = sorted(score_list, reverse=True) + ideal_cost = dcg(score_ranking) + return dcg_cost / ideal_cost + + +class NdcgTest(unittest.TestCase): + def __init__(self): + pass + + def runcase(self): + a = [3, 2, 3, 0, 1, 2] + value = ndcg(a) + self.assertAlmostEqual(0.961, value, places=3) + + +if __name__ == '__main__': + unittest.main() diff --git a/ltr/ranknet.jpg b/ltr/ranknet.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9767cec96cd2386218df261cf4d78e288fecbb3d GIT binary patch literal 35950 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 F{vQsQ4aWcg literal 0 HcmV?d00001 diff --git a/ltr/ranknet.py b/ltr/ranknet.py index cf759309..e849d128 100644 --- a/ltr/ranknet.py +++ b/ltr/ranknet.py @@ -1,104 +1,135 @@ import os, sys import gzip +import functools import paddle.v2 as paddle import numpy as np +from metrics import ndcg # ranknet is the classic pairwise learning to rank algorithm # http://icml.cc/2015/wp-content/uploads/2015/06/icml_ranking.pdf + def half_ranknet(name_prefix, input_dim): + """ + parameter in same name will be shared in paddle framework, + these parameters in ranknet can be used in shared state, e.g. left network and right network + shared parameters in detail + https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/api.md + """ + # data layer + data = paddle.layer.data(name_prefix + "/data", + paddle.data_type.dense_vector(input_dim)) - data = paddle.layer.data(name_prefix+"/data", paddle.data_type.dense_vector(input_dim)) - - # two hidden layers - hd1 = paddle.layer.fc( - name=name_prefix+"/hidden_1", - input=data, - size=32, - act=paddle.activation.Tanh(), - param_attr=paddle.attr.Param(initial_std=0.01, name="hidden_w1")) - hd2 = paddle.layer.fc( - name=name_prefix+"/hidden_2", - input=hd1, - size=16, - act=paddle.activation.Tanh(), - param_attr=paddle.attr.Param(initial_std=0.01, name="hidden_w2")) - output = paddle.layer.fc( - name=name_prefix+"/output", - input=hd2, - size=1, - act=paddle.activation.Linear(), - param_attr=paddle.attr.Param(initial_std=0.01, name="output")) - return output + # hidden layer + hd1 = paddle.layer.fc( + input=data, + size=10, + act=paddle.activation.Tanh(), + param_attr=paddle.attr.Param(initial_std=0.01, name="hidden_w1")) + # fully connect layer/ output layer + output = paddle.layer.fc( + input=hd1, + size=1, + act=paddle.activation.Linear(), + param_attr=paddle.attr.Param(initial_std=0.01, name="output")) + return output def ranknet(input_dim): - label = paddle.layer.data("label", paddle.data_type.integer_value(1)) - output_left = half_ranknet("left", input_dim) - output_right = half_ranknet("right", input_dim) - cost = paddle.layer.rank_cost(name="cost", left=output_left, right=output_right, label=label) - return cost + # label layer + label = paddle.layer.data("label", paddle.data_type.integer_value(1)) + + # reuse the parameter in half_ranknet + output_left = half_ranknet("left", input_dim) + output_right = half_ranknet("right", input_dim) + + evaluator = paddle.evaluator.auc(input=output_left, label=label) + # rankcost layer + cost = paddle.layer.rank_cost( + name="cost", left=output_left, right=output_right, label=label) + return cost def train_ranknet(num_passes): - train_reader = paddle.batch( - paddle.reader.shuffle(paddle.dataset.mq2007.train, buf_size=1000), batch_size=1000) - test_reader = paddle.batch( - paddle.reader.shuffle(paddle.dataset.mq2007.test, buf_size=1000), batch_size=1000) - - # mq2007 feature_dim = 46, dense format - # fc hidden_dim = 128 - feature_dim = 46 - cost = ranknet(feature_dim) - parameters = paddle.parameters.create(cost) - - trainer = paddle.trainer.SGD( - cost=cost, - parameters=parameters, - update_equation=paddle.optimizer.Adam(learning_rate=2e-4) - ) - - # Define end batch and end pass event handler - def event_handler(event): - if isinstance(event, paddle.event.EndIteration): - if event.batch_id % 100 == 0: - print "Pass %d Batch %d Cost %.9f" % ( - event.pass_id, event.batch_id, event.cost) - else: - sys.stdout.write(".") - sys.stdout.flush() - if isinstance(event, paddle.event.EndPass): - result = trainer.test(reader=test_reader, feeding=feeding) - print "\nTest with Pass %d, %s" %(event.pass_id, result.metrics) - with gzip.open("ranknet_params_%d.tar.gz" %(event.pass_id), "w") as f: - parameters.to_tar(f) - feeding = {"label":0, - "left/data" :1, - "right/data":2} - trainer.train(reader=train_reader, - event_handler=event_handler, - feeding=feeding, - num_passes=num_passes) + train_reader = paddle.batch( + paddle.reader.shuffle(paddle.dataset.mq2007.train, buf_size=100), + batch_size=100) + test_reader = paddle.batch( + paddle.reader.buffered(paddle.dataset.mq2007.test, size=100), + batch_size=100) + + # mq2007 feature_dim = 46, dense format + # fc hidden_dim = 128 + feature_dim = 46 + cost = ranknet(feature_dim) + parameters = paddle.parameters.create(cost) + + trainer = paddle.trainer.SGD( + cost=cost, + parameters=parameters, + update_equation=paddle.optimizer.Adam(learning_rate=2e-4)) + + # Define the input data order + feeding = {"label": 0, "left/data": 1, "right/data": 2} + + # Define end batch and end pass event handler + def event_handler(event): + if isinstance(event, paddle.event.EndIteration): + if event.batch_id % 100 == 0: + print "Pass %d Batch %d Cost %.9f" % ( + event.pass_id, event.batch_id, event.cost) + else: + sys.stdout.write(".") + sys.stdout.flush() + if isinstance(event, paddle.event.EndPass): + result = trainer.test(reader=test_reader, feeding=feeding) + print "\nTest with Pass %d, %s" % (event.pass_id, result.metrics) + with gzip.open("ranknet_params_%d.tar.gz" % (event.pass_id), + "w") as f: + parameters.to_tar(f) + + trainer.train( + reader=train_reader, + event_handler=event_handler, + feeding=feeding, + num_passes=num_passes) + def ranknet_infer(pass_id): - print "Begin to Infer..." - feature_dim = 46 - output = half_ranknet("left", feature_dim) - parameters = paddle.parameters.Parameters.from_tar(gzip.open("ranknet_params_%d.tar.gz" %(pass_id-1))) - infer_data = [] - infer_data_num = 1000 - for label, left, right in paddle.dataset.mq2007.test(): - infer_data.append(left) - if len(infer_data) == infer_data_num: - break - predicitons = paddle.infer(output_layer=output, - parameters=parameters, - input=infer_data) - for i, score in enumerate(predicitons): - print score - + """ + load the trained model. And predict with plain txt input + """ + print "Begin to Infer..." + feature_dim = 46 + + # we just need half_ranknet to predict a rank score, which can be used in sort documents + output = half_ranknet("left", feature_dim) + parameters = paddle.parameters.Parameters.from_tar( + gzip.open("ranknet_params_%d.tar.gz" % (pass_id - 1))) + + # load data of same query and relevance documents, need ranknet to rank these candidates + infer_query_id = None + infer_data = [] + infer_score_list = [] + infer_data_num = 1000 + + # convert to mq2007 built-in data format + # + plain_txt_test = functools.partial( + paddle.dataset.mq2007.test, format="plain_txt") + + for query_id, relevance_score, feature_vector in plain_txt_test(): + if infer_query_id == None: + infer_query_id = query_id + elif infer_query_id != query_id: + break + infer_data.append(feature_vector) + predicitons = paddle.infer( + output_layer=output, parameters=parameters, input=infer_data) + if __name__ == '__main__': - paddle.init(use_gpu=False, trainer_count=4) - train_ranknet(2) - ranknet_infer(pass_id=2) + paddle.init(use_gpu=False, trainer_count=4) + pass_num = 10 + train_ranknet(pass_num) + ranknet_infer(pass_id=pass_num - 1) diff --git a/ltr/search-engine-example.png b/ltr/search-engine-example.png new file mode 100644 index 0000000000000000000000000000000000000000..36386085f45794f51d5cae79b3f9dd6ba004ded8 GIT binary patch literal 81260 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 literal 0 HcmV?d00001 -- GitLab