Scikit-learn'de Katmanlı Tren / Test-split


95

Verilerimi bir eğitim setine (% 75) ve test setine (% 25) bölmem gerekiyor. Şu anda bunu aşağıdaki kodla yapıyorum:

X, Xt, userInfo, userInfo_train = sklearn.cross_validation.train_test_split(X, userInfo)   

Ancak, eğitim veri kümemi katmanlara ayırmak istiyorum. Bunu nasıl yaparım? StratifiedKFoldYönteme bakıyordum , ancak% 75 /% 25'lik dağılımı belirlememe ve yalnızca eğitim veri setini katmanlaştırmama izin vermiyor.

Yanıtlar:


161

[0.17 için güncelleme]

Aşağıdaki dokümanlara bakın sklearn.model_selection.train_test_split:

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y,
                                                    stratify=y, 
                                                    test_size=0.25)

[/ 0.17 için güncelleme]

Burada bir çekme talebi var . Ancak isterseniz train, test = next(iter(StratifiedKFold(...))) tren ve test endekslerini kolayca yapabilir ve kullanabilirsiniz.


1
@AndreasMueller Regresyon verilerini tabakalandırmanın kolay bir yolu var mı?
Ürdün

3
@Jordan scikit-learn'de hiçbir şey uygulanmaz. Standart bir yol bilmiyorum. Yüzdelik dilimleri kullanabiliriz.
Andreas Mueller

@AndreasMueller Bu yöntemin StratifiedShuffleSplit'ten çok daha yavaş olduğu davranışı hiç gördünüz mü? MNIST veri kümesini kullanıyordum.
activatedgeek

train_test_split (... stratify =) sadece StratifiedShuffleSplit'i çağırdığı ve ilk bölünmeyi aldığı için @activatedgeek çok garip görünüyor. Tekrarlanabilir bir örnekle izleyicide bir sorun açabilirsiniz.
Andreas Mueller

@AndreasMueller Aslında bir sorunu açmadım çünkü güçlü bir his var, yanlış bir şey yaptığımı hissediyorum (sadece 2 satır olmasına rağmen). Ama onu bugün hala birkaç kez yeniden üretebiliyorsam, bunu yapacağım!
activatedgeek

29

TL; DR: StratifiedShuffleSplit iletest_size=0.25

Scikit-learn, Katmanlı Bölme için iki modül sağlar:

  1. StratifiedKFold : Bu modül, doğrudan k-kat çapraz doğrulama operatörü olarak kullanışlıdır: içinde olduğu n_foldsgibi, sınıfların her ikisinde de eşit olarak dengeleneceği şekilde eğitim / test setleri kuracaktır .

İşte bazı kodlar (doğrudan yukarıdaki belgelerden)

>>> skf = cross_validation.StratifiedKFold(y, n_folds=2) #2-fold cross validation
>>> len(skf)
2
>>> for train_index, test_index in skf:
...    print("TRAIN:", train_index, "TEST:", test_index)
...    X_train, X_test = X[train_index], X[test_index]
...    y_train, y_test = y[train_index], y[test_index]
...    #fit and predict with X_train/test. Use accuracy metrics to check validation performance
  1. StratifiedShuffleSplit : Bu modül, eşit olarak dengelenmiş (tabakalı) sınıflara sahip tek bir eğitim / test seti oluşturur. Esasen bu,n_iter=1 . Test boyutundan burada olduğu gibi bahsedebilirsiniz.train_test_split

Kod:

>>> sss = StratifiedShuffleSplit(y, n_iter=1, test_size=0.5, random_state=0)
>>> len(sss)
1
>>> for train_index, test_index in sss:
...    print("TRAIN:", train_index, "TEST:", test_index)
...    X_train, X_test = X[train_index], X[test_index]
...    y_train, y_test = y[train_index], y[test_index]
>>> # fit and predict with your classifier using the above X/y train/test

5
Not itibariyle bu 0.18.x, n_iterolması gerektiği n_splitsiçin StratifiedShuffleSplit - ve bunun için biraz farklı bir API var: scikit-learn.org/stable/modules/generated/...
lollercoaster

2
Eğer ybir Pandalar Serisi, kullanımıy.iloc[train_index], y.iloc[test_index]
Owlright

1
@Owlright Pandas veri çerçevesi kullanmayı denedim ve StratifiedShuffleSplit'in döndürdüğü endeksler veri çerçevesindeki endeksler değil. dataframe index: 2,3,5 the first split in sss:[(array([2, 1]), array([0]))]:(
Meghna Natraj

2
@tangy bu neden bir for döngüsü? bir satır X_train, X_test = X[train_index], X[test_index]çağrıldığında geçersiz kılınması X_trainve X_test? O zaman neden sadece bir tek değil next(sss)?
Bartek Wójcik

13

Bunu train_test_split()Scikit'te bulunan yöntemle kolayca yapabilirsiniz öğrenin:

from sklearn.model_selection import train_test_split 
train, test = train_test_split(X, test_size=0.25, stratify=X['YOUR_COLUMN_LABEL']) 

Ayrıca stratifyseçeneğin nasıl çalıştığını gösteren kısa bir GitHub Gist'i hazırladım :

https://gist.github.com/SHi-ON/63839f3a3647051a180cb03af0f7d0d9


13

İşte sürekli / regresyon verileri için bir örnek ( GitHub'daki bu sorun çözülene kadar).

min = np.amin(y)
max = np.amax(y)

# 5 bins may be too few for larger datasets.
bins     = np.linspace(start=min, stop=max, num=5)
y_binned = np.digitize(y, bins, right=True)

X_train, X_test, y_train, y_test = train_test_split(
    X, 
    y, 
    stratify=y_binned
)
  • startMin nerede vestopSürekli hedefinizin maksimum .
  • Ayarlamazsanız right=True, maksimum değerinizi az çok ayrı bir bölme haline getirir ve bölmeniz her zaman başarısız olur çünkü bu fazladan bölmede çok az örnek olacaktır.

6

@Andreas Mueller tarafından kabul edilen cevaba ek olarak, bunu yukarıda belirtilen @tangy olarak eklemek istiyorum:

StratifiedShuffleSplit , aşağıdaki ek özelliklerle birlikte train_test_split ( stratify = y) 'e en çok benzer :

  1. varsayılan olarak katmanlaştırmak
  2. n_splits belirterek , verileri tekrar tekrar böler

0
#train_size is 1 - tst_size - vld_size
tst_size=0.15
vld_size=0.15

X_train_test, X_valid, y_train_test, y_valid = train_test_split(df.drop(y, axis=1), df.y, test_size = vld_size, random_state=13903) 

X_train_test_V=pd.DataFrame(X_train_test)
X_valid=pd.DataFrame(X_valid)

X_train, X_test, y_train, y_test = train_test_split(X_train_test, y_train_test, test_size=tst_size, random_state=13903)

0

Yukarıdaki @tangy yanıtını scikit-learn'ün güncel sürümüne güncelleme: 0.23.2 ( StratifiedShuffleSplit belgeleri ).

from sklearn.model_selection import StratifiedShuffleSplit

n_splits = 1  # We only want a single split in this case
sss = StratifiedShuffleSplit(n_splits=n_splits, test_size=0.25, 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]
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.