sklearn loocv.split返回一个比预期更小的测试和训练阵列

时间:2017-11-20 10:53:30

标签: python scikit-learn cross-validation

由于我有一个小数据集,我在LOOCV使用sklearn(在交叉验证中保留一个)。

当我运行分类器时,我收到以下错误:

"Number of labels=41 does not match number of samples=42"

我使用以下代码生成了测试和训练集:

otu_trans = test_train.transpose()
# transpose otu table 
merged = pd.concat([otu_trans, metadata[status]], axis=1, join='inner')
# merge phenotype column from metadata file with transposed otu table

X = merged.drop([status],axis=1)

# drop status from X 
y = merged[status]


encoder = LabelEncoder()
y = pd.Series(encoder.fit_transform(y),
index=y.index, name=y.name)
# convert T and TF lables to 0 and 1 respectively

loocv = LeaveOneOut()
loocv.get_n_splits(X)

for train_index, test_index in loocv.split(X):
    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]
    print(X_train, X_test, y_train, y_test)

input data

当我检查X_trainX_test的形状时,我认为它应该是42,41而不是41,257,因此看起来数据正在被分割错误的轴。

任何人都可以向我解释为什么会这样吗?

谢谢

1 个答案:

答案 0 :(得分:0)

首先,初始矩阵X根本不受影响。 它仅用于生成索引并拆分数据。

初始X的形状将始终相同。

现在,这是一个使用LOOCV拆分的简单示例

import numpy as np
from sklearn.model_selection import LeaveOneOut

# I produce fake data with same dimensions as yours.
#fake data
X = np.random.rand(41,257)
#fake labels
y = np.random.rand(41)

#Now check that the shapes are correct:
X.shape
y.shape

这会给你:

(41, 257)
(41,)

现在拆分

loocv = LeaveOneOut()
loocv.get_n_splits(X)

for train_index, test_index in loocv.split(X):
    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]

    #classifier.fit(X_train, y_train)
    #classifier.predict(X_test)


X_train.shape
X_test.shape

打印:

(40, 257)
(1, 257)

如您所见,X_train包含40个样本,而X_test仅包含1个样本。这是正确的,因为我们使用LOOCV拆分。

初始X矩阵共有42个样本,所以我们使用41个进行训练,1个进行测试。

此循环将生成大量X_trainX_test矩阵。具体而言,它将生成N = N的{​​{1}}矩阵(在我们的例子中为number of samples)。

N = 41等于N

希望这有帮助