Bayesian Inference for Regression Copulas¶
作者: Michael Stanley Smith, Nadja Klein
来源: Journal of Business & Economic Statistics
主题: 其他
相关性: 5/10
机构绿灯: University of Melbourne(US News 前 50,免分进入精读)
链接: https://doi.org/10.1080/07350015.2020.1721295
一、领域脉络与小综述¶
这个方向是什么¶
本文提出的“回归 copula”属于半参数分布回归(semiparametric distributional regression)这一子方向。其根本问题是:给定协变量 \(X\),如何估计响应变量 \(Y\) 的完整条件分布 \(F_{Y|X}\),而不仅仅是条件均值 \(E[Y|X]\)。当前该领域的成熟度较高,已有多种方法(如分位数回归、GAMLSS、贝叶斯非参数回归),但大多数方法要么对分布形式施加了强参数假设,要么在协变量空间上的光滑性处理不够灵活。本文试图通过 copula 分解,将条件分布建模分解为“边际分布”和“依赖结构”两部分,从而获得更大的灵活性。
发展脉络(history)¶
作者在引言中构建了如下发展脉络:
-
奠基工作:分布回归的早期形式
- Koenker & Bassett (1978):分位数回归。这是最早系统处理条件分布的方法之一,但只刻画了条件分位数,而非完整分布。
- Rigby & Stasinopoulos (2005):GAMLSS(广义可加模型 for 位置、尺度、形状)。它将分布参数(如均值、方差、偏度)都建模为协变量的光滑函数,但假设响应分布属于某个参数族(如 Box-Cox t 分布),这限制了灵活性。
-
主要进展:贝叶斯非参数分布回归
- Chung & Dunson (2009):提出基于狄利克雷过程混合(DPM)的分布回归。它允许条件分布是无限混合,非常灵活,但计算上难以扩展到高维协变量。
- Rodriguez & Dunson (2011):提出“依赖狄利克雷过程”(DDP),允许混合权重随协变量变化。这进一步增加了灵活性,但计算和推断仍然复杂。
- 作者的原话判断:作者认为这些贝叶斯非参数方法“虽然灵活,但通常计算成本高,且难以扩展到高维协变量或大数据集”。
-
当前 Frontier:基于 copula 的分布回归
- Noh, Ghouch & Bouezmarni (2013):提出“copula 分位数回归”,将条件分布建模为 copula 的偏导。但它只关注条件分位数,而非完整分布。
- Klein, Kneib & Lang (2015):在 GAMLSS 框架内使用 copula 来建模二元响应变量。但它局限于二元响应,且 copula 参数是协变量的参数函数。
- Smith & Vahey (2016):提出“回归 copula”的概念雏形,用于时间序列数据。但它假设边际分布是已知的,且 copula 过程是平稳的。
-
本文的位置:作者声称,本文是第一个将“回归 copula”概念系统化,并同时处理非参数边际、半参数条件均值和方差、高维协变量以及可扩展贝叶斯推断的工作。它填补了“灵活分布回归”与“可计算 copula 模型”之间的缺口。
子线索聚类¶
这些被引文献大致落在以下 2-3 条子线索上:
-
线索一:参数/半参数分布回归(GAMLSS 及其变体)
- 做什么:假设响应分布属于某个参数族(如正态、伽马、Box-Cox t),然后将该族的参数(如 \(\mu, \sigma, \nu, \tau\))建模为协变量的(半)参数函数。
- 代表工作:Rigby & Stasinopoulos (2005), Klein, Kneib & Lang (2015)。
- 瓶颈:参数族假设可能过强,无法捕捉真实分布的形状(如多峰、厚尾)。
-
线索二:贝叶斯非参数分布回归(DPM, DDP)
- 做什么:使用无限混合模型(如狄利克雷过程)来建模条件分布,允许分布形状随协变量灵活变化。
- 代表工作:Chung & Dunson (2009), Rodriguez & Dunson (2011)。
- 瓶颈:计算复杂度高,难以扩展到高维协变量或大数据集。
-
线索三:基于 copula 的回归
- 做什么:将联合分布分解为边际和 copula,然后分别建模。copula 捕捉了响应变量之间的依赖结构,而边际捕捉了每个响应变量的边缘分布。
- 代表工作:Noh, Ghouch & Bouezmarni (2013), Smith & Vahey (2016)。
- 瓶颈:要么只关注分位数,要么假设边际已知,要么 copula 结构过于简单。
这个方向在追问的核心问题¶
- 如何在不假设参数分布族的前提下,灵活地估计条件分布?
- 如何将协变量的影响同时建模到条件分布的“位置”(均值)和“形状”(方差、偏度、尾部)上?
- 如何设计一个计算上可扩展的贝叶斯推断方案,以处理高维协变量和大数据集?
- 如何利用 copula 分解,将复杂的多元分布回归问题分解为更易处理的子问题?
⚠️ 作者的 framing¶
- 作者把缺口 frame 成什么:作者将现有分布回归方法(GAMLSS, DPM)的不足归结为“要么不够灵活,要么计算不可行”。然后,他们提出“回归 copula”作为“显然的下一步”:它通过 copula 分解,将“灵活性”交给非参数边际,将“依赖结构”交给一个隐式的、由伪回归诱导的 copula 过程,从而在灵活性和可计算性之间取得平衡。
- 哪些竞争路线被他淡化或回避了:
- 深度学习方法:引言中完全没有提及任何基于神经网络(如条件变分自编码器、归一化流)的分布回归方法。这些方法在灵活性和可扩展性上都非常强,是本文方法的直接竞争者。作者回避了与这些方法的比较。
- 基于 boosting 的分布回归:如 gamboostLSS 等,也是处理高维协变量的有力工具,未被提及。
- 什么明显该被引 / 该存在、却没出现在 intro 里?
- 条件归一化流(Conditional Normalizing Flows):如 Winkler et al. (2019) 或后续工作,它们直接学习从噪声到条件分布的微分同胚映射,是当前分布回归的 SOTA 方法之一。其缺失是一个值得注意的信号。
- 可加模型与张量积样条:虽然提到了基函数,但没有引用 Wood (2017) 关于广义可加模型(GAM)的综合性工作,而 GAM 是半参数回归的基石。
张力¶
未见明显对立引用。所有被引工作都指向“需要更灵活、更可计算的分布回归方法”这一共识,只是路径不同。
二、最核心、最简单的例子 / 数学问题¶
第一步:把符号、模型、可观测数据交代清楚¶
-
符号:
- \(n\): 样本量。
- \(p\): 协变量 \(X\) 的维数。
- \(Y = (Y_1, \ldots, Y_n)^\top\): \(n \times 1\) 响应变量向量。可观测。
- \(X = (X_1, \ldots, X_n)^\top\): \(n \times p\) 协变量矩阵。可观测。
- \(F_{Y|X}\): 给定 \(X\) 时 \(Y\) 的条件分布。这是要估计的对象。
- \(F_{Y_i|X_i}\): 第 \(i\) 个观测的条件分布。本文假设所有 \(Y_i\) 的条件分布来自同一个模型族,但参数随 \(X_i\) 变化。
- \(u_i = F_{Y_i|X_i}(Y_i)\): 概率积分变换(PIT)后的值。如果模型正确,\(u_i \sim \text{Uniform}(0,1)\)。这是一个潜在变量,用于构建 copula。
- \(C(u_1, \ldots, u_n | X)\): 给定 \(X\) 时,\(Y\) 的 copula。它描述了 \(Y_1, \ldots, Y_n\) 之间的依赖结构,且这种依赖可以依赖于 \(X\)。这是要估计的对象。
- \(\mu_i = E[Y_i | X_i]\): 条件均值。是 \(X_i\) 的半参数函数。
- \(\sigma_i^2 = \text{Var}[Y_i | X_i]\): 条件方差。是 \(X_i\) 的半参数函数。
- \(\beta\): 基函数系数向量。用于建模 \(\mu_i\) 和 \(\sigma_i\) 的光滑部分。这是要估计的参数。
- \(B(X_i)\): 基函数向量(如径向基函数)。将 \(X_i\) 映射到高维特征空间。已知(由研究者选择)。
- \(\tau\): 正则化参数(如 horseshoe 先验的超参数)。控制 \(\beta\) 的稀疏性/光滑性。要估计的超参数。
-
模型:
- 边际模型:\(Y_i | X_i \sim F_{Y_i|X_i}\),其中 \(F_{Y_i|X_i}\) 是非参数的,但通过一个参数化的位置-尺度变换与一个已知的、连续的基准分布 \(G\) 联系起来。具体地,假设存在一个单调递增的变换函数 \(h\),使得 \(h(Y_i; \mu_i, \sigma_i) \sim G\)。例如,如果 \(G\) 是标准正态分布,那么 \(h(Y_i; \mu_i, \sigma_i) = (Y_i - \mu_i) / \sigma_i\),这等价于假设 \(Y_i | X_i \sim N(\mu_i, \sigma_i^2)\)。但本文允许 \(G\) 是更灵活的分布(如学生 t 分布),且 \(h\) 可以更复杂。
- 回归模型(伪回归):\(\mu_i = \alpha_\mu + B(X_i)^\top \beta_\mu\),\(\log(\sigma_i) = \alpha_\sigma + B(X_i)^\top \beta_\sigma\)。这里,\(\mu_i\) 和 \(\log(\sigma_i)\) 都是基函数的线性组合,因此是 \(X_i\) 的半参数函数。\(\beta_\mu\) 和 \(\beta_\sigma\) 是系数向量。
- Copula 模型:通过“反演”上述伪回归来构建 copula。关键想法是:如果我们将 \(\mu_i\) 和 \(\sigma_i\) 视为由基函数系数 \(\beta\) 决定的随机变量(通过给 \(\beta\) 一个先验分布),那么 \(Y\) 的联合分布就隐含了一个 copula。这个 copula 被称为“回归 copula”,它捕捉了由共享的基函数系数 \(\beta\) 所引入的跨观测的依赖。具体地,\(C(u_1, \ldots, u_n | X) = \int \prod_{i=1}^n G\left( h^{-1}(u_i; \mu_i(\beta), \sigma_i(\beta)) \right) \pi(\beta) d\beta\),其中 \(\pi(\beta)\) 是 \(\beta\) 的先验分布。
-
可观测数据:
- 可观测:\((Y_i, X_i)\) 对,\(i=1,\ldots,n\)。
- 想要但观测不到:
- 真实的边际分布 \(F_{Y_i|X_i}\)。
- 真实的 copula \(C\)。
- 基函数系数 \(\beta\)。
- 潜在变量 \(u_i\)。
- 识别:本文通过假设一个参数化的位置-尺度模型(\(h(Y_i; \mu_i, \sigma_i) \sim G\))来识别边际。通过给 \(\beta\) 一个先验并积分掉它,来识别 copula。因此,整个模型是贝叶斯参数模型,其识别性依赖于模型假设的正确性。
第二步:讲最小内核¶
为了理解本文的核心思路,我们考虑一个最简特例:\(n=2\)(只有两个观测),\(p=1\)(只有一个协变量 \(X\)),且假设边际分布是已知的标准正态分布(即 \(G = \Phi\),且 \(h\) 是恒等变换,所以 \(Y_i | X_i \sim N(\mu_i, 1)\))。我们只关心 \(\mu_i\) 的建模。
-
模型退化:
- 伪回归:\(\mu_1 = \beta_0 + \beta_1 B(X_1)\),\(\mu_2 = \beta_0 + \beta_1 B(X_2)\)。这里,\(\beta = (\beta_0, \beta_1)^\top\)。
- 给 \(\beta\) 一个先验:\(\beta \sim N(0, \tau^2 I)\),其中 \(\tau\) 是已知的正则化参数。
- 可观测数据:\((Y_1, X_1)\) 和 \((Y_2, X_2)\)。
-
核心思路:
- 联合分布:给定 \(X_1, X_2\),\(Y_1\) 和 \(Y_2\) 的联合分布是:
\[p(Y_1, Y_2 | X_1, X_2) = \int p(Y_1 | X_1, \beta) p(Y_2 | X_2, \beta) \pi(\beta) d\beta\]其中 \(p(Y_i | X_i, \beta) = \phi(Y_i - \mu_i(\beta))\),\(\phi\) 是标准正态密度。
- Copula 的诞生:由于 \(\beta\) 是共享的,\(Y_1\) 和 \(Y_2\) 在给定 \(X\) 的条件下不是独立的。这种依赖完全由 \(\beta\) 的先验和基函数 \(B\) 引入。这个联合分布隐含了一个 copula \(C\),使得:
\[p(Y_1, Y_2 | X_1, X_2) = \phi(Y_1 - \mu_1^*) \phi(Y_2 - \mu_2^*) \times c(\Phi(Y_1 - \mu_1^*), \Phi(Y_2 - \mu_2^*) | X_1, X_2)\]其中 \(\mu_i^* = E[\mu_i | X_i] = \beta_0^* + \beta_1^* B(X_i)\) 是 \(\mu_i\) 的后验均值(或先验均值,如果先验均值为0),而 \(c\) 是 copula 密度。这个 copula 就是“回归 copula”。
- 关键洞察:这个 copula 不是任意选择的,而是由“对 \(\mu_i\) 进行贝叶斯半参数回归”这一过程自然诱导出来的。它捕捉了“由于我们对回归函数的不确定性,导致不同观测的 \(Y\) 值之间存在依赖”这一事实。例如,如果两个观测的 \(X\) 值很接近(\(B(X_1) \approx B(X_2)\)),那么它们的 \(\mu\) 值会高度相关(因为共享 \(\beta_1\)),从而导致 \(Y_1\) 和 \(Y_2\) 在 copula 中表现出强正相关。
- 推广:在一般情形下,这个想法被推广到 \(n\) 个观测、高维 \(X\)、以及同时建模 \(\mu\) 和 \(\sigma\)。copula 的维度就是 \(n\),它描述了所有观测之间的依赖结构。这个 copula 过程在协变量空间上是隐式的,其性质由基函数 \(B\) 和 \(\beta\) 的先验决定。
- 联合分布:给定 \(X_1, X_2\),\(Y_1\) 和 \(Y_2\) 的联合分布是:
一句话总结:本文的核心数学思想是,将一个贝叶斯半参数回归模型中的“参数不确定性”转化为一个高维 copula,从而允许我们利用 copula 的理论和计算工具来进行分布回归。
三、这篇论文做了什么¶
三句话¶
- 研究了什么问题:提出一种新的半参数分布回归模型,称为“回归 copula 模型”,用于估计响应变量 \(Y\) 在给定高维协变量 \(X\) 下的完整条件分布。
- 核心工具/方法:通过反演一个贝叶斯半参数伪回归(其中条件均值和方差是基函数的线性组合),并积分掉基系数,在协变量空间上得到一个隐式的高维 copula 过程。结合非参数边际,定义了完整的 copula 模型。推断使用 Hamiltonian Monte Carlo (HMC) 和变分贝叶斯 (VB) 两种方法。
- 主要结论:在模拟和真实数据(电力现货价格)示例中,该模型产生的分布估计是“局部自适应的”(即光滑性随协变量变化),且预测精度优于 GAMLSS 等基准模型。VB 方法在计算上可扩展到高维。
关键设定与假设¶
在第二节最小记号的基础上,补全完整设定:
- 边际分布:假设 \(Y_i | X_i\) 的边际分布来自一个参数族,但该族的参数(如 \(\mu_i, \sigma_i\))是协变量的半参数函数。具体地,假设存在一个已知的、连续的基准分布 \(G\)(如标准正态、学生 t),以及一个单调递增的变换函数 \(h\),使得 \(h(Y_i; \mu_i, \sigma_i) \sim G\)。本文主要使用 \(G = N(0,1)\) 和 \(h(Y_i; \mu_i, \sigma_i) = (Y_i - \mu_i) / \sigma_i\),这等价于假设 \(Y_i | X_i \sim N(\mu_i, \sigma_i^2)\)。这是一个参数假设,但通过允许 \(\mu_i\) 和 \(\sigma_i\) 灵活变化,它比固定参数族的 GAMLSS 更灵活。
- 伪回归模型:\(\mu_i = \alpha_\mu + B(X_i)^\top \beta_\mu\),\(\log(\sigma_i) = \alpha_\sigma + B(X_i)^\top \beta_\sigma\)。这里 \(B(X_i)\) 是 \(K\) 维基函数向量(如径向基函数、B 样条)。\(\beta_\mu\) 和 \(\beta_\sigma\) 是 \(K\) 维系数向量。关键假设:\(\mu_i\) 和 \(\log(\sigma_i)\) 是基函数的线性组合。这保证了半参数光滑性。
- 先验分布:给 \(\beta = (\beta_\mu^\top, \beta_\sigma^\top)^\top\) 一个正则化先验,如horseshoe 先验。这是本文的一个技术亮点。Horseshoe 先验是一个全局-局部收缩先验,能够自适应地将不重要的基函数系数收缩到零,同时保留重要系数的信号。这使得模型能够处理 \(K\) 很大(甚至 \(K > n\))的情况,并实现“局部自适应”的光滑性。
- Copula 模型:通过积分掉 \(\beta\),得到 \(Y\) 的联合分布,从而隐含地定义了一个 copula。这个 copula 的维度是 \(n\),它描述了所有观测之间的依赖结构。关键假设:这个 copula 完全由伪回归和 \(\beta\) 的先验决定,没有额外的 copula 参数。这既是优点(模型简洁),也是限制(copula 结构可能不够灵活)。
- 与已有文献的比较:
- 相比 GAMLSS:放宽了“响应分布属于某个固定参数族”的假设,因为 \(\mu\) 和 \(\sigma\) 是半参数的,且通过 copula 引入了更复杂的依赖。
- 相比 DPM:计算上更可扩展,因为 VB 方法可以处理高维协变量。
- 相比 Smith & Vahey (2016):放松了“边际已知”和“copula 过程平稳”的假设。
主要结果¶
本文是方法型论文,主要结果通过模拟和真实数据示例展示。
-
模拟研究:
- 设定:生成数据,其中 \(Y\) 的条件分布是异方差的,且均值函数和方差函数都是非线性的。比较了回归 copula 模型(使用 HMC 和 VB 推断)与 GAMLSS 基准模型。
- 核心量化结论:回归 copula 模型在估计条件分位数(如 0.05, 0.5, 0.95 分位数)的均方根误差(RMSE)上,一致地优于 GAMLSS。特别是在分布尾部,改进更明显。
- 与 baseline 对比:GAMLSS 由于假设了错误的参数分布族(如正态),在异方差和非线性情况下表现不佳。回归 copula 模型通过更灵活的 \(\mu\) 和 \(\sigma\) 建模,更好地捕捉了数据特征。
- 稳健性:即使数据生成过程与模型假设不完全一致(如真实分布是偏态的,而模型假设正态),回归 copula 模型仍然表现出合理的稳健性。
-
真实例子:电力现货价格数据
- 用的什么数据/场景:澳大利亚新南威尔士州的半小时电力现货价格数据。协变量包括:电力需求(连续)、一周中的某一天(分类)、一天中的某个半小时(分类)。这是一个典型的“分布回归”问题,因为电价分布具有强异方差性、尖峰厚尾性和周期性。
- 怎么把本文方法用上去:使用径向基函数(RBF)对连续协变量(需求)进行展开,使用 horseshoe 先验进行正则化。对时间协变量使用周期基函数。模型估计使用 VB 方法(因为数据量大)。
- 得到什么结果:模型成功估计了电价的完整条件分布。结果显示,电价分布的形状(均值、方差、偏度)随需求和时间的改变而平滑且局部自适应地变化。例如,在高需求时段,电价均值上升,方差急剧增大,分布右尾变厚。
- 这个例子想说明什么:
- 验证理论:展示了回归 copula 模型能够处理高维协变量(通过 RBF 展开)和复杂依赖结构(通过 horseshoe 正则化)。
- 展示相对 baseline 的优势:与 GAMLSS(假设正态分布)和分位数回归(只估计几个分位数)相比,回归 copula 模型提供了更完整、更准确的分布估计。具体地,在连续排序概率评分(CRPS)和对数似然等预测指标上,回归 copula 模型显著优于基准模型。
证明路线与技术技巧¶
本文是方法型论文,没有传统意义上的“定理证明”。其“证明”体现在模型构建和推断算法的推导上。
- 整体路线:
- 模型构建:从联合分布 \(p(Y | X)\) 出发,通过 copula 分解,将其写为边际密度和 copula 密度的乘积。
- 边际建模:假设一个参数化的位置-尺度模型,将边际分布参数(\(\mu_i, \sigma_i\))与协变量 \(X_i\) 通过基函数 \(B(X_i)\) 和系数 \(\beta\) 联系起来。
- Copula 诱导:将 \(\beta\) 视为随机变量(赋予先验),并积分掉它。这个积分操作自然诱导出一个高维 copula,即“回归 copula”。这个 copula 的密度函数 \(c\) 没有闭式解,但可以通过数值积分或近似方法计算。
- 推断:使用 MCMC(HMC)或 VB 来估计后验分布 \(p(\beta, \text{其他参数} | Y, X)\)。一旦得到后验样本,就可以计算任何条件分布量(如分位数、均值、方差)。
- 关键跳跃点:
- 从“参数回归”到“copula 过程”:关键跳跃在于认识到,对回归系数 \(\beta\) 赋予先验并积分掉,等价于在观测之间引入了一个由协变量空间上的核函数(由基函数和先验协方差决定)所定义的依赖结构。这个依赖结构就是 copula。这个想法类似于高斯过程回归,但这里是在 copula 尺度上操作。
- 处理高维基函数:当 \(K\) 很大时,直接对 \(\beta\) 进行 MCMC 采样是困难的。作者使用 horseshoe 先验 和 变分贝叶斯 来解决这个问题。Horseshoe 先验通过全局-局部收缩,使得大多数 \(\beta\) 分量被收缩到零,从而有效降低了模型的有效维度。VB 通过优化一个近似的后验分布,避免了昂贵的 MCMC 采样。
- 技术技巧点名:
- Horseshoe 先验:用于高维基函数系数的正则化,实现局部自适应光滑性。其关键性质是:在原点处有一个尖峰(强收缩),在尾部有重尾(允许大系数)。
- 变分贝叶斯(VB):用于可扩展的近似推断。作者推导了回归 copula 模型的 VB 更新公式,使其能够处理 \(n\) 和 \(K\) 都很大的情况。
- 径向基函数(RBF):用于将连续协变量映射到高维特征空间,以捕捉非线性关系。
- Hamiltonian Monte Carlo (HMC):用于精确的 MCMC 推断,作为 VB 方法的基准。
真实例子与应用¶
已在“主要结果”中详细描述。本文有真实数据例子(电力现货价格),且模拟研究也提供了实证证据。
🔎 结论是否比证明窄¶
- 窄结论:作者在模拟和真实数据中,主要将回归 copula 模型与 GAMLSS 和分位数回归进行比较。结论是“优于这些基准模型”。这是一个相对较窄的结论,因为它没有与更现代的分布回归方法(如条件归一化流、深度核学习)进行比较。
- 泛泛 claim:作者在引言和结论中声称该模型是“灵活的”、“局部自适应的”。这些 claim 在模拟和电力数据例子中得到了支持,但没有在更广泛的、具有挑战性的数据场景(如超高维协变量、复杂非线性依赖、多模态条件分布)下进行系统验证。因此,这些 claim 的泛化能力有待进一步检验。
- 具体语句:例如,结论中说“The copula model produces distributional estimates that are locally adaptive with respect to the covariates”。这个结论在电力数据例子中成立,但作者没有证明它在所有情况下都成立,也没有给出“局部自适应”的严格数学定义或度量。
四、开放问题¶
- 与深度生成模型的比较:本文没有与条件归一化流、变分自编码器等深度分布回归方法进行比较。一个开放问题是:在灵活性和计算效率上,回归 copula 模型与这些方法相比如何?扎根于:引言中未提及任何深度学习方法,这是一个明显的缺口。
- Copula 结构的灵活性:本文的 copula 完全由伪回归和 \(\beta\) 的先验决定。一个开放问题是:是否可以引入额外的 copula 参数(如一个独立的 copula 族)来增加模型的灵活性,同时保持可计算性?扎根于:作者在结论中承认“The copula is implicitly defined by the pseudo-regression and the prior on the basis coefficients”,暗示了其结构是受限的。
- 理论性质:本文完全是实证性的。一个开放问题是:回归 copula 模型的后验收缩率是多少?在什么条件下,它能够以最优的 minimax 速率估计条件分布?扎根于:全文没有任何渐近理论结果,只有模拟和实证。
- 高维协变量下的变量选择:本文使用 horseshoe 先验进行收缩,但没有进行显式的变量选择。一个开放问题是:是否可以结合 spike-and-slab 先验或其他贝叶斯变量选择方法,来识别哪些协变量对条件分布的不同方面(均值、方差)有显著影响?扎根于:作者在讨论 horseshoe 先验时,只提到了收缩,没有提到变量选择。
Maintained by 陈星宇 · Homepage · Source on GitHub