我正在阅读 Hands on Machine Learning 这本书,作者谈到了训练和测试拆分期间的随机种子,在某个时间点,作者说在此期间机器会看到你的整个数据集。
作者正在使用以下函数来划分 Tran 和 Test 拆分,
def split_train_test(data, test_ratio):
shuffled_indices = np.random.permutation(len(data))
test_set_size = int(len(data) * test_ratio)
test_indices = shuffled_indices[:test_set_size]
train_indices = shuffled_indices[test_set_size:]
return data.iloc[train_indices], data.iloc[test_indices]
Usage of the function like this:
>>>train_set, test_set = split_train_test(housing, 0.2)
>>> len(train_set)
16512
>>> len(test_set)
4128
好吧,这可行,但并不完美:如果再次运行该程序,它将生成不同的测试集!随着时间的推移,您(或您的机器学习算法)将看到整个数据集,这是您想要避免的。
Sachin Rastogi:为什么以及如何影响我的模型性能?我知道每次运行时我的模型精度都会有所不同,因为训练集总是不同的。我的模型如何在一段时间内看到整个数据集?
作者还提供了一些解决方案,
一种解决方案是在第一次运行时保存测试集,然后在后续运行中加载它。另一种选择是在调用 np.random.permutation() 之前设置随机数生成器的种子(例如,np.random.seed(42)),以便它始终生成相同的随机索引。
但是,当您下次获取更新的数据集时,这两种解决方案都会中断。一个常见的解决方案是使用每个实例的标识符来决定它是否应该进入测试集(假设实例具有唯一且不可变的标识符)。
Sachin Rastogi:这会是一个很好的训练/测试部门吗?我认为不,训练和测试应该包含来自整个数据集的元素,以避免训练集中的任何偏差。
作者举个例子,
您可以计算每个实例标识符的哈希值,如果哈希值低于或等于最大哈希值的 20%,则将该实例放入测试集中。这可确保测试集在多次运行中保持一致,即使您刷新数据集也是如此。
新的测试集将包含 20% 的新实例,但不会包含之前在训练集中的任何实例。
Sachin Rastogi:我无法理解这个解决方案。能否请你帮忙?