拆分 k 折,其中每折验证数据不包含重复项
Split k-fold where each fold of validation data doesn't include duplicates
假设我有一个 pandas 数据框 df
。 df
包含 1,000 行。如下所示。
print(df)
id class
0 0000799a2b2c42d 0
1 00042890562ff68 0
2 0005364cdcb8e5b 0
3 0007a5a46901c56 0
4 0009283e145448e 0
... ... ...
995 04309a8361c5a9e 0
996 0430bde854b470e 0
997 0431c56b712b9a5 1
998 043580af9803e8c 0
999 043733a88bfde0c 0
它有 950 个数据作为 class 0
和 50 个数据作为 class 1
。
现在我想再添加一列 fold
,如下所示。
id class fold
0 0000799a2b2c42d 0 0
1 00042890562ff68 0 0
2 0005364cdcb8e5b 0 0
3 0007a5a46901c56 0 0
4 0009283e145448e 0 0
... ... ... ...
995 04309a8361c5a9e 0 4
996 0430bde854b470e 0 4
997 0431c56b712b9a5 1 4
998 043580af9803e8c 0 4
999 043733a88bfde0c 0 4
其中 fold
列包含 5 个折叠 (0,1,2,3,4)。每折有200个数据,其中190个数据为class 0
,10个数据为class 1
(即保留每个class
的样本百分比)。
我试过 StratifiedShuffleSplit
来自 sklearn.model_selection
,如下所示。
sss = StratifiedShuffleSplit(n_split=5, random_state=2021, test_size = 0.2)
for _, val_index in sss.split(df.id, df.class):
....
然后我将 val_index
的每个列表视为一个特定的折叠,但它最终在每个 val_index
.
中给我重复项
有人可以帮助我吗?
您需要的是用于交叉验证的 kfold,而不是训练测试拆分。你可以使用StratifiedKFold
,比如你的数据集是这样的:
import pandas as pd
import numpy as np
from sklearn.model_selection import StratifiedKFold
np.random.seed(12345)
df = pd.DataFrame({'id' : np.random.randint(1,1e5,1000),
'class' :np.random.binomial(1,0.1,1000)})
df['fold'] = np.NaN
我们使用 kfold,像您一样遍历并分配折叠数:
skf = StratifiedKFold(n_splits=5,shuffle=True)
for fold, [train,test] in enumerate(skf.split(df,df['class'])):
df.loc[test,"fold"] = fold
最终产品:
pd.crosstab(df['fold'],df['class'])
class 0 1
fold
0.0 182 18
1.0 182 18
2.0 182 18
3.0 182 18
4.0 181 19
假设我有一个 pandas 数据框 df
。 df
包含 1,000 行。如下所示。
print(df)
id class
0 0000799a2b2c42d 0
1 00042890562ff68 0
2 0005364cdcb8e5b 0
3 0007a5a46901c56 0
4 0009283e145448e 0
... ... ...
995 04309a8361c5a9e 0
996 0430bde854b470e 0
997 0431c56b712b9a5 1
998 043580af9803e8c 0
999 043733a88bfde0c 0
它有 950 个数据作为 class 0
和 50 个数据作为 class 1
。
现在我想再添加一列 fold
,如下所示。
id class fold
0 0000799a2b2c42d 0 0
1 00042890562ff68 0 0
2 0005364cdcb8e5b 0 0
3 0007a5a46901c56 0 0
4 0009283e145448e 0 0
... ... ... ...
995 04309a8361c5a9e 0 4
996 0430bde854b470e 0 4
997 0431c56b712b9a5 1 4
998 043580af9803e8c 0 4
999 043733a88bfde0c 0 4
其中 fold
列包含 5 个折叠 (0,1,2,3,4)。每折有200个数据,其中190个数据为class 0
,10个数据为class 1
(即保留每个class
的样本百分比)。
我试过 StratifiedShuffleSplit
来自 sklearn.model_selection
,如下所示。
sss = StratifiedShuffleSplit(n_split=5, random_state=2021, test_size = 0.2)
for _, val_index in sss.split(df.id, df.class):
....
然后我将 val_index
的每个列表视为一个特定的折叠,但它最终在每个 val_index
.
有人可以帮助我吗?
您需要的是用于交叉验证的 kfold,而不是训练测试拆分。你可以使用StratifiedKFold
,比如你的数据集是这样的:
import pandas as pd
import numpy as np
from sklearn.model_selection import StratifiedKFold
np.random.seed(12345)
df = pd.DataFrame({'id' : np.random.randint(1,1e5,1000),
'class' :np.random.binomial(1,0.1,1000)})
df['fold'] = np.NaN
我们使用 kfold,像您一样遍历并分配折叠数:
skf = StratifiedKFold(n_splits=5,shuffle=True)
for fold, [train,test] in enumerate(skf.split(df,df['class'])):
df.loc[test,"fold"] = fold
最终产品:
pd.crosstab(df['fold'],df['class'])
class 0 1
fold
0.0 182 18
1.0 182 18
2.0 182 18
3.0 182 18
4.0 181 19