Se le classi non sono equilibrati, ma si desidera la scissione di essere equilibrata, poi la stratificazione non sta per aiutare. Non sembra essere un metodo per fare il campionamento equilibrato sklearn, ma è una specie di facile utilizzo NumPy di base, ad esempio una funzione come questa potrebbe aiutare:
def split_balanced(data, target, test_size=0.2):
classes = np.unique(target)
# can give test_size as fraction of input data size of number of samples
if test_size<1:
n_test = np.round(len(target)*test_size)
else:
n_test = test_size
n_train = max(0,len(target)-n_test)
n_train_per_class = max(1,int(np.floor(n_train/len(classes))))
n_test_per_class = max(1,int(np.floor(n_test/len(classes))))
ixs = []
for cl in classes:
if (n_train_per_class+n_test_per_class) > np.sum(target==cl):
# if data has too few samples for this class, do upsampling
# split the data to training and testing before sampling so data points won't be
# shared among training and test data
splitix = int(np.ceil(n_train_per_class/(n_train_per_class+n_test_per_class)*np.sum(target==cl)))
ixs.append(np.r_[np.random.choice(np.nonzero(target==cl)[0][:splitix], n_train_per_class),
np.random.choice(np.nonzero(target==cl)[0][splitix:], n_test_per_class)])
else:
ixs.append(np.random.choice(np.nonzero(target==cl)[0], n_train_per_class+n_test_per_class,
replace=False))
# take same num of samples from all classes
ix_train = np.concatenate([x[:n_train_per_class] for x in ixs])
ix_test = np.concatenate([x[n_train_per_class:(n_train_per_class+n_test_per_class)] for x in ixs])
X_train = data[ix_train,:]
X_test = data[ix_test,:]
y_train = target[ix_train]
y_test = target[ix_test]
return X_train, X_test, y_train, y_test
Si noti che se si utilizza questo e assaggiare più punti per classe rispetto ai dati di input, quindi quelli verranno sovracampionati (campione con sostituzione). Di conseguenza, alcuni punti dati appariranno più volte e questo potrebbe avere un effetto sulle misure di accuratezza, ecc. E se alcune classi hanno solo un punto dati, ci sarà un errore. Si può facilmente verificare il numero di punti per classe, per esempio con np.unique(target, return_counts=True)
se si vuole ancora utilizzare 'cross_validation.train_test_split' e sei su sklearn '0.17' puoi bilanciare allenamento e test, controlla la mia risposta –
Su una nota a margine, per un allenamento non bilanciato impostato con [sklearn.ensemble.RandomForestClassifier] (http://scikit-learn.org/stable /modules/generated/sklearn.ensemble.RandomForestClassifier.html#sklearn.ensemble.RandomForestClassifier) ad esempio, 'class_weight =" balanced "' può essere usato. – shadi