2017-03-07 39 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有2562

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

我應該如何着手獲得1階級和階級0每個樣品2500在我的訓練集。 (和測試集也是25000)

+0

「X」的實際大小是多少? –

回答

1

由於您沒有提供給我們數據集,我使用的模擬數據生成的手段爲make_blobs。從你的問題來看,還不清楚應該有多少測試樣品。我已經定義了test_samples = 50000,但您可以更改此值以適合您的需求。

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

如下片段分割數據分成訓練集和測試具有平衡類:

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) 

編輯

由於@geompalik正確地指出,如果數據集不平衡StratifiedShuffleSplit不會產生均衡的分裂。在這種情況下,你可能會發現這個功能很有用:

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這很容易完成。儘管你描述的分裂幾乎是平衡的。

相關問題