You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

无标签高维时间序列数据的特征重要性提取方法求助

解决无标签时序数据集的特征重要性分析问题

首先得明确核心问题:无标签场景下用回归器做特征重要性,关键是把时序数据转化为自监督的预测任务——因为时序数据天然自带时间维度,我们可以构造"用过去的特征预测未来行为"的伪标签任务,这样监督模型输出的特征重要性,就能反映哪些特征对时序变化更有贡献,也就是你要找的"具备时序特性的有效特征"。

先说说你之前代码里的几个问题:

  • 变量混淆:用xgb.train()得到的是原生XGBoost模型,不能直接调用xgb.feature_importances_(那是scikit-learn封装的XGBRegressor的属性)
  • 标签选择不合理:随便拿某一列当y不符合无标签场景的逻辑,应该基于时序规律构造伪标签
  • 样本量太小:23个时间步用来训练树模型很容易过拟合,需要调整模型参数或换用更适合小样本的方法

下面给你具体的可行方案:

方案1:基于自监督时序预测的XGBoost特征重要性

假设你的df3行是时间步(共23个),列是14291个特征,我们构造"用当前时刻特征预测下一个时刻整体行为强度"的任务,模型认为重要的特征就是具备时序特性的特征。

步骤1:构造有监督数据集

import pandas as pd
import numpy as np

# X:前22个时间步的所有特征(用来预测下一个时刻)
X = df3.iloc[:-1, :].values  # 形状(22, 14291)
# y:每个时间步的下一个时刻,所有特征的总和(代表整体行为强度,作为伪标签)
y = df3.iloc[1:, :].sum(axis=1).values  # 形状(22,)

步骤2:用Scikit-learn版XGBRegressor训练(更易获取特征重要性)

原生XGBoost的train()方法获取重要性需要用get_fscore(),而scikit-learn接口更直观:

from xgboost import XGBRegressor
import matplotlib.pyplot as plt

# 调整参数避免过拟合(样本量极小,必须限制模型复杂度)
model = XGBRegressor(
    objective="reg:squarederror",
    max_depth=2,  # 减小树深
    learning_rate=0.05,
    gamma=1,  # 增加gamma,减少不必要的分裂
    n_estimators=50,
    random_state=42
)
model.fit(X, y)

# 整理特征重要性并排序
feature_importance = pd.DataFrame({
    'feature': df3.columns,
    'importance': model.feature_importances_
}).sort_values('importance', ascending=False)

# 可视化前20个重要特征
plt.figure(figsize=(10, 8))
plt.barh(feature_importance['feature'].head(20), feature_importance['importance'].head(20))
plt.xlabel("XGBoost Feature Importance")
plt.gca().invert_yaxis()
plt.show()

步骤3:筛选特征

你可以根据业务需求设置阈值,比如保留重要性大于0.001的特征,或者直接取前N个重要特征。

方案2:小样本友好的Lasso回归特征重要性

因为你的样本量只有22个,树模型容易过拟合,用带L1正则化的Lasso回归可以得到稀疏系数,系数绝对值大的特征就是重要的:

from sklearn.linear_model import Lasso
from sklearn.preprocessing import StandardScaler

# Lasso对特征尺度敏感,先标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 初始化模型,调整alpha控制正则化强度
lasso = Lasso(alpha=0.1, random_state=42)
lasso.fit(X_scaled, y)

# 整理特征重要性(系数绝对值)
lasso_importance = pd.DataFrame({
    'feature': df3.columns,
    'importance': np.abs(lasso.coef_)
}).sort_values('importance', ascending=False)

# 筛选系数不为0的特征(Lasso会自动把不重要的特征系数压缩到0)
valid_features = lasso_importance[lasso_importance['importance'] > 0]['feature'].tolist()
df_filtered = df3[valid_features]

补充:非监督时序特征筛选方法

如果不想用监督模型,也可以直接针对每个特征的时序特性筛选:

  • 删除低方差特征:几乎没有变化的特征直接排除
    var_threshold = 0.1  # 根据你的数据调整阈值
    high_var_features = df3.columns[df3.var() > var_threshold].tolist()
    
  • 删除低自相关特征:没有时序相关性的特征排除
    autocorr_threshold = 0.2  # 调整阈值
    high_autocorr_features = []
    for col in df3.columns:
        autocorr = df3[col].autocorr(lag=1)
        if np.abs(autocorr) > autocorr_threshold:
            high_autocorr_features.append(col)
    

关键注意事项

  1. 样本量限制:你的原始数据只有23个时间步,构造监督任务后只有22个样本,任何监督模型的结果都可能不稳定,建议结合非监督方法互相验证。
  2. 任务对齐:确保你构造的伪标签任务和业务需求一致——比如如果要保留"能反映用户行为随时间变化的特征",用"预测下一个时刻行为强度"是合理的;如果要保留"能区分不同时间阶段的特征",可以先对时间步聚类,再用分类模型计算特征重要性。

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

火山引擎 最新活动