개발/Python

[파이썬] scikit-learn에서 계층화된 학습/테스트 분할

MinorMan 2022. 10. 24. 03:57
반응형

<질문>

데이터를 훈련 세트(75%)와 테스트 세트(25%)로 분할해야 합니다. 나는 현재 아래 코드로 그렇게 한다.

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

그러나 훈련 데이터 세트를 계층화하고 싶습니다. 어떻게 해야 하나요? 나는 ~에 대해 조사했다StratifiedKFold방법이지만 75%/25% 분할을 지정하지 않고 교육 데이터 세트만 계층화할 수 있습니다.


<답변1>

[0.17 업데이트]

의 문서를 참조하십시오.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 업데이트]

풀 리퀘스트가 있습니다here. 그러나 당신은 단순히 할 수 있습니다train, test = next(iter(StratifiedKFold(...)))원하는 경우 기차 및 테스트 인덱스를 사용하십시오.


<답변2>

TL;DR : 사용StratifiedShuffleSplit~와 함께test_size=0.25

Scikit-learn은 계층 분할을 위한 두 가지 모듈을 제공합니다.

  1. StratifiedKFold: 이 모듈은 직접 k-겹 교차 검증 연산자로 유용합니다.n_folds클래스가 양쪽에서 동등하게 균형을 이루도록 훈련/테스트 세트.

다음은 일부 코드(위 문서에서 직접)

>>> 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: 이 모듈은 균등하게 균형잡힌(계층화된) 클래스를 갖는 단일 교육/테스트 세트를 생성합니다. 본질적으로 이것은 당신이 원하는 것입니다n_iter=1. 여기에서와 같이 테스트 크기를 언급할 수 있습니다.train_test_split

암호:

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

<답변3>

당신은 단순히 그것을 할 수 있습니다train_test_split()Scikit에서 사용할 수 있는 방법 학습:

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

또한 방법을 보여주는 짧은 GitHub Gist를 준비했습니다.stratify옵션 작동:

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


<답변4>

다음은 연속/회귀 데이터의 예입니다.this issue on GitHub해결됨).

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
)
  • 어디에start최소이고stop연속 목표의 최대값입니다.
  • 설정하지 않으면right=True그러면 최대 값을 별도의 빈으로 만들 수 있으며 해당 추가 빈에 샘플이 너무 적기 때문에 분할은 항상 실패합니다.

<답변5>

@Andreas Mueller가 수락한 답변 외에도 위에서 언급한 @tangy와 같이 추가하고 싶습니다.

StratifiedShuffleSplit가장 흡사하다train_test_split(stratify = y) 다음과 같은 기능이 추가되었습니다.

  1. 충이 되다기본적으로
  2. 지정하여n_split, 반복적으로 데이터를 분할합니다.

<답변6>

StratifiedShuffleSplit은 생성하려는 모든 작은 데이터 세트에서 고르게 표현되어야 하는 열을 선택한 후에 수행됩니다. '폴드는 각 클래스에 대한 샘플의 백분율을 유지하여 만들어집니다.'

'season' 열이 있는 데이터 세트 'data'가 있고 'season'의 균일한 표현을 원한다고 가정하면 다음과 같습니다.

from sklearn.model_selection import StratifiedShuffleSplit
sss=StratifiedShuffleSplit(n_splits=1,test_size=0.25,random_state=0)

for train_index, test_index in sss.split(data, data["season"]):
    sss_train = data.iloc[train_index]
    sss_test = data.iloc[test_index]

<답변7>

따라서 원본 데이터 세트에서 관찰된 것과 같이 각 클래스의 동일한 비율을 유지하는 방식으로 데이터 세트를 훈련 세트와 테스트 세트로 분할하는 것이 바람직합니다.

이것을 계층화된 기차-테스트 분할이라고 합니다.

"stratify" 인수를 원본 데이터세트의 y 구성요소로 설정하여 이를 달성할 수 있습니다. 이는 train_test_split() 함수에서 사용하여 훈련 세트와 테스트 세트 모두 제공된 "y" 배열에 있는 각 클래스의 예제 비율을 갖도록 합니다.


<답변8>

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

<답변9>

@tangy 답변을 scikit-learn의 현재 버전으로 업데이트: 0.23.2(StratifiedShuffleSplit documentation).

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]
반응형