跳转至

Bayesian Causal Machine Learning for Cure Models

作者: Antonio R. Linero, F. Javier Rubio, Piyali Basak
主题: 因果推断
相关性: 7/10
链接: https://arxiv.org/abs/2606.11405


一、领域脉络与小综述

这个方向是什么

生存数据中经常出现一个非可忽略的子群,在随访期内始终不经历事件(被“治愈”)。经典的 cure rate model(混合 cure 模型或 promotion-time 模型)将总体生存函数显式地分解为治愈概率与未治愈者的生存分布(Othus et al. 2012; Peng & Taylor 2014)。当讨论 因果效应 时,一个自然的问题是:治疗通过哪条路径影响结局——是提高了治愈概率,还是延长了未治愈者的生存时间?近五年,因果机器学习文献开始介入生存分析,但绝大部分方法(如因果生存森林、深度表征学习)并没有显式建模治愈子群,而是把累积生存函数或 RMST 作为目标(Cui et al. 2023; Henderson et al. 2020; Curth et al. 2021)。只有少数工作(Wang et al. 2024; Sun & Song 2025)尝试在治愈子群存在下定义因果 estimand,但它们要么依赖强假设(单调性),要么采用的对比比较了不同潜在人群(“uncured average treatment effect”不构成标准因果 estimand)。本文试图填补这一缺口:在治愈子群存在时,定义一组可解释的因果效应(尤其是将 RMST 效应分解为“归因于治愈概率的部分”与“归因于未治愈者生存分布的部分”),并用贝叶斯非参数回归树(BART)加以估计。 该方向目前处于“轮廓已现但理论尚浅”的阶段:estimand 的定义有了(本文),但 identification 假设的强弱、估计量的渐近性质、效率界等均未系统处理。

发展脉络(history)

  1. 奠基:cure rate 模型与统计推断
  2. Chen et al. (1999)Yakovlev et al. (1996) 提出了 promotion-time cure 模型:假定潜在致癌事件数 \(N_i \sim \text{Poisson}(\theta)\),治愈等价于 \(N_i=0\),生存函数为 \(S(t) = \exp\{-\theta \tilde{F}(t)\}\)。该模型的优势在于治愈概率与未治愈生存分布由同一组参数 \(\theta\)\(\tilde{F}\) 决定,从而自动“共享信息”。
  3. Peng & Taylor (2014) 的综述总结了 cure 模型的识别条件:必须对尾巴行为施加约束(如 cure threshold \(\tau\) 或常数 hazard),否则模型即使形式上可识别,有限样本估计也高度不稳定(Li et al. 2001 也强调了识别性问题)。

  4. 因果机器学习进入生存分析(不加治愈子群)

  5. Hill (2011) 首先用 BART 估计异质性因果效应;Hahn et al. (2020) 提出 Bayesian Causal Forest(BCF),将模型分解为预后与处理效应分量,通过先验正则化处理效应异质性。
  6. Henderson et al. (2020) 提出 IndivAFT:用 BART 建模 \(\log T_i(a) = \mu_a(X_i) + \epsilon_i\),其中 \(\epsilon_i\) 用 Dirichlet 过程混合建模,得到完全贝叶斯的加速失效时间模型。
  7. Cui et al. (2023) 提出 causal survival forest (CSF),扩展因果森林到右删失数据,目标 estimand 是有限时间生存概率与 RMST。
  8. 这些方法在估计 ATE 与 CATE 时有效,但 不区分治愈与非治愈。本文指出,在没有治愈子群的设定下,这些方法已足够;但存在治愈子群时,它们不提供关于“治愈概率 vs. 延迟死亡”机制的分解。

  9. 治愈子群下的因果 estimand 尝试

  10. Wang et al. (2024)principal stratification(Frangakis & Rubin, 2002)将个体分为“always-uncured”“cured-by-treatment”等 strata,并在“always-uncured”上定义因果效应。这需要 单调性假设(不存在“cured under control but uncured under treatment”)。在 CALGB 40101 这样的非劣效试验中,该假设难以辩护。
  11. Sun & Song (2025) 采用 混合 cure 模型(BART probit 用于治愈概率 + BCF 用于 \(\log\) 生存时间),并定义了“uncured average treatment effect”(UATE)。但作者正确地指出:UATE 比较了不同潜在人群的潜在结局(治愈者 vs 未治愈者),不是一个标准因果 estimand。
  12. 本文的位置:提出 stochastic cure/latency 分解,将 RMST 效应分解为两个可识别、可解释的组件,并声称其 所需假设不比标准因果生存分析更强(只需 cure threshold + 常规 ignorability/positivity/censoring 假设)。同时给出了与新 estimand 相关的 principal strata 解释(Proposition 3),但强调该解释需要额外条件(单调性 + 主忽略性),从而使 estimand 本身与 mechanistic 解释保持距离。

  13. 当前 frontier

  14. 在同一年(2025-2026),Kabata et al. (2026) 系统比较了 IndivAFT 与 CSF 在 RMST 估计上的性能,发现 BART 方法在不确定性量化上占优。
  15. Basak et al. (2026) 将 BART 推广到相对生存模型。
  16. 本文作者包含了这些结果,并进一步加入 cure 结构。

