2017-03-07 14 views
0

私はバイナリクラスラベルを持つデータセットを持っています。データセットからバランスのとれたクラスのサンプルを抽出したいと思います。以下に書いたコードは、私に不均衡なデータセットを与えます。sklearnの不均衡なデータセットからバランスの取れたサンプルを取得するには?

sss = StratifiedShuffleSplit(train_size=5000, n_splits=1, test_size=50000, random_state=0) 
for train_index, test_index in sss.split(X, y): 
     X_train, X_test = X[train_index], X[test_index] 
     y_train, y_test = y[train_index], y[test_index] 
     print(itemfreq(y_train)) 

あなたはそのクラス0は2438のサンプルとクラス1を持って見ることができるように、私は私のトレーニングセットで2500クラス1のサンプルとクラス0それぞれを取得するために進むべき方法2562.

[[ 0.00000000e+00 2.43800000e+03] 
[ 1.00000000e+00 2.56200000e+03]] 

を持っています。 (また、25000のテストセットもあります)

+0

「X」の実際のサイズはどれくらいですか? –

答えて

1

あなたに私たちにデータセットを提供しなかったので、make_blobsによって生成されたモックデータを使用しています。あなたの質問から、どのくらい多くのテストサンプルがあるべきかは不明です。私はtest_samples = 50000を定義しましたが、あなたのニーズに合わせてこの値を変更することができます。

from sklearn.model_selection import StratifiedShuffleSplit  

sss = StratifiedShuffleSplit(train_size=train_samples, n_splits=1, 
          test_size=test_samples, random_state=0) 

for train_index, test_index in sss.split(X, y): 
    X_train, X_test = X[train_index], X[test_index] 
    y_train, y_test = y[train_index], y[test_index] 

デモ

In [54]: from scipy import stats 

In [55]: stats.itemfreq(y_train) 
Out[55]: 
array([[ 0, 2500], 
     [ 1, 2500]], dtype=int64) 

In [56]: stats.itemfreq(y_test) 
Out[56]: 
array([[ 0, 25000], 
     [ 1, 25000]], dtype=int64) 

sklearnインポートデータセットから

train_samples = 5000 
test_samples = 50000 
total_samples = train_samples + train_samples 
X, y = datasets.make_blobs(n_samples=total_samples, centers=2, random_state=0) 

次のスニペットは、バランスの取れたクラスで電車やテストにデータを分割しますあなたのデータセットがStratifiedShuffleSplitバランスの分割を得られませんアンバランスであれば

EDIT

としては正しく、指摘@geompalik。その場合、あなたは便利なこの機能を見つけるかもしれない:

def stratified_split(y, train_ratio): 

    def split_class(y, label, train_ratio): 
     indices = np.flatnonzero(y == label) 
     n_train = int(indices.size*train_ratio) 
     train_index = indices[:n_train] 
     test_index = indices[n_train:] 
     return (train_index, test_index) 

    idx = [split_class(y, label, train_ratio) for label in np.unique(y)] 
    train_index = np.concatenate([train for train, _ in idx]) 
    test_index = np.concatenate([test for _, test in idx]) 
    return train_index, test_index 

デモ

私はpreviuosulyあなたが示されたクラスあたりのサンプル数(コードここでは図示せず)とのモックデータを生成しました。

In [153]: y 
Out[153]: array([1, 0, 1, ..., 0, 0, 1]) 

In [154]: y.size 
Out[154]: 55000 

In [155]: train_ratio = float(train_samples)/(train_samples + test_samples) 

In [156]: train_ratio 
Out[156]: 0.09090909090909091 

In [157]: train_index, test_index = stratified_split(y, train_ratio) 

In [158]: y_train = y[train_index] 

In [159]: y_test = y[test_index] 

In [160]: y_train.size 
Out[160]: 5000 

In [161]: y_test.size 
Out[161]: 50000 

In [162]: stats.itemfreq(y_train) 
Out[162]: 
array([[ 0, 2438], 
     [ 1, 2562]], dtype=int64) 

In [163]: stats.itemfreq(y_test) 
Out[163]: 
array([[ 0, 24380], 
     [ 1, 25620]], dtype=int64) 
+0

私のデータセットは不均衡です。不均衡なデータセットからバランスクラスを取得するにはどうすればよいですか。 –

+0

質問は少し異なります。この戦略は、不均衡なデータセットのバランスの取れた分割を定義によって達成することはできません。 – geompalik

1

問題がStratifiedShuffleSplit方法あなたが定義(成層)によってクラスの割合を保存することによって、定義分割によって使用することです。

StratifiedShuffleSplitを使用して目的を達成する簡単な方法は、ドミナントクラスを最初にサブサンプルして、最初のデータセットを均衡させてから続行することです。 numpyを使うとこれは簡単に達成できます。あなたが記述する分割はほとんどバランスがとれていますが。

関連する問題