626. NeurIPS - Ariel Data Challenge 2024 | ariel-data-challenge-2024
首先,我要感谢主办方的准备工作,感谢我的队友 @imayushsaxena 和 @octaviograu,以及所有让这次比赛充满挑战的 competitors!
该解决方案取得了以下成绩:
| 方案变体 | 公开榜 | 私有榜 | Leaderboard 排名 | 最终排名 |
|---|---|---|---|---|
| 第 10 名 | 0.6152848 | 0.6198108 | 53 | - |
| 第 11 名 | 0.6128403 | 0.6293136 | - | 37 |
该解决方案仅使用了 AIRS 数据。
解决方案的基本流程:
gaussian_filter1d 对信号去噪我们尝试了许多去噪策略,因此需要一种简单的方法来进行迭代。我们构建了一个易于配置的功能性 pipeline:
from functools import reduce
full_pipeline = [
lambda **kwargs: bin_wavelengths(**kwargs),
lambda **kwargs: normalize_signal(**kwargs),
lambda **kwargs: filter_signal_with_gaussian(sigma=25, **kwargs),
lambda **kwargs: polynomial_detrend(**kwargs),
lambda **kwargs: fit_transit_poly(**kwargs),
lambda **kwargs: collect_features(**kwargs),
]
initial_kwargs = {'signal': None, 'margin': 1, 'from_wavelength':39, 'to_wavelength':321}
result = reduce(lambda kw, func: func(**kw), full_pipeline, initial_kwargs)
然后我们可以结合不同 pipeline 的 result['features']。
Pipeline 中的每个步骤可以这样组织:
def filter_signal_with_median(window=5, **kwargs):
signal = kwargs['signal']
filtered_signal = median_filter(signal, size=window)
kwargs['signal'] = filtered_signal
return kwargs
在实验了 BATMAN 库之后,我们发现即使完全去噪和去趋势后,凌日通量信号仍有几种可能的结构。临边昏暗会影响凌日深度的计算,进而影响我们计算凌日边缘的方式。
def get_transit_phases2(**kwargs):
signal = kwargs['signal'] + 1
grad1 = np.gradient(signal)
mn = np.argmin(grad1)
mx = np.argmax(grad1)
peaks = find_peaks(grad1, width=25)[0]
ingress_left = peaks[(peaks < mn) & (mn - peaks <= 250)][-1] if np.any((peaks < mn) & (mn - peaks <= 250)) else mn-110
ingress_right = peaks[(peaks > mn) & (peaks - mn <= 250)][0] if np.any((peaks > mn) & (peaks - mn <= 250)) else mn+110
dips = find_peaks(-grad1, width=25)[0]
egress_left = dips[(dips < mx) & (mx - dips <= 250)][-1] if np.any((dips < mx) & (mx - dips <= 250)) else mx-110
egress_right = dips[(dips > mx) & (dips - mx <= 250)][0] if np.any((dips > mx) & (dips - mx <= 250)) else mx+110
kwargs['ingress_left'] = ingress_left
kwargs['ingress_right'] = ingress_right
kwargs['egress_left'] = egress_left
kwargs['egress_right'] = egress_right
return kwargs
知道凌日的 ingress 和 egress 后,我们将多项式拟合到通量信号中(忽略凌日),然后执行去趋势。
然后我们可以假设,一旦 plain 去趋势信号处于常数 1 的水平,我们就可以通过以下公式推导凌日深度:
def transit_formula(s):
return 1/s - 1
这里 s 可以是凌日中的平均通量、中点通量等。我们在这里收集了不少特征。与 minimize 方法相比,这是一个巨大的速度改进。
此外,我们还收集了凌日通量的通用特征,如标准差。
我们生成了 500 个 Ridge 模型和 500 个 PLSRegression 模型,形成了集成模型。
Ridge 的 Alpha 是随机的:
alpha = 10 ** (2 - 3 * np.random.rand())
PLSRegression 的 n_components 也是如此:
model = PLSRegression(n_components=n_components, tol=1e-8)
我们为每个模型使用了不同的训练数据子集:
subset_size = int(X_train.shape[0] * np.random.uniform(0.5, 1))
我们对每个波长的模型预测进行了排序,去除了最低和最高的 30%,并取剩余预测的平均值。
我们计算了每个波长排序预测的标准差:
std_preds = np.std(sorted_preds, axis=0)
然后将标准差乘以在 LB 上效果最好的系数:
COEFF_0 = 4 # 这个效果最好
sigma_response = sigma * COEFF_0
pywt) - 我们最喜欢的是 db29median_filtersavgol_filter欢迎探索我们的 最佳解决方案。