子线索聚类

  • 线索 A:因果生存森林的扩展(Cui et al., 2023; Zhu & Gallego, 2020)。它们不显式处理治愈,但可通过选择合适的 \(\tau\) 覆盖治愈情形。
  • 线索 B:贝叶斯非参数生存因果模型(Henderson et al., 2020; Sun & Song, 2025; 以及本文)。这类方法提供完整后验,可以输出个体水平的效应分布。Sun & Song 是混合 cure + BCF;本文是 promotion-time + BART。
  • 线索 C:主分层方法定义治愈子群内的因果效应(Wang et al., 2024)。该方法需要单调性,但可以给出更直接的 mechanistic 解释。
  • 线索 D:promotion-time 模型与 BART 的融合(本文及 Basak et al., 2026; Alam & Linero, 2025)。promotion-time 模型自然地产生相依的治愈概率与生存分布,BART 提供非参数灵活性。

这个方向在追问的核心问题

  1. 怎样在治愈子群存在时定义既有因果解释、又仅依赖可检验(或弱)假设的 estimand?
  2. 能否不依赖单调性假设即可识别主分层效应?
  3. 用什么估计方法可以在有限样本下同时获得 ATE 和 CATE 的可靠不确定性量化?
  4. 这些 estimand 的渐近效率界是什么,能否构造双稳健估计量?

当前主流方法与瓶颈:现有方法要么强化假设(Wang 的单调性),要么定义估计量但缺少渐近理论(Sun & Song;本文)。未看到任何工作给出 semiparametric efficiency bound 或 influence function 推导——这是一个明显空白。

⚠️ 作者的 framing(必须明确标注为作者的说法)

作者将自己的贡献 frame 为:

“Unlike the proposals of Wang et al. (2024), our latency effect can be estimated with minimal assumptions beyond those typically made in causal survival analysis.”(Section 1)
“We define useful parameters in the cure-rate setting… including effects that decompose RMST effects into effects attributable and not attributable to cure process.”(Section 1)

  • 竞争路线被淡化/回避:作者在讨论中将 UATE(Sun & Song 2025)视为“not a standard causal estimand”,但并未在其模拟中与 Sun & Song 的方法直接比较(实际上模拟对比的是 IndivAFT 和 CSF,而非 Sun & Song 的实现)。此外,作者声称 promotion-time 模型比混合 cure 模型“更有效地跨治愈与潜伏共享信息”,但并未提供理论或模拟证据说明这种共享带来了什么实质改善(在模拟中,one-forest 模型略优于 two-forest,但差异不大)。
  • 明显该被引/该存在、却没出现在 intro 里:① Stensrud et al. (2022) 的“separable effects”框架与本文的 stochastic intervention 在理念上高度相似(将生存时间分解为不同机制的贡献),但作者只在提到“separable effects”时引用了一次,并未详细对比。② 关于 semiparametric efficiency bound 的文献(如 Tsiatis, 2006; van der Laan & Robins, 2003)完全未被引用,尽管本文定义了一个可以通过 one-step 或 TMLE 估计的 estimand(\(\Delta_{SC}, \Delta_{SL}\))。③ Cox 模型的因果解释(如 marginal structural models)以及 逆概率加权用于生存曲线(Cole & Hernán, 2004)未被提及。

张力

