我在使用sklearn中的train_test_split()
时感到困惑。以下是我尝试过的一个代码片段:
X = example_df.drop('features', axis=1)y = example_df['price']y_test, X_train, X_test, y_train= train_test_split(X, y, test_size=0.2)
train_test_split()
是如何分割example_df
的行的?example_df
有100行,所以我期望数据集的分割大小如下:
-
y_test
应该有80行 -
X_train
应该有20行 -
X_test
应该有80行 -
y_train
应该有20行
但是我的数据集的实际大小分别是:20, 20, 80, 20。
这是为什么呢?
回答:
在这种情况下,你应该使用的正确变量赋值顺序是X_train, X_test, y_train, y_test
。也就是说,你需要重写你的代码为
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
多重赋值解包
此外,我怀疑你的困惑还可能来自于对python中多重赋值解包工作原理的误解,以及train_test_split(...)
的返回值。
让我们考虑给train_test_split(...)
传递一个数组进行分割,例如y = [0, 1, 2, 3, 4]
。train_test_split(y)
的输出会类似于[[0, 1, 2], [3, 4]]
(加上或减去一些随机排序)。我们看到它接收我们的原始列表并返回一个包含2个列表的列表。
我们可以向train_test_split(...)
传递任意数量的列表进行分割。所以让我们看看如果我们给train_test_split(...)
传递2个列表(list_1
, list_2
)作为输入会发生什么。它将返回一个包含4个列表的列表。前两个内部列表将是list_1
的训练集,然后是list_1
的测试集,最后两个内部列表将是list_2
的训练集,然后是list_2
的测试集。然而,返回的列表并不对应于任何关键字如”X_train”或”x_test”,它们只是普通的列表。
处理输出的一种方法如下:
datasets = train_test_split(list_1, list_2)list_1_train = datasets[0]list_1_test = datasets[1]list_2_train = datasets[2]list_2_test = datasets[3]
但是这种方法冗长、重复且容易出错。幸运的是,python提供了语法让我们可以在一行中解包多个变量并进行赋值。以上述代码片段中赋值四个列表的等价方式是这样的:
[list_1_train, list_1_test, list_2_train, list_2_test] = train_test_split(list_1, list_2)
或者使用更多的语法糖:
list_1_train, list_1_test, list_2_train, list_2_test = train_test_split(list_1, list_2)