Determinantal Point Process:机器学习中行列式的妙用

Determinantal Point Process:机器学习中行列式的妙用_第1张图片

©PaperWeekly 原创 · 作者 | Yunpeng Tai

主页 | https://yunpengtai.top/

在机器学习中,我们通常会面临一个问题:给定一个集合 ,从中寻找 个样本构成子集 ,尽量使得子集的质量高同时多样性好。比如在推荐系统中,我们就希望给用户推荐的东西尽可能的有质量,同时具有差异性。

而使得采样的子集尽可能具备多样性便是行列式点过程(Determinantal Point Process)大展身手的地方,俗称 DPP。

eda7ab6083561af624f94d977404c53f.png

边缘分布

首先引入 DPP 的边缘分布定义,当我们某次采样出子集,「包括」  的概率:

7b4dea1dd349760332190d2e62cbc65c.png

是核矩阵(Kernel Matrix),即:

2fd8053ec64578dfb55c2062bc784320.png

是由 中元素构成的子矩阵,举个例子,假如 ,那么:

aad2bd3762b4fb94a5e7e2a419f85724.png

当 越大,则 同时出现在 的概率就越小,从这个角度想,核函数应该是呈现出某种相似性。

从正定性出发,严格的定义如下是:

举个例子:

cad1ebe042cff6f68882f997a83fcc3b.png

其特征值为 ,不满足 ,即不是半正定矩阵。

6b6e1a628062798a61da85e411250f0e.png

L-Ensemble

然而,上面边缘定义只是告诉我们采样时,某个子集被「包括」的概率,并非就是这个子集,而这个问题可以通过 L-Ensemble 去解

0e889565ed7c5c481d54aa99681fd616.png

这里的 省略了下标,跟上面的 一样,是跟 元素相关的子矩阵。 矩阵的核函数是内积是 ,。

Determinantal Point Process:机器学习中行列式的妙用_第2张图片

注意,这里指的不是概率,而是说概率「正比于」 矩阵的行列式,那么如何计算概率呢?也就是说我们得计算一个归一化常数(normalization constant),可以类比抛硬币,我们得去求总的抛起次数,除以它才能得到概率。

引入下述定理:

f816d08d8b2e1200ae9ae90c4fef9c62.png

其中 是将单位矩阵中与 相关元素全部置零,举个例子,当 时:

Determinantal Point Process:机器学习中行列式的妙用_第3张图片

那么如何求归一化常数呢,即将 ,当 为空集时,便包括了所有的情况,即:

5b3b36ce6e85ee7f94464acbc970c83f.png

另外,L-Emsemble 的  对应关系如下:

Determinantal Point Process:机器学习中行列式的妙用_第4张图片

7494a104b7fe4f3f15c921a9f8338f7b.png

直观解释

那么,行列式与多样性的直观解释是什么呢?

多样性和相似性的意思正好相反,通常我们会定义相似性为两个向量之间做点积,即为 ,直观上看,两向量夹角的余弦值 越大,相似性越高,反过来看,当 最小即为两者相似性最差,多样性最好。显然,当两向量正交时多样性最好。

那么,对于一个子集 而言,该如何定义它的多样性呢?不难想出,可以通过线性无关向量的数量来定义,若两两都互不线性相关,此时的子集的多样性是最好的。直观上可以转换为构成的超平行体的体积,下方为 时的示意图。

Determinantal Point Process:机器学习中行列式的妙用_第5张图片

为什么呢?可以拿平行六面体为例,若其中一个向量与其他向量线性相关,那么则会坍缩成一个平面,构不成平行六面体

只有当所有向量两两都线性无关时,构成的超平行体体积最大,即多样性最好。

而行列式可以表示体积,下式中 代表体积(volume),此时 , 为方阵

e5a41159e4e72e47e490f244ee13c7d2.png

也就是说,我们可以通过行列式的大小来定义多样性。

那么, 的行列式是否也跟体积有关呢?答案是肯定的:

a3a27c5c6db613c4a3f42afaa69d03fe.png

接下来证明这一结论:

由于 ,因为 维空间至多存在 个两两线性无关的向量,那么肯定存在一个 维子空间 ,存在正交矩阵 ,对向量 进行旋转,使得 都落在子空间  上。不妨设 的基底是前 个标准正交基,那么:

