2
$\begingroup$

I have a dataset with N features, each one with 500 instances in time.

For example, let's say that I have the following:
Features x, y, v_x, v_y, a_x, a_y, j_x, j_y,
A sample with 500 examples (rows in a table) for each feature,
A sample with 500 other instances, and a class.

I'd like to select a subset of the features automatically with the Random Forests algorithm. The problem is that the algorithm (I'm using ScikitLearn, RandomForestClassifier), accepts a matrix (2D array) as X input, of size [N_samples, N_features]. If I give the array as it is, that is a vector (len 500) for the feature x, another (len 500) for the feature y, etc., I get a N_samples x N_features x 500 array, which is incompatible with the requirements of RandomForestClassifier.

I tried to unroll the matrix in a vector, like having so 500 x N_features array, but in that way, in the reduction, it considers all the elements independent feature, and breaks my structure.

How can I select/reduce the features keeping the time instances consistent?
(I can use this algorithm, but i'm also open to other libraries and/or algorithms)

My goal is to do classification, so forecasting resources are limitedly useful to me. Also I have the requirement that each sample has those occurrences, and I don't have them as separate samples unfortunately.

$\endgroup$
  • $\begingroup$ Welcome to this site! If you want to treat 500 values per feature as "all or nothing", i.e. not breaking the structure, one way is to use the average for each feature thus reducing 500 to 1. $\endgroup$ – Esmailian Mar 28 '19 at 22:16
  • $\begingroup$ But the features bring a semantic which kind of gets lost if I just do the average. But I tried a similar thing. I ran the DTW distance for each feature against the a feature-sequence of a target sample (avg of 3-4 target samples), where target's class is the one of active classes (in binarized comparison, one vs all other classes), and still no success. On the class I'm interested I get up to 0.50 precision and 1.00 recall, if I take out the difficult class out, less if I have it $\endgroup$ – user1714647 Mar 28 '19 at 22:59
  • $\begingroup$ Can you say something more about what kind of data this is? $\endgroup$ – jonnor Apr 6 '19 at 11:29
  • $\begingroup$ What is the performance when you flatten the features? Sometimes it actually works fine, with a strong enough model and enough data... $\endgroup$ – jonnor Apr 6 '19 at 11:35
1
$\begingroup$

Some EDA might be needed to create new features for each time-series item. You might want to mine for patterns and have random forest reduce the overfitting. Exactly how mining is done depends on the nature of the problem, which might indicate for things like:

  • interesting time periods,
  • events that happen at a time,
  • time lag between different series,
  • dynamical systems,
  • latent variables,
  • scedasticity

Breiman's landmark paper on random forest gives some theoretical guarantees that random forest works well when individual classifiers are good and the correlation between these individuals are low. This can also be a heuristic to prune features.

| improve this answer | |
$\endgroup$
0
$\begingroup$

If you want to preserve and utilize the 2D structure, use something like a Convolutional Neural Network. Feature selection can be done using L1 regularization. Otherwise you will have to do feature engineering outside the classifier.

This 2D structure with one axis being time is quite similar to spectrograms used in audio, where CNNs are frequently applied. So check out literature on Acoustic Event Recognition and Acoustic Scene Classification for more details.

| improve this answer | |
$\endgroup$
0
$\begingroup$

From your question I'm not sure I fully understand the nature of your data, but since you mention ScikitLearn and Random Forests and feature selection, you may be interested in the Python implementations of the Boruta all-relevant feature selection method. Boruta is based on Random Forests, automatically selects important features and is based on SciKit methods. If you can shoehorn your data into this framework, it might answer your needs.

| improve this answer | |
$\endgroup$
0
$\begingroup$

Check out the example here. Just modify to suit your specific data-set.

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()

enter image description here

All details are available here.

http://blog.yhat.com/tutorials/5-Feature-Engineering.html

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.