我必须解决排名机器学习问题。首先,我已经成功地应用了逐点排名方法。
现在,我正在玩成对排名算法。我已经创建了成对概率(即项目 i 高于项目 j 的概率),但我不确定如何将其转换为排名。
对于历史数据(假设这些是查询),我有他们的成对概率和实际排名(理想排名)。我想要一个能够为新查询提供排名的解决方案(即理想的排名就是我在这里寻找的)。
任何 python 包至少部分具有我正在寻找的功能?
编辑:我有所有可能的 i 和 j 对的成对概率。
我必须解决排名机器学习问题。首先,我已经成功地应用了逐点排名方法。
现在,我正在玩成对排名算法。我已经创建了成对概率(即项目 i 高于项目 j 的概率),但我不确定如何将其转换为排名。
对于历史数据(假设这些是查询),我有他们的成对概率和实际排名(理想排名)。我想要一个能够为新查询提供排名的解决方案(即理想的排名就是我在这里寻找的)。
任何 python 包至少部分具有我正在寻找的功能?
编辑:我有所有可能的 i 和 j 对的成对概率。
当您有成对比较概率而不是二元结果时,可以轻松地将诸如 Bradley 和 Terry 的成对比较模型扩展到您的案例。
让 是项目的数量,并让 是查询的概率 比查询好 . 然后,Bradley-Terry 参数的对数似然 给定概率 是
这可以重新参数化为凸函数,并且可以通过许多凸优化方法之一找到最大似然参数。
这是一个简单的 Python 算法,它将使用最小化最大化方法找到 ML 估计。
import numpy as np
def mle(pmat, max_iter=100):
n = pmat.shape[0]
wins = np.sum(pmat, axis=0)
params = np.ones(n, dtype=float)
for _ in range(max_iter):
tiled = np.tile(params, (n, 1))
combined = 1.0 / (tiled + tiled.T)
np.fill_diagonal(combined, 0)
nxt = wins / np.sum(combined, axis=0)
nxt = nxt / np.mean(nxt)
if np.linalg.norm(nxt - params, ord=np.inf) < 1e-6:
return nxt
params = nxt
raise RuntimeError('did not converge')
示例用法:
import itertools
# Generating pairwise probability matrix.
pmat = np.zeros((10, 10))
for i, j in itertools.permutations(range(10), r=2):
pmat[i][j] = (j + 1) / (i + j + 2)
# Estimating Bradley-Terry model parameters.
params = mle(pmat)
# Ranking (worst to best).
ranking = np.argsort(params)
资料来源:我是用于在各种统计比较模型中进行参数推断的 Python 库choix的作者。
我相信你可以在 David Barber 的《贝叶斯推理与机器学习》一书中找到一些资料。查看第 22 章的“成对比较排名”。这本书有一个 MATLAB 工具箱,其中实现了 Rasch 模型函数。Bradley-Terry-Luce 等排名模型是对 Rasch 模型的修改,所以我相信这段代码可以为您提供一个良好的开端。例程很小,因此从 MATLAB 转换到 Python 不会很困难。
一种选择是从成对概率创建有向无环图 (DAG),其中节点是项目,连接的方向由成对概率驱动(如果 ,则连接从项目 A 到项目 B p(A > B) > 0.5,否则连接从 B 到 A),然后计算图的拓扑排序。这将为您提供一系列节点,这些节点尊重从概率派生的成对排序。
实现拓扑排序的python代码可以从算法中实现,但也有像toposort这样的python包。
使用旨在支持排名的排名框架,例如Bradley-Terry 模型。另请参阅Elo 排名和所有关于成对比较的一般统计理论。