You need to enable JavaScript to run this app. 基于多列分组数据构建训练测试集预测QTR4销售代表拜访量
优惠活动
大模型
产品
解决方案
定价
更多

基于多列分组数据构建训练测试集预测QTR4销售代表拜访量

基于历史季度拜访数据的QTR4拜访量落地方案

一、基础数据预处理

原始数据加载后首先做类型修正,避免后续计算报错:

import pandas as pd
import numpy as np

# 加载示例数据
df = pd.DataFrame({"CUSTOMER_NUMBER": ["CUST1", "CUST1", "CUST1", "CUST1", "CUST1", "CUST1", "CUST1", "CUST1", "CUST1", "CUST2", "CUST2", "CUST2", "CUST2", "CUST2", "CUST2", "CUST2", "CUST3", "CUST3", "CUST3", "CUST4", "CUST4", "CUST4"],
"PRODUCT": ["PRODUCT1", "PRODUCT2", "PRODUCT3", "PRODUCT1", "PRODUCT2", "PRODUCT3", "PRODUCT1", "PRODUCT2", "PRODUCT3", "PRODUCT1", "PRODUCT2", "PRODUCT3", "PRODUCT1", "PRODUCT2", "PRODUCT3", "PRODUCT3", "PRODUCT3", "PRODUCT3", "PRODUCT3", "PRODUCT1", "PRODUCT1", "PRODUCT2"],
"REP_VISITS": ["3", "3", "3", "3", "3", "3", "4", "4", "4", "3", "2", "2", "4", "6", "8", "5", "3", "1", "3", "2", "0", "3"],
"QTR": ["QTR1", "QTR1", "QTR1", "QTR2", "QTR2", "QTR2", "QTR3", "QTR3", "QTR3", "QTR1", "QTR1", "QTR1", "QTR2", "QTR2", "QTR2", "QTR3", "QTR1", "QTR2", "QTR3", "QTR1", "QTR2", "QTR3"],
"START_DATE": ["2020-01-01", "2020-01-01", "2020-01-01", "2020-04-01", "2020-04-01", "2020-04-01", "2020-07-01", "2020-07-01", "2020-07-01", "2020-01-01", "2020-01-01", "2020-01-01", "2020-04-01",  "2020-04-01", "2020-04-01","2020-07-01", "2020-01-01", "2020-04-01", "2020-07-01", "2020-01-01", "2020-04-01", "2020-07-01"],
"END_DATE": ["2020-03-31", "2020-03-31", "2020-03-31", "2020-06-30", "2020-06-30", "2020-06-30", "2020-09-30", "2020-09-30", "2020-09-30", "2020-03-31", "2020-03-31", "2020-03-31", "2020-06-30", "2020-06-30", "2020-06-30", "2020-09-30", "2020-03-31", "2020-06-30", "2020-09-30", "2020-03-31", "2020-06-30", "2020-09-30"]})

# 修正字段类型
df["REP_VISITS"] = df["REP_VISITS"].astype(int)  # 原始拜访量为字符串,转整数方便计算
df["START_DATE"] = pd.to_datetime(df["START_DATE"])
df["END_DATE"] = pd.to_datetime(df["END_DATE"])

二、客户-产品维度的训练数据集构建

核心逻辑是把每个客户-产品组合作为独立的时序分析单元,通过滑动窗口构造匹配规则的训练样本:

  • 先按CUSTOMER_NUMBER、PRODUCT分组,对每个分组内的记录按季度时间顺序排序
  • 以每个季度的真实拜访量为预测目标,往前取3个季度的历史拜访量构造输入特征,完全匹配“基于最近3个季度数据预测下一季度”的需求
  • 可构造的特征包括:上一季度拜访量、上两季度拜访量、上三季度拜访量、近3个季度平均拜访量、近3个季度拜访量的环比趋势
  • 对没有连续季度记录的客户-产品组合,按实际可获取的历史值填充特征,不要强行补0
    对应的特征构造代码:
def build_group_features(group_df):
    # 组内按时间排序
    group_df = group_df.sort_values("START_DATE").reset_index(drop=True)
    # 生成滞后特征
    group_df["lag1_visit"] = group_df["REP_VISITS"].shift(1)
    group_df["lag2_visit"] = group_df["REP_VISITS"].shift(2)
    group_df["lag3_visit"] = group_df["REP_VISITS"].shift(3)
    group_df["avg_3q_visit"] = group_df[["lag1_visit", "lag2_visit", "lag3_visit"]].mean(axis=1)
    group_df["visit_trend"] = (group_df["lag1_visit"] - group_df["lag3_visit"]) / group_df["lag3_visit"].replace(0, np.nan)
    return group_df