未发现被引文献之间存在彼此矛盾的实证结论。但潜在的理论张力存在于:Wang et al. (2024) 认为主分层效应是“正确”的因果 estimand(需要单调性),而本文则认为 stochastic latency effect 更实用(不需要单调性)。这两种哲学取向的优劣无法通过理论判定,取决于应用背景。


二、最核心、最简单的例子 / 数学问题

第一步:符号、模型、可观测数据

  • 符号
  • \(T_i\):个体 \(i\) 的生存时间。允许 \(T_i = \infty\)(治愈)。
  • \(C_i\):右删失时间。
  • \(Y_i = \min(T_i, C_i)\):观测到的事件时间。
  • \(\delta_i = \mathbb{1}(T_i \le C_i)\):事件指示(1=事件,0=删失)。
  • \(A_i \in \{0,1\}\):二值治疗指示。
  • \(X_i \in \mathbb{R}^p\):协变量(可能同时是混杂变量与效应修饰因子)。
  • 潜在结果:\(T_i(a)\),对 \(a\in\{0,1\}\)。一致性:\(T_i = T_i(A_i)\)
  • 生存函数:\(S_a(t) = \Pr(T_i(a) > t)\)。治愈概率:\(\lim_{t\to\infty} S_a(t)\)
  • RMST:\(R_i(a,t) = \min(T_i(a), t)\)\(\Delta_R(t) = \mathbb{E}[R_i(1,t) - R_i(0,t)]\)
  • 条件量:\(\Delta_R(t,x) = \mathbb{E}[R_i(1,t)-R_i(0,t) \mid X_i=x]\)
  • 治愈概率条件:\(p_a(x) = \Pr(T_i(a) < \infty \mid X_i=x)\)
  • 未治愈者 RMST 条件:\(m_a(t,x) = \mathbb{E}[R_i(a,t) \mid T_i(a) < \infty, X_i=x]\)
  • \(G_a(u\mid x) = \Pr(T_i(a) > u \mid T_i(a) < \infty, X_i=x)\):未治愈者生存函数。

  • 模型(数据生成机制)
    本文不假设一个参数化模型,而是采用 promotion-time cure model 作为高效但灵活的建模框架:

    \[S(t\mid a, x) = \exp\{-\theta(a,x) \tilde{F}(t\mid a,x)\}, \quad \tilde{F}(\infty\mid a,x)=1.\]
    其中 \(\theta(a,x) >0\) 与 “expected number of latent competing events” 有关;\(\tilde{F}(t\mid a,x)\) 是事件时间分布。治愈概率为 \(e^{-\theta(a,x)}\)。未治愈者的生存分布为
    \[G_a(t\mid x) = \frac{\exp\{-\theta(a,x)\tilde{F}(t\mid a,x)\} - e^{-\theta(a,x)}}{1 - e^{-\theta(a,x)}}.\]

    BART 用来非参数地建模 \(\log\theta(a,x)\)\(\tilde{F}\) 的 hazard 部分。

  • 可观测数据:研究者观测量为 \((Y_i, \delta_i, A_i, X_i)\)\(i=1,\dots,n\)

  • 可观测的:事件时间或删失时间、事件指示、治疗分配、协变量。
  • 不可观测但想要:个体是否治愈(\(T_i=\infty\) 从未被直接观测);完整的潜在生存曲线;principal strata 归属(如 \(i\in UU\))。
  • 识别所需的假设:Assumptions 1-5(标准 positivity, ignorability, SUTVA, ignorable censoring, cure threshold)。关键假设 5 断言存在已知 \(\tau\) 使得 \(h(t\mid a,x)=0\) 对所有 \(t>\tau\),从而将不可观测的 “cure” 事件 \(\{T_i=\infty\}\) 替换为可观测的 \(\{T_i > \tau\}\)

第二步:最小内核(最简特例)

去掉一切冗余的设定后,本文核心的数学操作是一个分解恒等式:

假设:(i)没有协变量(或条件版本,但下面展示无条件版本);(ii)治愈阈值 \(\tau\) 已知,且 \(t \le \tau\);(iii)记 \(p_a = \Pr(T_i(a)<\infty)\)\(m_a(t) = \mathbb{E}[\min(T_i(a), t) \mid T_i(a)<\infty]\),且 \(S_a(t) = \Pr(T_i(a)>t)\)

则 RMST 效应

\[\Delta_R(t) = \int_0^t (S_1(u) - S_0(u))\,du\]

