我需要将数据分成训练集(75%)和测试集(25%)。我目前使用以下代码执行此操作:
X, Xt, userInfo, userInfo_train = sklearn.cross_validation.train_test_split(X, userInfo)
然而,我想将我的训练数据集分层。我该怎么做?我一直在研究StratifiedKFold
方法,但它不允许我指定75%/25%的分割,并且只对训练数据集进行分层。
我需要将数据分成训练集(75%)和测试集(25%)。我目前使用以下代码执行此操作:
X, Xt, userInfo, userInfo_train = sklearn.cross_validation.train_test_split(X, userInfo)
然而,我想将我的训练数据集分层。我该怎么做?我一直在研究StratifiedKFold
方法,但它不允许我指定75%/25%的分割,并且只对训练数据集进行分层。
[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]
这里有一个拉取请求。但是如果您愿意,您可以简单地执行train, test = next(iter(StratifiedKFold(...)))
并使用训练和测试索引。
您可以使用Scikit learn中提供的train_test_split()
方法来轻松完成此操作:
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
简述:使用StratifiedShuffleSplit和test_size=0.25
进行分层抽样。
Scikit-learn提供了两个模块用于分层抽样:
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
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
0.18.x
开始,StratifiedShuffleSplit
中的n_iter
应替换为n_splits
,同时它的API也稍有不同:http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.StratifiedShuffleSplit.html - lollercoastery
是一个Pandas序列,使用y.iloc[train_index], y.iloc[test_index]
。 - Owlrightdataframe索引:2、3、5
sss中的第一个分割:[(array([2, 1]), array([0]))]
:( - Meghna NatrajX_train, X_test = X[train_index], X[test_index]
这一行时,它不是会覆盖 X_train
和 X_test
吗?那么为什么不只用一个 next(sss)
呢? - Bartek Wójcik这是一个连续/回归数据的例子(直到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
,那么它将或多或少地使您的最大值成为一个单独的bin,并且您的分割将始终失败,因为那个额外的bin中的样本太少。StratifiedShuffleSplit最接近train_test_split(stratify = y),并增加了以下功能:
在我们选择应在所有即将生成的小数据集中均匀表示的列之后,会使用StratifiedShuffleSplit进行操作。 '折叠是通过保留每个类别样本的百分比来完成的。
假设我们有一个名为'data'的数据集,其中包含一个名为'season'的列,并且我们希望获得'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]
#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)
更新@tangy的答案,以适应当前版本的scikit-learn:0.23.2(StratifiedShuffleSplit文档)。
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]