时间序列数据上的随机森林特征选择

数据挖掘 Python scikit-学习 时间序列 特征选择 随机森林
2022-02-17 22:33:54

我有一个包含 N 个特征的数据集,每个特征都有 500 个时间实例。

例如,假设我有以下内容:
Features x, y, v_x, v_y, a_x, a_y, j_x, j_y
每个特征包含 500 个示例(表中的行)
的样本,具有 500 个其他实例的样本和一个类。

我想使用随机森林算法自动选择特征的子集。问题是该算法(我使用的是 ScikitLearn,RandomForestClassifier)接受一个矩阵(二维数组)作为 X 输入,大小为 [N_samples,N_features]。如果我按原样给出数组,即特征的向量(len 500),特征x的另一个向量(len 500)y等,我得到一个 N_samples x N_features x 500 数组,这与要求不兼容随机森林分类器。

我试图在一个向量中展开矩阵,就像拥有 500 x N_features 数组一样,但这样一来,在缩减过程中,它考虑了所有元素的独立特征,并打破了我的结构。

如何选择/减少保持时间实例一致的特征
(我可以使用这个算法,但我也对其他库和/或算法开放)

我的目标是进行分类,因此预测资源对我的用处有限。我还要求每个样本都有这些事件,不幸的是我没有将它们作为单独的样本。

4个回答

可能需要一些 EDA 来为每个时间序列项目创建新功能。您可能想要挖掘模式并让随机森林减少过度拟合。究竟如何进行挖掘取决于问题的性质,这可能表明:

  • 有趣的时间段,
  • 一次发生的事件,
  • 不同系列之间的时间滞后,
  • 动力系统,
  • 潜变量,
  • 奇异性

Breiman 关于随机森林的里程碑式论文提供了一些理论保证,即当个体分类器良好且这些个体之间的相关性较低时,随机森林运行良好。这也可以是修剪特征的启发式方法。

如果您想保留和利用 2D 结构,请使用卷积神经网络之类的东西。可以使用 L1 正则化来完成特征选择。否则,您将不得不在分类器之外进行特征工程。

这种以时间为轴的 2D 结构与音频中使用的频谱图非常相似,其中经常应用 CNN。因此,请查看有关声学事件识别和声学场景分类的文献以获取更多详细信息。

根据您的问题,我不确定我是否完全理解您的数据的性质,但是由于您提到 ScikitLearn 和随机森林以及特征选择,您可能对Boruta all-relevant feature selection method 的 Python 实现感兴趣。Boruta 基于随机森林,自动选择重要特征,基于 SciKit 方法。如果您可以将数据硬塞到这个框架中,它可能会满足您的需求。

在此处查看示例。只需修改以适合您的特定数据集。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# matplotlib inline

df = pd.read_csv("https://rodeo-tutorials.s3.amazonaws.com/data/credit-data-trainingset.csv")
df.head()

from sklearn.ensemble import RandomForestClassifier

features = np.array(['revolving_utilization_of_unsecured_lines',
                     'age', 'number_of_time30-59_days_past_due_not_worse',
                     'debt_ratio', 'monthly_income','number_of_open_credit_lines_and_loans', 
                     'number_of_times90_days_late', 'number_real_estate_loans_or_lines',
                     'number_of_time60-89_days_past_due_not_worse', 'number_of_dependents'])
clf = RandomForestClassifier()
clf.fit(df[features], df['serious_dlqin2yrs'])

# from the calculated importances, order them from most to least important
# and make a barplot so we can visualize what is/isn't important
importances = clf.feature_importances_
sorted_idx = np.argsort(importances)


padding = np.arange(len(features)) + 0.5
plt.barh(padding, importances[sorted_idx], align='center')
plt.yticks(padding, features[sorted_idx])
plt.xlabel("Relative Importance")
plt.title("Variable Importance")
plt.show()

在此处输入图像描述

所有详细信息都可以在这里找到