Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

resampling data - using SMOTE from imblearn with 3D numpy arrays

I want to resample my dataset. This consists in categorical transformed data with labels of 3 classes. The amount of samples per class are:

  • counts of class A: 6945
  • counts of class B: 650
  • counts of class C: 9066
  • TOTAl samples: 16661

The data shape without labels is (16661, 1000, 256). This means 16661 samples of (1000,256). What I would like is to up-sampling the data up to the number of samples from the majority class, that is, class A -> (6945)

However, when calling:

from imblearn.over_sampling import SMOTE
print(categorical_vector.shape)
sm = SMOTE(random_state=2)
X_train_res, y_labels_res = sm.fit_sample(categorical_vector, labels.ravel())

It keeps saying ValueError: Found array with dim 3. Estimator expected <= 2.

How can I flatten the data in a way that the estimator could fit it and that it makes sense too? Furthermore, how can I unflatten (with 3D dimension) after getting X_train_res?

like image 771
sanchezjAI Avatar asked Oct 28 '25 19:10

sanchezjAI


2 Answers

I am considering a dummy 3d array and assuming a 2d array size by myself,

arr = np.random.rand(160, 10, 25)
orig_shape = arr.shape
print(orig_shape)

Output: (160, 10, 25)

arr = np.reshape(arr, (arr.shape[0], arr.shape[1]))
print(arr.shape)

Output: (4000, 10)

arr = np.reshape(arr, orig_shape))
print(arr.shape)

Output: (160, 10, 25)

like image 133
Abdur Rehman Avatar answered Oct 31 '25 09:10

Abdur Rehman


from imblearn.over_sampling 
import RandomOverSampler 
import numpy as np 
oversample = RandomOverSampler(sampling_strategy='minority')

X could be a time stepped 3D data like X[sample,time,feature], and y like binary values for each sample. For example: (1,1),(2,1),(3,1) -> 1

X = np.array([[[1,1],[2,1],[3,1]],
             [[2,1],[3,1],[4,1]],
             [[5,1],[6,1],[7,1]],
             [[8,1],[9,1],[10,1]],
             [[11,1],[12,1],[13,1]]
             ])

y = np.array([1,0,1,1,0])

There is no way to train OVERSAMPLER with 3D X values because if you use 2D you will get back 2D data.

Xo,yo = oversample.fit_resample(X[:,:,0], y)
Xo:
[[ 1  2  3]
 [ 2  3  4]
 [ 5  6  7]
 [ 8  9 10]
 [11 12 13]
 [ 2  3  4]]

yo:
[1 0 1 1 0 0]

but if you use 2D data (sample,time,0) to fit the model, it will give back indices, and it is enough to create 3D oversampled data

oversample.fit_resample(X[:,:,0], y)
Xo = X[oversample.sample_indices_]
yo = y[oversample.sample_indices_]

Xo:
[[[ 1  1][ 2  1][ 3  1]]
 [[ 2  1][ 3  1][ 4  1]]
 [[ 5  1][ 6  1][ 7  1]]
 [[ 8  1][ 9  1][10  1]]
 [[11  1][12  1][13  1]]
 [[ 2  1][ 3  1][ 4  1]]]
yo:
[1 0 1 1 0 0]
like image 43
Gábor Kőrösi Avatar answered Oct 31 '25 09:10

Gábor Kőrösi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!