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

news2024/11/6 3:02:58

a19503b3282ed11ffd749ceef847135e.gif

©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

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

9f82c4024cd6e033686909732edfedb4.png

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

引入下述定理:

f816d08d8b2e1200ae9ae90c4fef9c62.png

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

64e96abb5c1606217210c855330c5890.png

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

5b3b36ce6e85ee7f94464acbc970c83f.png

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

b1dc156c1286e0def2b96f3dfef24fd4.png

7494a104b7fe4f3f15c921a9f8338f7b.png

直观解释

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

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

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

7ba13733c51cde3c891de3091be77d60.png

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

adafaec44742a4785ffb5e82f02f914b.gif

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

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

e5a41159e4e72e47e490f244ee13c7d2.png

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

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

a3a27c5c6db613c4a3f42afaa69d03fe.png

接下来证明这一结论:

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

41ebf8f00b6ee656be4ec53ab481525d.png

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

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 分解即为下式,其中 :

45b6031a1a3c6a368ba547df94a6c35d.png

结合上面两式:

3fec45c4004ddee82ca89921f1178efe.png

可得:

aad1ebe5e8c9e93e57f0fba31c512c3a.png

那么:

896eb0c8b4bf4ef674cdbb65baf2c37e.png

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

3a5d989bb045306e9d9092e31d63d212.png

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

6ed15f2d43211d97200cbfd6992dbacb.png

ec302b873bce8b177b9f5e1c30ea5cbb.png

增量更新

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

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

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

4a9ae34052468ad4caf341cd58c53fc8.png

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

3d6967a64f2a4ce1dfc03b47cea348c1.png

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

c25456335624c5a1a2a635fcdcae0715.png

继而:

5f673706d3f27defc93f6b8cff5a5d6d.png

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

568699979663476868dc51d1ab0c5b4b.png

b201e1dce963a69e02e4ded7d7a97eb2.png

流程

3f87b4741c0cf93bb8dc3a337a584791.png

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

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:

5873e1b628d7ecd0de33aa249bacb6c1.png

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

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

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

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

更多阅读

e553495334b12df8213dc6f598b5299d.png

37d19630fb1dddc70ebe05785df7d2cc.png

128e89e0d132990b6eeca1e67d4b5d8c.png

51436fb6127f719e1ee63df62104a977.gif

#投 稿 通 道#

 让你的文字被更多人看到 

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

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

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

📝 稿件基本要求:

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

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

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

📬 投稿通道:

• 投稿邮箱:hr@paperweekly.site 

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

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

3afebc05984edec5f033ae610bbe7003.png

△长按添加PaperWeekly小编

🔍

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

进入知乎首页搜索「PaperWeekly」

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

·

·

c3152ca55639671da230d69ac146222f.jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/807323.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI绘画StableDiffusion实操教程:可爱头像奶茶小女孩(附高清图片)

本教程收集于&#xff1a;AIGC从入门到精通教程汇总 今天继续分享AI绘画实操教程&#xff0c;如何用lora包生成超可爱头像奶茶小女孩 放大高清图已放到教程包内&#xff0c;需要的可以自取。 欢迎来到我们这篇特别的文章——《AI绘画StableDiffusion实操教程&#xff1a;可爱…

element 时间插件 placement 报错

只需一个简单配置一下 align"center" 就不会再报错了&#xff0c;不需要升级element的版本

Vue 常用指令 v-on 自定义参数,事件修饰符

自定义参数就是可以在触发事件的时候传入自定义的值。 文本框&#xff0c;绑定了一个按钮事件&#xff0c;对应的逻辑是sayhi&#xff0c;现在无论按下什么按钮都会触发这个sayhi。但是实际上不是所有的按钮都会触发&#xff0c;只会限定某一些按钮&#xff0c;最常见的按钮就…

【C语言项目】多臂井径电子测井成像项目(一)

目录 1、目的和意义2、本章概述3、串口R2324、OpenGL5、开发环境6、环境配置6.1、VS安装OpenGL6.2、虚拟串口生成工具 7、成品速览参考文献 1、目的和意义 本项目为获取矿藏地层的油气当量和及时精确地测量含油、含气层的压力及温度值的需求&#xff0c;辅助生产管理人员完成对…

【Nginx】keepalived安装配置

环境说明 Centos 7版本 主机名 IP地址 其他 nginx 192.168.10.150 主 nginx-2 192.168.10.151 备 配置 主-192.168.10.150 [rootnginx ~]# yum install keepalived [rootnginx ~]# vim /etc/keepalived/keepalived.conf ! Configuration File for keepalived #定义全…

【2023Java 面试题全集】实用、全面、系统,助你一路通关!

前两个月&#xff0c;公司 java 岗位面了 50候选人&#xff0c;面试下来发现几类过不了的情况&#xff0c;分享大家防止踩坑&#xff1a; 新技术倒是掌握得挺多&#xff0c;基础的却一塌糊涂。 工作多年&#xff0c;从未学习过工作之外的技术栈&#xff0c;也没有对技术有任何…

Golang操作阿里云OSS上传文件

为什么要使用OSS&#xff1f;应用场景是什么&#xff1f; 最近在开发考试系统&#xff0c;里面需要上传课件&#xff0c;课件包括pdf&#xff0c;map等等各种类型的文件&#xff0c;这些文件不能像图片一样&#xff0c;直接上传到项目目录下面&#xff0c;需要单独存放&#x…