# 批量生成所有组合的特征
feature_df = df.groupby(["CUSTOMER_NUMBER", "PRODUCT"], group_keys=False).apply(build_group_features)
# 筛选有真实目标值、有有效特征的样本作为训练集基础
train_samples = feature_df.dropna(subset=["REP_VISITS", "lag1_visit"])

三、测试集拆分与效果评估

因为是时序预测场景,绝对不能用随机打乱的方式拆分训练测试集,否则会出现数据泄漏,导致评估结果完全失真:

  • 严格按时间先后顺序拆分:将较早时段的样本作为训练集,较晚时段的样本作为测试集
    • 针对当前数据的QTR1/QTR2/QTR3三个季度,可直接把QTR1+QTR2的所有样本作为训练集,QTR3的所有样本作为测试集
    • 验证逻辑:用QTR1、QTR2的历史数据训练模型,预测QTR3的拜访量,将预测值和QTR3的真实拜访量做对比,用平均绝对误差(MAE)、均方根误差(RMSE)作为评估指标,即可得到模型的实际预测精度
  • 这种拆分方式和最终预测QTR4的场景完全一致,能真实反映模型的泛化能力
    对应的拆分代码:
# 按时间顺序拆分,无数据泄漏
train = train_samples[train_samples["QTR"].isin(["QTR1", "QTR2"])]
test = train_samples[train_samples["QTR"] == "QTR3"]

# 定义特征列和目标列
feature_cols = ["lag1_visit", "lag2_visit", "lag3_visit", "avg_3q_visit", "visit_trend"]
X_train, y_train = train[feature_cols], train["REP_VISITS"]
X_test, y_test = test[feature_cols], test["REP_VISITS"]

四、预测逻辑选择与最终预测

因为当前样本量较小,避免用复杂模型过拟合,优先选择泛化性强的简单模型,预测结果会更稳定,按精度从低到高选择即可:

  • 基线方案:直接取对应客户-产品近3个季度的平均拜访量作为QTR4的预测值,可作为精度对照基准
  • 进阶方案:用线性回归、LightGBM这类简单的树模型,在上述构造的特征上训练,通常比基线精度提升30%以上
  • 最终预测:用所有QTR1/QTR2/QTR3的样本训练模型,为需要预测的9个客户-产品组合构造对应特征(即取各组合QTR1/QTR2/QTR3的拜访量作为滞后特征),输出QTR4的预测值
    对应的目标预测样本构造代码:
# 生成需要预测的目标客户-产品组合
target_combinations = pd.DataFrame([
    ("CUST1", "PRODUCT1", "QTR4"),
    ("CUST1", "PRODUCT2", "QTR4"),
    ("CUST1", "PRODUCT3", "QTR4"),
    ("CUST2", "PRODUCT1", "QTR4"),
    ("CUST2", "PRODUCT2", "QTR4"),
    ("CUST2", "PRODUCT3", "QTR4"),
    ("CUST3", "PRODUCT3", "QTR4"),
    ("CUST4", "PRODUCT1", "QTR4"),
    ("CUST4", "PRODUCT2", "QTR4"),
], columns=["CUSTOMER_NUMBER", "PRODUCT", "QTR"])

# 匹配各组合的历史季度拜访量
pivot_df = df.pivot(index=["CUSTOMER_NUMBER", "PRODUCT"], columns="QTR", values="REP_VISITS").reset_index()
predict_feature = target_combinations.merge(pivot_df, on=["CUSTOMER_NUMBER", "PRODUCT"], how="left")

# 构造和训练集一致的特征
predict_feature["lag1_visit"] = predict_feature["QTR3"]
predict_feature["lag2_visit"] = predict_feature["QTR2"]
predict_feature["lag3_visit"] = predict_feature["QTR1"]
predict_feature["avg_3q_visit"] = predict_feature[["lag1_visit", "lag2_visit", "lag3_visit"]].mean(axis=1)
predict_feature["visit_trend"] = (predict_feature["lag1_visit"] - predict_feature["lag3_visit"]) / predict_feature["lag3_visit"].replace(0, np.nan)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.06 19:57:00