如何将测试和训练数据归一化为具有不同的行数

Posted

技术标签:

【中文标题】如何将测试和训练数据归一化为具有不同的行数【英文标题】:how to normalize test and train data as both having different different number of rows 【发布时间】:2022-01-14 11:11:27 【问题描述】:

我有一个数据框 d,其中一列是 price(数字),有 109248 行。我将数据分为d_traind_test 两部分。 d_train 有 73196 个值,d_test 有 36052 个值。现在标准化d_train['price']d_test['price'] 我做了这样的事情..

price_scalar = Normalizer()
X_train_price = price_scalar.fit_transform(d_train['price'].values.reshape(1, -1)
X_test_price = price_scalar.transform(d_test['price'].values.reshape(1, -1))

现在我遇到了这个问题

ValueError                                Traceback (most recent call last)
<ipython-input-20-ba623ca7bafa> in <module>()
3 X_train_price = price_scalar.fit_transform(X_train['price'].values.reshape(1, -1))
----> 4 X_test_price = price_scalar.transform(X_test['price'].values.reshape(1, -1))
/usr/local/lib/python3.7/dist-packages/sklearn/base.py in _check_n_features(self, X, reset)
394         if n_features != self.n_features_in_:
395             raise ValueError(
397                 f"is expecting self.n_features_in_ features as input."
398             )
ValueError: X has 36052 features, but Normalizer is expecting 73196 features as input.

进行更改:reshape(-1,1) 而不是 reshape(1,-1) 运行正常,但将 price 的所有行值设为 1。

【问题讨论】:

你想要实现什么样的标准化?规范化特征或数据点?到一个绝对范围或统计上(例如,有单位标准偏差)? 我只是想获得 0 到 1 之间的值 你到底为什么要改造?您谈到值(73196 和 36052),但错误清楚地表明这些被视为 特征 (自然,在重塑后),因此是预期的错误。您不应该在此处显示的代码中重塑。 # normalizer.fit(X_train['price'].values) # 这会产生错误 Expected 2D array, got 1D array instead: # array=[105.22 215.96 96.01 ... 368.98 80.53 709.67 ]。 # 如果您的数据具有单个特征,则使用 #array.reshape(-1, 1) 重塑您的数据 # 如果它包含单个样本,则使用 #array.reshape(1, -1)。这就是原因 【参考方案1】:

Reshape(-1, 1) 可以。如果您使用 sklearn 中的 Normalizer,则结果为 1: 具有至少一个非零分量的每个样本(即数据矩阵的每一行)独立于其他样本重新缩放,使其范数(l1、l2 或 inf)等于 1。

【讨论】:

那么如何使两者都在 0 到 1 之间......这就是我要问的 也许您需要的是更多类似 StandardScaler 或 MinMaxScaler 的东西。 我试过了......我也遇到了同样的问题 如果您尝试 price_scaler = StandardScaler(),但没有选项,例如,您无法获得只有 1 个值的输出行,因为 fit_transform 后训练数据的平均值为 0。【参考方案2】:

scikit-learn 始终假定数据以(n_points, n_features) 的形式组织(即,每一行都是一个数据点)。此外,从文档中,Normalizer 将“样本单独标准化为单位标准”。这意味着每个数据点(即行)都是标准化的,而不是沿着列(即所有价格值)。

要将值标准化为 [0, 1] 范围,您应该使用 MinMaxScaler 将数据重新整形为一列。也就是说,

from sklearn.preprocessing import MinMaxScaler
price_scalar = MinMaxScaler()
X_train_price = price_scalar.fit_transform(d_train['price'].values.reshape(-1, 1))
X_test_price = price_scalar.transform(d_test['price'].values.reshape(-1, 1))

值得注意的是,这保证测试集中的价格值都在 [0, 1] 范围内。这是学习 ML 模型时应该采用的方式,但请记住这一点。

【讨论】:

【参考方案3】:

这里可以直接fit_transform()函数,而不是fit()transform()分别函数。

price_scalar = Normalizer()
X_train_price = price_scalar.fit_transform(d_train['price'].values.reshape(1, -1)
X_test_price = price_scalar.fit_transform(d_test['price'].values.reshape(1, -1))

【讨论】:

以上是关于如何将测试和训练数据归一化为具有不同的行数的主要内容,如果未能解决你的问题,请参考以下文章

Sklearn标准化和归一化方法汇总:范数归一化

Sklearn标准化和归一化方法汇总:范数归一化

有关利用libsvm对数据进行归一化的问题。

批归一化(Batch Normalization)

标准化和归一化概念澄清与梳理

如何将网格归一化为 -1 到 1,然后从归一化网格恢复为原始网格?