Determinantal Point Process:机器学习中行列式的妙用_第6张图片

, 一共有 个,因为用 的基底向量表示,后面只能为,将 当作 的列,就有:

930360cbbd1a043ab387e6764e9621bf.png

显然, 与 两者体积相等。

9c0b7d21aa3e9027109b145c8e6558c8.png

那么:

1ceac0aa56ad547c16e08e47e10f5466.png

由于对超平面体进行旋转不改变其体积(注意,这里是旋转而不是一般的线性变换,一般的线性变换不具备该性质)。

7ede1d1a332fe926ef64d50efa97a500.png

那么:

4704e7748dcca2dbb62f54692faf1487.png

又因为 正交矩阵,即 ,那么:

e1b13d1b67bb2a42905eee6483b26218.png

所以:

ed91a2c980686ee5fb015817991976d5.png

从 L-Emsemble 角度看,被采样的概率正比于构成的超平面体的体积,即两两之间线性无关更容易被采样出。

484d7f3d2e2dfc947e6a5c183c77a753.png

Demo

接下来我们用例子来看一下是否 DPP 能够采样出更有多样性的子集。

from torch import det, eye
from transformers import set_seed
from transformers import BertModel, BertTokenizer

set_seed(42)
pretrain_path = "fabriceyhc/bert-base-uncased-imdb"
model = BertModel.from_pretrained(pretrain_path).cuda()

tk = BertTokenizer.from_pretrained(pretrain_path)
input_text = [
    "I am happy because the weather is extremely good!",
    "I hate the bad weather",
    "The weather is extremely good!",
]
inputs = tk(input_text, max_length=128, return_tensors="pt", truncation=True, padding=True)
inputs = {k: v.cuda() for k, v in inputs.items()}
outputs = model(**inputs).pooler_output.T
vtv = outputs.T @ outputs
group_12 = vtv[:2][:, [0, 1]]
I = eye(2).cuda()
p_12 = det(group_12) / det(group_12 + I)

group_13 = vtv[[0, 2]][:, [0, 2]]
p_13 = det(group_13) / det(group_13 + I)

print('采样到第一个和第二个的概率:%f'%p_12)
print('采样到第一个和第三个的概率:%f'%p_13)

# 采样到第一个和第二个的概率:0.983567
# 采样到第一个和第三个的概率:0.923823

然而,对于一个大小为 的集合,一共有 种组合,如何快速地进行 DPP 的计算以及如何最快找到大小为 的多样性最大的子集是比较困难的,留给下文。

faa239cbb66b584339a3474aeccf8070.png

问题

先规定一些术语:记选中元素构成的集合为 ,未选中构成的元素记为 , 是核矩阵(核函数是内积), 是由集合 的元素构成的子矩阵。

在上文中我们提到在大小为 的集合里去挑选 个物品构成集合 ,使得 最大便是我们的目标,然而,怎么去里面挑选 却是 NP-Hard 问题,为此,Chen et al., 2018 提出了一篇比较巧妙的贪婪算法作为近似解,并且整个算法的复杂仅有 。

861ffcc28ea38da202fb07dcfb488cc2.png

暴力求解

我们人为规定了要选择 个,这相当于是一种前验分布,那么 k-DPP 其实就是最大化后验概率(MAP)的一种,每一步的目标就是选择会让新矩阵的行列式变得最大的元素。

1f3a1cdfd4696c33976c25be18cfe9fd.png

对于一个 的方阵而言,求它的行列式需要 (每一轮消元的复杂度是 ,而要进行 轮消元)。

这里的话,每次要对 所有的元素求一次行列式,而行列式的为 ,同时需要选 个,复杂度变为了 ,即为 ,暴力求解的话复杂度很大,此时原作者便提出了利用 Cholesky 分解的方式来进行求解,巧妙地将复杂度降到了 。

2496953e6da56904c57d0691a0fd05a3.png

Cholesky分解

是对称半正定矩阵,证明如下:

a1e25664f4fd4b942604a9c759f71a42.png

那么 存在 Cholesky 分解,即 ,这里的 是大小为 的下三角矩阵, 比 多了一行和一列,即为:

6f3605b2458378f057675f876f9b5aa3.png

而这里默认每个向量是经过归一化的,即 ,那么 的 Cholesky 分解即为下式,其中 :

Determinantal Point Process:机器学习中行列式的妙用_第7张图片

