You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为CatBoost分类器优雅生成近月样本权重更高的月度权重列

问题场景

手头有高度不平衡的数据集,计划按月份为观测样本分配权重,规则为距离当前越近的月份样本权重越高:例如2022年1月的观测样本权重赋值为1/5,2022年3月的观测样本权重赋值为1/3,依此类推,权重列格式示例如下:

feature_1    date     weights
117       2016-11-12   0.015
...          ...        ...
123       2022-01-01    0.2
234       2022-01-02    0.2
...          ...  
345       2022-05-31    1.0

当前使用CatboostClassifier构建模型,已知可将全量样本对应的权重列表传入Pool的weight参数完成加权训练,调用形式如下:

model.fit(Pool(X_train,y_train,weight=train_weight))

当前痛点:没有找到优雅的实现方案来生成所需的权重列/权重列表
现有临时实现方案逻辑繁琐、性能差:

  1. 先按月份频率拆分训练集数据框
g = X_train.groupby(pd.Grouper(key='date', freq='M'))
dfs = [group for _,group in g]
  1. 通过双层循环遍历每个月度分组,逐行给样本赋值权重
for i, df in enumerate(dfs):
    weight = []
    for val in dfs[i].iterrows():
        weight.append(1 / (len(dfs)+2 - i))
    dfs[i]['weight'] = weight

需要更简洁高效、代码更优雅的月度样本权重生成方案。

优化实现方案

完全不需要拆分DataFrame、不需要逐行循环,用pandas向量化操作即可实现,性能比原方案提升1~2个数量级,逻辑清晰易维护:

import pandas as pd

# 若date列未转时间格式先执行这步,已转可跳过
X_train['date'] = pd.to_datetime(X_train['date'])

# 提取所有样本所属月份,按时间从远到近排序去重
unique_months = sorted(X_train['date'].dt.to_period('M').unique())
# 构建月份-权重映射字典,完全匹配示例规则:最近月份权重为1,每往前1个月权重分母加1
month_weight_map = {
    month: 1 / (len(unique_months) - idx)
    for idx, month in enumerate(unique_months)
}
# 直接映射生成整列权重,全程无循环
X_train['weight'] = X_train['date'].dt.to_period('M').map(month_weight_map)

# 提取给CatBoost用的权重数组直接取values即可
train_weight = X_train['weight'].values
  • 方案优势:
    • 无iterrows()逐行遍历的性能损耗,十万级以上样本处理速度远高于原双层循环方案
    • 不需要拆分、拼接DataFrame,不会出现索引错位类bug
    • 权重规则调整灵活:如果需要改成线性权重、指数权重、固定窗口权重,仅需修改month_weight_map的生成逻辑即可,整体流程不需要变动

内容的提问来源于stack exchange,提问作者Michael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 03:30:59