可以分解为两个部分之和,定义如下:

  • Stochastic cure 成分

    \[\Delta_{SC}(t) = (p_0 - p_1)\left[t - \frac{m_0(t)+m_1(t)}{2}\right].\]
    直觉:如果治疗提高了治愈概率(即 \(p_1 < p_0\)),那么 \(\Delta_{SC}(t)\) 为正,幅度取决于治疗在“将个体从未治愈变为治愈”上获得的额外生存时间(平均而言,一个治愈者贡献 \(t\) 个月的 RMST,而未治愈者平均只贡献 \(\approx m_a(t)\) 个月的 RMST,二者之差被 \((p_0-p_1)\) 加权)。

  • Stochastic latency 成分

    \[\Delta_{SL}(t) = (m_1(t) - m_0(t)) \cdot \frac{p_0+p_1}{2}.\]
    直接反映未治愈者之间生存分布的差异,按平均未治愈概率加权。

为什么这是内核?
- 在一般有协变量的情形,\(\Delta_R(t,x)\) 的分解完全相同,只是所有量换为条件版本(Proposition 2)。
- 作者引入 stochastic intervention 框架(将 \(\Delta_{SC}\) 视为用随机选择的对照生存分布来替换处理组的生存分布)主要是为了提供更干净的解释,但核心代数关系就是上面这个不带辅助机制的恒等式。
- 作者证明的所有 Proposition(1-3)都是在此分解基础上,通过 principal strata 进一步解释 \(\Delta_{SL}\) 的因果含义。

该分解的证明即代数展开(见附录 Proposition 2 的证明,在补充材料中只有两行)。因此,整篇论文的 estimand 部分本质上就是发现并定义了这个分解,并把它从无协变量版本推广到了条件版本。


三、这篇论文做了什么

三句话

  1. 研究了什么问题:在存在治愈子群的生存数据中,定义新的因果 estimand(stochastic cure/latency)将 RMST 效应拆分为可解释分量,并说明其与主分层效应的联系。
  2. 核心工具/方法:提出 BartCure,基于 promotion-time cure model 与 Bayesian Additive Regression Trees 的完全贝叶斯非参数估计方法,包含 one-forest 和 two-forest 两种变体,通过 MCMC(Gibbs 采样)进行推断。
  3. 主要结论:模拟表明,one-forest BartCure 在 ATE 估计上竞争力强(尤其在有治愈子群时优于 IndivAFT 与 CSF),在检测处理效应异质性方向上具有保守的 Type-S 误差速率;CALGB 40101 试验分析显示 RMST 效应主要来源于治愈概率差异而非未治愈者生存差异。

关键设定与假设

补充上述第二节的记号,完整的假设列表(见附录 S1):
- Assumption 1 (SUTVA):一致性 + 无干扰。
- Assumption 2 (Positivity)\(0<\delta < e(x) < 1-\delta\)
- Assumption 3 (Ignorability)\((T_i(0), T_i(1)) \perp A_i \mid X_i\)
- Assumption 4 (Ignorable Censoring)\(C_i \perp T_i \mid A_i, X_i\)
- Assumption 5 (Cure Threshold):存在已知 \(\tau < \infty\) 使得 hazard \(h(t\mid a,x)=0\) 对所有 \(t>\tau\),且 \(\Pr(C_i > \tau \mid X_i) > 0\)

与已有文献的对比
- 相比 Wang et al. (2024),本文 不需要 单调性假设,但 需要 cure threshold,这是交换。
- 相比 Sun & Song (2025),本文使用 promotion-time 模型(共享信息)而非混合 cure 模型(分开参数化)。本文声称 promotion-time 自动共享信息,但并未提供边际增益的实证比较(模拟中未直接对比 Sun & Song 的方法)。

主要结果

