670. NeurIPS - Ariel Data Challenge 2025 | ariel-data-challenge-2025
数据校准是按照组织者建议的解决方案完成的。唯一的修改是使用传感器数据像素的子集。因此,数组切片 [:, 10:22, 39:321], [:, 10:22, :] 分别用于 AIRS-CH0 和 FGS1 传感器。
凌星进入和离开是使用基于梯度方法的算法计算的。在进行多项式拟合之前,排除了从 phase_a_start 到 phase_a_end 以及从 phase_b_start 到 phase_b_end 的窗口。如果 phase_a 检测无效,我仅使用 egress 部分来估计深度,反之亦然。如果 phase_a 和 phase_b 检测均无效,则不进行任何预测。
def detect_breakpoints(flux, verbose=False):
"""
通过计算去趋势信号的梯度来检测 airs 通量信号中的相位。
"""
# 均值和滤波信号
flux = flux.mean(axis=-1)
# 查找凌星中间点
min_index = np.argmin(flux)
in_a = flux[:min_index]
in_b = flux[min_index:]
# 计算两半部分的梯度
gradient_a = np.gradient(in_a, edge_order=1)
gradient_2a = np.gradient(gradient_a, edge_order=1)
gradient_2b = np.gradient(gradient_b, edge_order=1)
# 基于梯度识别相位索引
phase_a = gradient_a[1:].argmin() + 1
phase_b = gradient_b[:-1].argmax() + len(gradient_a)
phase_a_start = gradient_2a.argmin()
phase_a_end = gradient_2a.argmax()
phase_b_start = gradient_2b.argmax() + len(gradient_a)
phase_b_end = gradient_2b.argmin() + len(gradient_a)
breakpoints = {'center': min_index,
'phase_a_start': phase_a_start - 1,
'phase_a': phase_a,
'phase_a_end': phase_a_end + 1,
'phase_b_start': phase_b_start - 1,
'phase_b': phase_b,
'phase_b_end': phase_b_end + 1}
return breakpoints
凌星深度是使用多项式拟合和 Nelder-Mead 优化确定的。
def F(depth, phase_a_data, phase_x_data, phase_b_data, polyorder):
y = np.concatenate((
phase_a_data,
phase_x_data * depth,
phase_b_data
))
X = np.arange(len(y))
z = np.polyfit(X, y, polyorder)
p = np.poly1d(z)
score = np.abs(p(X) - y).mean()
return score
凌星深度是使用多项式拟合(最高 3 阶多项式)确定的。
我开始该方法时仅预测平坦输出,因为数据中的大多数光谱具有相对较小的振荡。
最初使用多项式拟合(最高 18 阶多项式)仅在平均波长上确定一次凌星深度。使用高达 18 阶的多项式拟合可能看起来违反直觉;然而,与拟合高达 3/4 阶相比,它产生了更好的结果。
为了准确预测最终光谱,确定了深度测量中的动态量。测量是在未平滑的时间序列上计算的。
过零率 (Zero Crossings Rate - ZCR) 是一个用于测量信号穿过零电平(即改变其符号)次数的特征。
def compute_zcr(signal, burn_in=20):
return librosa.zero_crossings(signal - signal.mean())[:-burn_in].sum()
Nelder-Mead 算法和以下代码用于确定 sigma/信号系数的值以及要使用的非平坦深度的量。
def operator(signal, zcr, additional_features, dynamic_depths, args):
"""
简化版本:
- 结合基础参数与 ZCR 及特征以修改 sigma。
- 根据特征调整信号。
- 如果在 'airs' 模式下,基于 zcr 添加残差深度以进行平坦化。
- 最后,使用多项式系数缩放信号。
"""
# 解包参数
a0, a1, a2, a3, cross_sigma, sigma, residual_coef, post_sigma = args[:8]
feature_coeffs = args[8:] # 额外特征的系数
# 使用基础值和 ZCR 影响初始化 sigma
sigma = sigma + cross_sigma * zcr
# 将额外特征的影响纳入 sigma 和信号
for i, (feature_name, feature_value) in enumerate(additional_features.items()):
sigma += feature_coeffs[i] * feature_value
signal += feature_coeffs[i] * feature_value
# 如果模式为 'airs' 则进行额外修正
if ScalerSigma.mode == 'airs':
# 计算残差(与均值的差异)并将其平坦化
residual = dynamic_depths - np.mean(dynamic_depths, axis=-1, keepdims=True)
residual = savgol_filter(residual, window_length=10, polyorder=1)
# 将通过 zcr 缩放的残差添加到信号
signal += zcr[:, None] * residual
# 信号的最终缩放
scaled_signal = a0 + a1 * signal + a2 * signal ** 2 + a3 * signal ** 3
return scaled_signal, sigma