结合上面两式:

3fec45c4004ddee82ca89921f1178efe.png

可得:

aad1ebe5e8c9e93e57f0fba31c512c3a.png

那么:

896eb0c8b4bf4ef674cdbb65baf2c37e.png

这样我们一开始的优化目标就可以简化为:

3a5d989bb045306e9d9092e31d63d212.png

接下来,当我们得到 时,便可以算出 ,那么添加 之后的新集合 的 Cholesky 分解便可以求得:

6ed15f2d43211d97200cbfd6992dbacb.png

ec302b873bce8b177b9f5e1c30ea5cbb.png

增量更新

接下来便是重头戏,这一轮我们已经得到了最好的 了,下一轮我们怎么求出最大的 呢?

可以利用之前求出的 来获取当前的 ,这便是论文的核心:增量更新

在我们选择了 后, 多了一个元素,不妨记 ,回忆上面的式子:

4a9ae34052468ad4caf341cd58c53fc8.png

也就是说,其中 就是第 个元素与集合 对应向量做内积的结果。

3d6967a64f2a4ce1dfc03b47cea348c1.png

那么,类比一下, 是 的 Cholesky 分解。

Determinantal Point Process:机器学习中行列式的妙用_第8张图片

继而:

5f673706d3f27defc93f6b8cff5a5d6d.png

求出 之后,我们便可以求出 :

568699979663476868dc51d1ab0c5b4b.png

b201e1dce963a69e02e4ded7d7a97eb2.png

流程

Determinantal Point Process:机器学习中行列式的妙用_第9张图片

那我们来分析一下复杂度,每选一个 需要进行 次操作,而 ,也就是 ,得进行 次迭代,那么总的复杂度即为 ,由 降到 ,是不错的进步。

a193b1d2d9ce68649e83d3ec065d606e.png

代码

熟悉了整个流程之后,代码想必也是呼之欲出了。

import math
import numpy as np

def fast_map_dpp(kernel_matrix, max_length):
    cis = np.zeros((max_length, kernel_matrix.shape[0]))
    di2s = np.copy(np.diag(kernel_matrix))
    selected = np.argmax(di2s)
    selected_items = [selected]
    while len(selected_items) < max_length:
        idx = len(selected_items) - 1
        ci_optimal = cis[:idx, selected]
        di_optimal = math.sqrt(di2s[selected])
        elements = kernel_matrix[selected, :]
        eis = (elements - ci_optimal @ cis[:idx, :]) / di_optimal
        cis[idx, :] = eis
        di2s -= np.square(eis)
        di2s[selected] = -np.inf
        selected = np.argmax(di2s)
        selected_items.append(selected)
    return selected_items

这里实现比较有趣的点就是,尽管伪代码中是 ,这里其实是全部算了,但他对已选的进行了后处理,置之为 。

接下来我们实操一下,从句子对匹配 BQ Corpus(Bank Question Corpus)拿出一条来看一下效果,首先是将其用预训练模型转换为表征向量,接着进行归一化操作,为了更好地看出 DPP 的效果,我们先用最大化内积来召回 50 个样本,再用 DPP 从这里召回 10 个具有多样性的样本:

原句:我现在申请微粒货?

['我现在申请微粒货?', '申请微贷粒', '申请微贷粒', '我想申请微粒贷', '可以么想申请微粒贷', '微粒貸申请', '微粒貸申请', '如何申请微粒', '我现在需要申请', '我可以申请微粒贷吗', '怎么申请微粒货', '微粒貸申请', '如何申请微粒', '我可以申请微粒贷吗', '什么情况下才能申请微粒', '我要求申请', '开通微粒货', '开通微粒貨', '开通微粒货', '可以申请开通吗', '开通微粒货', '开通微粒货', '怎么申请微粒货', '申请贷款', '如何申请微粒贷', '怎么申请微粒货', '开通微粒貨', '如何申请微粒', '想办理微粒贷业务', '申请贷款', '可以申请开通吗', '我要微粒贷', '我要微粒贷', '可以么想申请微粒贷', '开通微米粒', '想开通', '我要微粒贷', '如何申请微粒', '想开通', '开通微粒貨', '开通粒微贷', '何时才能申请啊', '现在想获取资格', '怎么申请微粒货', '开通申请', '开通', '开通', '你好我申请借款', '开通微']