理论结果(三个 Proposition)

  1. Proposition 1:在单调性(\(CU\) 空)假设下,naive latency effect \(\Delta_L(t)\) 可表达为 principal stratum \(UU\) 内 RMST 效应与来自 \(UC\) 的偏移项之差。

    \[\Delta_L(t) = p_1 \Delta_{UU}(t) - \Delta_C \mathbb{E}[R_i(0,t)\mid i\in UC].\]

    结论:\(\Delta_L\) 有缺陷,因为治疗若增加治愈(\(\Delta_C>0\)),则负项变大,可能使整体 latency 效应看起来有害。

  2. Proposition 2(核心分解):

    \[\Delta_R(t,x) = \Delta_{SC}(t,x) + \Delta_{SL}(t,x).\]

    其中
    \[\Delta_{SC}(t,x) = (p_0(x)-p_1(x))\left[t - \frac{m_0(t,x)+m_1(t,x)}{2}\right],\]

    \[\Delta_{SL}(t,x) = (m_1(t,x)-m_0(t,x))\frac{p_0(x)+p_1(x)}{2}.\]

    无需额外假设,只需 Assumptions 1-5(即标准因果生存假设 + cure threshold)。

  3. Proposition 3:在单调性(\(CU\) 空)且 \(\Pr(i\in CU\mid X)=0\) 下,\(\Delta_{SL}(t,x)\) 与 principal stratum \(UU\) 上的 RMST 效应 \(\Delta_{UU}(t,x)\) 成比例,若 \(\Delta_C(x)=0\)\(B_{UU}(t,x)=B_{UC}(t,x)\)(后一条件称为 principal ignorability)。因此 \(\Delta_{SL}\) 是比 \(\Delta_L\) 更稳健的 \(\Delta_{UU}\) 的代理。

技术难点:Proposition 3 的证明需要将条件期望在 strata 上展开,这本身不困难;真正的难点在于估计。BartCure 的推断算法(Gibbs sampler)需要处理潜变量 \(K_i\sim \text{Poisson}(\theta_i \tilde{S}_i)\) 以完成共轭更新,且处理 piecewise constant baseline hazard 的截断。附录 S3 给出了完整算法。

证明路线与技术技巧

整体路线(以 Proposition 3 为例)
1. 由单调性假设推出 stratum 概率关系。
2. 将 \(m_0(t,x)\) 写作 \(p_1(x)/p_0(x)\cdot B_{UU}(t,x) + \Delta_C(x)/p_0(x)\cdot B_{UC}(t,x)\)
3. 计算 \(m_1(t,x) - m_0(t,x)\) 得到关于 \(\Delta_{UU}\) 与偏移项的表达式。
4. 代入 \(\Delta_{SL}\) 的定义即得。

关键跳跃点:将 \(m_0\) 分解到两个 strata 上需要注意到 \(\Pr(i\in UU\mid X) = p_1\)\(\Pr(i\in UC\mid X) = \Delta_C\)——这种对应成立仅当 \(CU\) 为空。这是作者需要单调性假设的原因。

技术技巧点名
- Promotion-time 模型与 BART 的结合:使用 log-gamma 先验实现共轭 Gibbs 更新(参考 Murray, 2021 的 Poisson log-linear BART)。
- 数据增广:引入潜变量 \(K_i\sim \text{Poisson}(\theta_i \tilde{S}_i)\) 使得似然因子化,从而可以分别更新 \(\theta\) 和 hazard 部分的 BART 树。
- Piecewise constant baseline hazard + 阈值 \(\tau\) 截断:不符合 Assumption 5 时也能拟合,但设置最后一段 \(\lambda_K=0\) 强制满足。
- Metropolis-Hastings 更新树结构:使用 Chipman et al. (1998) 的 grow/prune/change 提议,利用整合似然进行接受。

真实例子与应用

数据:CALGB 40101 乳癌试验,\(N=3864\) 例,比较 paclitaxel (T) 与 cyclophosphamide+doxorubicin (CA)。终点:无病生存期。\(A=1\) 为 T,\(A=0\) 为 CA。
方法应用:给定 \(\tau=115\) 个月。用 one-forest BartCure 估计 \(\Delta_R(115)\)\(\Delta_C\)\(\Delta_{SL}\)\(\Delta_{SC}\),并输出个体后验。
结果
- \(\hat\Delta_R(115) = -2.24\) 月(95% CI: -4.14, -0.33),\(\hat\Delta_C = -0.039\)(-0.073, -0.004),均指示 T 不优于 CA。
- \(\Delta_{SL}\) 的 95% CI 包含 0(图2),即未治愈者生存分布差异不显著,RMST 效应几乎全部来自治愈概率差异
- 个体效应 waterfall 图(图3)显示所有个体效应均为负,但点估计异质性有限;CSF 估计的异质性更大(图4)。
- 决策树摘要(图5)识别出年龄 >60 和激素受体阴性(stra2=2)为可能携带更大负效应的亚组,但不确定性大(图6)。
用例目的:验证方法在真实数据上的可行性,展示如何解读 cure-latency 分解,以及展示 BartCure 相对于 CSF 和 IndivAFT 的保守性(在随机试验中,过大的异质性估计可能不可靠)。