iOS开发-下拉刷新动画loading旋转指示器动画效果

iOS开发-下拉刷新动画loading旋转指示器动画效果 之前开发中实现下拉刷新动画loading旋转指示器动画效果 一、效果图 二、基础动画 CABasicAnimation类的使用方式就是基本的关键帧动画。 所谓关键帧动画&#xff0c;就是将Layer的属性作为KeyPath来注册&#xff0c;指定动画…

尚医通10:科室排班日期+科室排班详细数据+搭建平台用户系统前端环境

内容介绍 1、查看科室排班日期统计数据 2、查看科室排班详细数据 3、搭建平台用户系统前端环境 4、首页静态数据整合 5、首页数据显示接口 6、首页数据显示前端 查看科室排班日期统计数据 1确认需求 2、实现接口 1&#xff09;分析接口 *参数&#xff1a;page、limit、h…

C语言基础入门详解一

前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下"通俗易懂&#xff0c;风趣幽默"&#xff0c;感觉非常有意思,忍不住分享一下给大家。 &#x1f449;点击跳转到教程 前言&#xff1a; 初识C语言 //#include 相当于java的import,stdio全称&#xff1a;st…

秒级体验本地调试远程 k8s 中的服务

点击上方蓝色字体&#xff0c;选择“设为星标” 回复”云原生“获取基础架构实践 背景 在这个以k8s为云os的时代&#xff0c;程序员在日常的开发过程中&#xff0c;肯定会遇到各种问题&#xff0c;比如&#xff1a;本地开发完&#xff0c;需要部署到远程k8s集群&#xff0c;本地…

【雕爷学编程】Arduino动手做(175)---机智云ESP8266开发板模块5

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

区间预测 | MATLAB实现VAR向量自回归时间序列区间预测

区间预测 | MATLAB实现VAR向量自回归时间序列区间预测 目录 区间预测 | MATLAB实现VAR向量自回归时间序列区间预测预测效果基本介绍程序设计参考资料预测效果 基本介绍 区间预测 | MATLAB实现VAR向量自回归时间序列区间预测 VAR(Vector Autoregression)模型是一种广泛应用于时…

pytest 自定义HOOK函数

除了系统提过的HOOK函数外&#xff0c;也可以通过自定义HOOK的方式实现想要的功能。 首先创建一个py文件&#xff0c;里面定义自己的HOOK函数&#xff0c;主要pytest里面的hook函数必须以pytest开头。 #myhook.pydef pytest_myhook(user):"""自定义HOOK函数&q…

SpringBoot项目部署(前后端分离、Linux部署项目)

一、架构 部署环境说明&#xff1a; 192.168.122.100(服务器A)&#xff1a; Nginx&#xff1a;部署前端项目、配置反向代理 Mysql&#xff1a;主从复制结构中的主库 192.168.122.131 (服务器B)&#xff1a; jdk: 运行Java项目 git:版本控制工具 (从gitee中拉取源码) maven:…

No104.精选前端面试题,享受每天的挑战和学习(小米)

文章目录 聊一下vue和react的区别react生命周期有哪些hooks解决了什么问题小程序跳转传参怎么传附录&#xff1a;「简历必备」前后端实战项目&#xff08;推荐&#xff1a;⭐️⭐️⭐️⭐️⭐️&#xff09; &#x1f4c8;「作者简介」&#xff1a;前端开发工程师 | 蓝桥云课签…

CenOS设置启动级别

背景知识 init一共分为7个级别&#xff0c;这7个级别的所代表的含义如下 0&#xff1a;停机或者关机&#xff08;千万不能将initdefault设置为0&#xff09;1&#xff1a;单用户模式&#xff0c;只root用户进行维护2&#xff1a;多用户模式&#xff0c;不能使用NFS(Net File S…

Banana Pi BPI-CM4 评测(计算模块 4),更快性能,旨在替换树莓派CM4

如果您正在寻找可靠的单板计算机来提升您的下一个项目&#xff0c;但无法找到满足您需求的 Raspberry Pi&#xff0c;请看看我是否可以提供帮助。在这篇详细的评论中&#xff0c;我将向您介绍 Banana Pi CM4&#xff0c;这是一款适用于各种任务的多功能且强大的解决方案。从经验…

Blazor前后端框架Known-V1.2.8

V1.2.8 Known是基于C#和Blazor开发的前后端分离快速开发框架&#xff0c;开箱即用&#xff0c;跨平台&#xff0c;一处代码&#xff0c;多处运行。 Gitee&#xff1a; https://gitee.com/known/KnownGithub&#xff1a;https://github.com/known/Known 概述 基于C#和Blazor…

太强了~ 这份《23 种设计模式加强版》宝典,阿里 P8 都得细细研究

说在前面的话 Java 作为老牌纯正的编程语言&#xff0c;在规范性上有着天然优势。因此本版的设计模式讲解全部用 Java 语言来描述&#xff0c;并针对 Java 语言的特性对讲解内容做了相当大的改动。 不知道大家是否听过编程界的一段话&#xff1a;掌握设计模式相当于华山派的&…