可以看到有不少重复且意思一样的样本:

接着看 DPP 的效果:

['我现在申请微粒货?', '开通', '何时才能申请啊', '怎么申请微粒货', '你好我申请借款', '现在想获取资格', '我可以申请微粒贷吗', '我要微粒贷', '微粒貸申请', '什么情况下才能申请微粒']

可以发现里面没有重复的情况,而且语义具备多样性,而值得注意的是,此时就有一些和我们的原句意思不匹配的情况,在应用时可以自定义新的 kernel,让它同时注意相似性和多样性;或者可以对 DPP 的样本进行后处理等。

8d4d0c8a13cc2a5fcaf10b93f3711783.png

Sliding Window

当 相当大的时候,就会有相似的样本开始出现,即超平行体会开始坍缩,不妨我们将 缩小成一个滑动窗口 ,我们仅仅需要保证窗口内的样本具备多样性即可,即:

a3763614c7c1708824c3cf7d90ca67e0.png

推荐系统中有短序推荐(Short Sequence Recommendation)的说法,推荐的时候只考虑用户短期内的一些行为,而长序推荐会考虑一个较长时间跨度来进行推荐。

Window size 的选择也是比较重要的,不妨看一些 demo:

Determinantal Point Process:机器学习中行列式的妙用_第10张图片

如果我们的目的是为了通过 Sliding Window 获取与直接 DPP 召回不一样的结果,窗口的大小要适当地小一些,然而小了导致看的范围小了,很有可能最后结果出现重复的情况,最好是将窗口设置到召回样本数目的 。

同时,为了防止样本重复,可以多召回一些,比较直觉的做法可以再加上一个 window 的大小,然后去重:

w/o window
['开通', '怎么申请微粒货', '何时才能申请啊', '现在想获取资格', '我要微粒贷', '微粒貸申请', '我可以申请微粒贷吗', '什么情况下才能申请微粒', '你好我申请借款', '我现在申请微粒货?']
w/ window
['开通', '开通申请', '怎么申请微粒货', '何时才能申请啊', '现在想获取资格', '我要微粒贷', '我可以申请微粒贷吗', '可以申请开通吗', '如何申请微粒', '我现在申请微粒货?']

可以看到会有 3 个不一样的样本,还是比较有效的。

更多阅读

Determinantal Point Process:机器学习中行列式的妙用_第11张图片

Determinantal Point Process:机器学习中行列式的妙用_第12张图片

Determinantal Point Process:机器学习中行列式的妙用_第13张图片

51436fb6127f719e1ee63df62104a977.gif

#投 稿 通 道#

 让你的文字被更多人看到 

如何才能让更多的优质内容以更短路径到达读者群体,缩短读者寻找优质内容的成本呢?答案就是:你不认识的人。

总有一些你不认识的人,知道你想知道的东西。PaperWeekly 或许可以成为一座桥梁,促使不同背景、不同方向的学者和学术灵感相互碰撞,迸发出更多的可能性。 

PaperWeekly 鼓励高校实验室或个人,在我们的平台上分享各类优质内容,可以是最新论文解读,也可以是学术热点剖析科研心得竞赛经验讲解等。我们的目的只有一个,让知识真正流动起来。

 稿件基本要求:

• 文章确系个人原创作品,未曾在公开渠道发表,如为其他平台已发表或待发表的文章,请明确标注 

• 稿件建议以 markdown 格式撰写,文中配图以附件形式发送,要求图片清晰,无版权问题

• PaperWeekly 尊重原作者署名权,并将为每篇被采纳的原创首发稿件,提供业内具有竞争力稿酬,具体依据文章阅读量和文章质量阶梯制结算

 投稿通道:

• 投稿邮箱:[email protected] 

• 来稿请备注即时联系方式(微信),以便我们在稿件选用的第一时间联系作者

• 您也可以直接添加小编微信(pwbot02)快速投稿,备注:姓名-投稿

Determinantal Point Process:机器学习中行列式的妙用_第14张图片

△长按添加PaperWeekly小编

现在,在「知乎」也能找到我们了

进入知乎首页搜索「PaperWeekly」

点击「关注」订阅我们的专栏吧

·

·

c3152ca55639671da230d69ac146222f.jpeg

你可能感兴趣的:(Determinantal Point Process:机器学习中行列式的妙用)