🔎 结论是否比证明窄

  • 关键例子:Proposition 3 的陈述包含“Hence \(\Delta_{SL}(t,x)\) is proportional to \(\Delta_{UU}(t,x)\) if \(\Delta_C(x)=0\) or \(B_{UU}(t,x)=B_{UC}(t,x)\)”。但作者在 Section 2.2 中描述 \(\Delta_{SL}\) 的优点时说“it can be estimated with minimal assumptions beyond those typically made in causal survival analysis”。而 Proposition 3 中的连接需要 额外的单调性假设\(\Pr(i\in CU)=0\))和 principal ignorability。作者在文中明确承认了这一点(“Without further assumptions, we view \(\Delta_{SC}\) and \(\Delta_{SL}\) as model-based standardizations … rather than as literal mechanistic effects.”)。因此 没有夸大结论,解释是谨慎的。
  • 另一个窄结论:对于 Hu DGP 中 \(\Delta_S(t)\) 的估计,所有方法(包括 BartCure)的覆盖非常差(表2中 Hu 3 & 4 的覆盖仅为 0.22-0.31)。作者承认“this occurs because the survival functions are very close to zero at these follow-up times”。这意味着在实际应用中,若随访时间接近生存曲线尾部,RMST 估计可能鲁棒,但生存概率的 ATE 不可靠。这一结论被明确局限在了该 DGP 特性中,未泛化声称。

四、开放问题(点到为止,扎根具体语句)

  1. 渐近理论缺失:BartCure 作为完全贝叶斯方法,其估计的 频率一致性、收敛速率、后验覆盖的校准性 均未证明。原文仅在模拟中评估覆盖,并承认对 CATE 覆盖不足(Section S4.2:“no method attains nominal coverage … ”)。一个明确的开放问题是:能否推导出 BartCure 估计量(posterior mean)的渐近分布?能否建立 semiparametric efficiency bound 并构造 debiased / one-step 估计量?这与研究者熟悉的 efficiency theory 直接相关。

  2. Stochastic latency effect 在缺乏单调性时的解释:本文定义的 \(\Delta_{SL}\) 本身在缺乏单调性下是良定义的(Proposition 2 不需要单调性),但作者将其与 principal stratum 效应连接时需要单调性(Proposition 3)。原文提到“without further assumptions, we view these as model-based standardizations” (Section 2.2)。一个开放问题是:是否存在一组 可检验的假设 可以部分放松单调性,使 \(\Delta_{SL}\) 获得更直接的 mechanistic 解释?例如,可考虑部分单调性或敏感性分析,其中偏移项被限制在一个范围内。

  3. Cure threshold 的选择敏感性:Assumption 5 需要已知 \(\tau\)。作者在讨论中承认“if the threshold is chosen too small… too large…”(Section 6)。开放问题是:怎样用数据自适应地选择 \(\tau\)?或者采用更弱的尾巴假设(如 exponential tail)后,识别与估计的数值稳定性如何?作者提到“our methodology can also accommodate the weaker assumption that there exists some \(\tau>0\) such that the hazard is constant beyond \(\tau\)”,但未给出明确的估计步骤或模拟比较。

  4. BART 先验对处理效应异质性的收缩方向:作者宣称 BART 先验“naturally penalizes treatment effect heterogeneity”(Section 3.2),模拟也确实发现 BartCure 比 CSF 更保守。但这一保守性是否总是可取的?在效应确实很大且异质时,BartCure 是否会低估方向(Type-M error)?模拟中 Hu 1 & 4 的 net directional score 不比 CSF 高(Table 3),暗示存在 trade-off。能否设计一种交叉验证或经验贝叶斯方法来选择先验的收缩强度,从而在过度保守与过度激进之间平衡?

(以上各点均扎根于论文的具体语句或模拟结果,不替研究者判断可行性。)


Maintained by 陈星宇 · Homepage · Source on GitHub

评论