lit*_*ely 17 python scikit-learn
缩放数据时,为什么训练数据集使用'fit'和'transform',但测试数据集只使用'transform'?
SAMPLE_COUNT = 5000
TEST_COUNT = 20000
seed(0)
sample = list()
test_sample = list()
for index, line in enumerate(open('covtype.data','rb')):
if index < SAMPLE_COUNT:
sample.append(line)
else:
r = randint(0,index)
if r < SAMPLE_COUNT:
sample[r] = line
else:
k = randint(0,index)
if k < TEST_COUNT:
if len(test_sample) < TEST_COUNT:
test_sample.append(line)
else:
test_sample[k] = line
from sklearn.preprocessing import StandardScaler
for n, line in enumerate(sample):
sample[n] = map(float, line.strip().split(','))
y = np.array(sample)[:,-1]
scaling = StandardScaler()
X = scaling.fit_transform(np.array(sample)[:,:-1]) ##here use fit and transform
for n,line in enumerate(test_sample):
test_sample[n] = map(float,line.strip().split(','))
yt = np.array(test_sample)[:,-1]
Xt = scaling.transform(np.array(test_sample)[:,:-1])##why here only use transform
Run Code Online (Sandbox Code Playgroud)
正如注释所说,为什么Xt只使用变换而不适合?
小智 7
我们有两个数据集:训练和测试数据集。想象一下,我们只有两个功能:
'x1'和'x2'。
现在考虑一下(一个非常假设的示例):
训练数据中的样本具有以下值:'x1'= 100和'x2'= 200缩放后,'x1'的值为0.1,'x2'的值为0.1。为此,响应变量值为100。这些仅通过训练数据的均值和标准差计算得出。
测试数据中的样本值:'x1'= 50和'x2'=100。根据测试数据值进行缩放时,'x1'= 0.1和'x2'= 0.1。这意味着我们的函数也将为此样本预测100的响应变量值。但这是错误的。不应为100。这应该是在预测其他内容,因为上述2个样本的特征的未缩放值不同,因此指向不同的响应值。仅当根据训练数据对其进行缩放时,我们才知道正确的预测是什么,因为这些是线性回归函数已获悉的值。
我试图在下面解释这种逻辑背后的直觉:
我们决定在应用线性回归和拟合线性回归函数之前对训练数据集中的两个特征进行缩放。当我们缩放训练数据集的特征时,所有“ x1”特征都会根据不同样本的均值和标准偏差调整到其“ x1”特征值。“ x2”功能也会发生相同的情况。从本质上讲,这意味着仅根据训练数据就已将每个功能转换为新的编号。就像每个功能都被赋予了相对位置。相对于训练数据的均值和标准差。因此,每个样本的新“ x1”和“ x2”值仅取决于训练数据的均值和标准差。
现在,当我们拟合线性回归函数时,将发生的事情是,它基于训练数据集的缩放特征来学习参数(即学会预测响应值)。这意味着它正在学习基于训练数据集中不同样本的特定均值和标准差x1和x2进行预测。因此,预测值取决于:
*学习的参数。反过来取决于
*训练数据的特征值(已缩放)。由于缩放,训练数据的特征取决于
*训练数据的均值和标准差。
如果现在将standardscaler()拟合到测试数据,则测试数据的“ x1”和“ x2”将具有自己的均值和标准差。这意味着这两个功能的新值将仅与测试数据中的数据有关,因此与训练数据没有任何关系。几乎就像它们已被随机值减去并除以随机值,现在又获得了新值,无法传达它们与训练数据的关系。
小智 7
您对数据所做的任何转换都必须通过训练数据生成的参数来完成。
该方法的作用很简单fit(),就是创建一个模型,从训练样本中提取各种参数,以便稍后进行必要的转换。transform()另一方面是对数据本身进行实际转换,返回标准化或缩放形式。
fit_transform()只是执行fit()和操作的更快方法transform()。
这里重要的是,当您将数据集划分为训练集和测试集时,您想要实现的目标是在某种程度上模拟现实世界的应用程序。在现实世界中,您将只有训练数据,您将根据该数据开发模型并预测类似数据的未见过的实例。
如果您将整个数据转换为fit_transform()然后拆分以训练测试,则您违反了该模拟方法并根据未见过的示例进行转换。这将不可避免地产生一个乐观的模型,因为您已经通过看不见的样本指标在一定程度上准备了您的模型。
如果您将数据拆分为训练测试并应用于fit_transform()两者,您也会被错误地认为您的训练数据的第一次转换将仅通过训练拆分指标来完成,而您的第二次转换将仅通过测试指标来完成。
进行这些预处理的正确方法是仅使用训练数据训练任何变压器并对测试数据进行转换。因为只有这样,您才能确定生成的模型代表了现实世界的解决方案。
遵循这个实际上并不重要,如果你
fit(train)然后transform(train)然后transform(test)或者
fit_transform(train)然后transform(test)
| 归档时间: |
|
| 查看次数: |
13668 次 |
| 最近记录: |