训练数据所代表的分布是否需要反映测试数据的分布和您预测的数据?我可以通过查看每个功能的分布来衡量培训数据的质量,并将该分布与我预测或测试的数据进行比较吗?理想情况下,训练数据应足以代表现实世界的分布。
答案 0 :(得分:2)
简短回答:类似的范围是个好主意。 答案很长:有时它不会成为一个问题(很少),但让我们检查一下。
在理想情况下,您的模型将完全捕捉 的真实现象。想象一下最简单的情况:线性模型y = x。如果训练数据是无噪声的(或具有可容忍的噪声)。线性回归自然会落在大约等于y = x的模型上。即使在训练范围之外,模型的推广也将近乎完美。如果您的列车数据为{1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,10:10}。测试点500将很好地映射到函数上,返回500.
在大多数建模方案中,几乎肯定不会是这种情况。如果训练数据充足且模型相当复杂(并且不再存在),那么你就是金色的。
问题在于,很少有函数(和相应的自然现象) - 特别是当我们考虑非线性函数时 - 如此干净地扩展到训练范围之外的数据。想象一下采样办公室的温度与员工的舒适感。如果你只看40度到60度的温度。线性函数在训练数据中表现得非常出色。奇怪的是,如果你测试60到80,映射将会崩溃。在这里,问题在于您对数据具有足够代表性的说法充满信心。
现在让我们考虑一下噪音。想象一下,你完全了解现实世界的功能:正弦波。更好的是,你被告知它的幅度和相位。你不知道的是它的频率。你有一个真正可靠的1到100之间的采样,你适合的功能很好地映射到训练数据。现在,如果有足够的噪音,你可能会错误估计头发的频率。当您在训练范围附近进行测试时,结果并非如此糟糕。训练场的外部,事情开始变得不稳定。随着您越来越远离训练范围,实际功能和功能会根据其相对频率发散和收敛。有时,残差看似很好;有时它们很可怕。
您对检查变量分布的想法存在问题:变量之间的交互。即使每个变量在训练和测试中得到适当平衡,变量之间的关系也可能不同(联合分布)。对于一个纯粹人为的例子,考虑一下你预测个人在任何特定时间怀孕的可能性。在你的训练集中,你有20到30岁的女性和30到40岁的男性。在测试中,你有相同比例的男性和女性,但年龄范围被翻转。独立地,变量看起来非常匹配!但是在你的训练集中,你可以很容易地得出结论,“只有30岁以下的人才会怀孕。”#34;奇怪的是,您的测试装置将证明完全相反!问题在于您的预测是从多变量空间进行的,但您正在考虑的分布是单变量的。然而,考虑到连续变量相互之间的联合分布(并适当地考虑分类变量)是一个好主意。理想情况下,您的拟合模型应该可以访问与测试数据类似的范围。
从根本上说,问题是关于从有限的训练空间进行推断。如果模型适合训练空间的概括,可以概括;最终,拥有一个非常好的分布式训练集通常是最安全的,以最大限度地提高你捕获基础函数复杂性的可能性。
非常有趣的问题!我希望答案有点有见地;当资源浮现在脑海中时,我将继续为此而努力!如果有任何问题,请告诉我们!
编辑:我认为应该由未来读者阅读的评论中提出的观点。 理想情况下,培训数据不应以任何方式影响测试数据。这包括检查分布,联合分布等。有了足够的数据,训练数据中的分布应该收敛于测试数据中的分布(想想平均值,大数定律)。匹配分布的操作(如列车/测试拆分前的z评分)从根本上扭曲了对您有利的性能指标。用于分割列车和测试数据的适当技术将类似于用于交叉验证的分层k折叠。
答案 1 :(得分:0)
抱歉延迟回复。经过几个月的迭代后,我实施并将以下解决方案推向生产并且运行良好。
这里的问题归结为如何在执行交叉验证时减少训练/测试分数差异。这很重要,因为您的方差很高,选择最佳模型的信心会下降。测试数据对列车数据的代表性越高,您在交叉验证集中的测试得分中获得的差异就越小。分层交叉验证通过确保在所有测试/训练集中保留标签类比例来解决此问题,尤其是当存在显着的类不平衡时。但是,这并没有解决功能分发的问题。
在我的情况下,我有一些非常强大的预测因素,但在分布上也非常偏斜。这导致我的测试分数出现显着差异,这使得选择模型更加自信。本质上,解决方案是确保标签与特征集的联合分布在测试/训练集之间保持不变。执行此操作的许多方法,但是一种非常简单的方法是在生成测试和训练集时,逐个采用每个柱桶范围(如果是连续的)或标签(如果是分类的)并从这些桶中取样。请注意,特别是当您有很多分类变量时,存储桶会很快变得非常稀疏。此外,您的存储桶的列顺序会极大地影响采样输出。下面是一个解决方案,我首先打开标签(与分层CV相同),然后采样另一个功能(最重要的功能(称为score_percentage),这是预先知道的。)
def train_test_folds(self, label_column="label"):
# train_test is an array of tuples where each tuple is a test numpy array and train numpy array pair.
# The final iterator would return these individual elements separately.
n_folds = self.n_folds
label_classes = np.unique(self.label)
train_test = []
fmpd_copy = self.fm.copy()
fmpd_copy[label_column] = self.label
fmpd_copy = fmpd_copy.reset_index(drop=True).reset_index()
fmpd_copy = fmpd_copy.sort_values("score_percentage")
for lbl in label_classes:
fmpd_label = fmpd_copy[fmpd_copy[label_column] == lbl]
# Calculate the fold # using the label specific dataset
if (fmpd_label.shape[0] < n_folds):
raise ValueError("n_folds=%d cannot be greater than the"
" number of rows in each class."
% (fmpd_label.shape[0]))
# let's get some variance -- shuffle within each buck
# let's go through the data set, shuffling items in buckets of size nFolds
s = 0
shuffle_array = fmpd_label["index"].values
maxS = len(shuffle_array)
while s < maxS:
max = min(maxS, s + n_folds) - 1
for i in range(s, max):
j = random.randint(i, max)
if i < j:
tempI = shuffle_array[i]
shuffle_array[i] = shuffle_array[j]
shuffle_array[j] = tempI
s = s + n_folds
# print("shuffle s =",s," max =",max, " maxS=",maxS)
fmpd_label["index"] = shuffle_array
fmpd_label = fmpd_label.reset_index(drop=True).reset_index()
fmpd_label["test_set_number"] = fmpd_label.iloc[:, 0].apply(
lambda x: x % n_folds)
print("label ", lbl)
for n in range(0, n_folds):
test_set = fmpd_label[fmpd_label["test_set_number"]
== n]["index"].values
train_set = fmpd_label[fmpd_label["test_set_number"]
!= n]["index"].values
print("for label ", lbl, " test size is ",
test_set.shape, " train size is ", train_set.shape)
print("len of total size", len(train_test))
if (len(train_test) != n_folds):
# Split doesnt exist. Add it in.
train_test.append([train_set, test_set])
else:
temp_arr = train_test[n]
temp_arr[0] = np.append(temp_arr[0], train_set)
temp_arr[1] = np.append(temp_arr[1], test_set)
train_test[n] = [temp_arr[0], temp_arr[1]]
return train_test
答案 2 :(得分:0)
随着时间的流逝,我意识到整个问题都属于协变量移位的范畴,而协变量移位是机器学习中一个经过充分研究的领域。在下面链接或仅在Google中搜索协变量偏移。该概念是如何检测并确保您的预测数据与训练数据具有相似的分布。这是在特征空间中,但从理论上讲,您也可能会出现标签漂移。