为啥 sklearn MinMaxScaler() 返回超出范围的值而不是错误?
Posted
技术标签:
【中文标题】为啥 sklearn MinMaxScaler() 返回超出范围的值而不是错误?【英文标题】:Why does sklearn MinMaxScaler() return an out-of-range value instead of an error?为什么 sklearn MinMaxScaler() 返回超出范围的值而不是错误? 【发布时间】:2021-03-17 22:41:06 【问题描述】:当我使用 sklearn MinMaxScaler() 时,我注意到一些有趣的行为,如以下代码所示。
>>> from sklearn.preprocessing import MinMaxScaler
>>> data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
>>> scaler = MinMaxScaler(feature_range=(0, 1))
>>> scaler.fit(data)
MinMaxScaler(copy=True, feature_range=(0, 1))
>>> test_data = [[-22, 20], [20.5, 26], [30, 40], [19, 13]]
>>> scaler.transform(test_data)
array([[-10.5 , 1.125 ],
[ 10.75 , 1.5 ],
[ 15.5 , 2.375 ],
[ 10. , 0.6875]])
我注意到,当我使用合适的 MinMaxScaler() 转换 test_data 时,它返回的值超出了定义的范围 (0 - 1)。
现在,我故意让 test_data 超出“数据”的取值范围,以测试 MinMaxScaler() 的输出。
我认为当“test_data”的值超出变量“data”的值范围时,它应该返回一些错误。但是,情况并非如此,我得到了一个超出定义范围的输出值。
我的问题是,为什么函数会表现出这种行为(即,当 test_data 值超出正在拟合 MinMaxScaler 的数据中的值范围时,返回超出定义范围的输出值),而不是返回错误?
【问题讨论】:
你知道fit
和transform
是什么意思吗?
@ombk:是的,我当然知道两者的区别
【参考方案1】:
如果生成的(转换后的)数据在拟合期间提供的feature_range
之外,MinMaxScaler 会引发错误(并因此终止程序执行),这可能是一个糟糕且奇怪的设计选择。
假设现实世界的管道定期处理数十万个传入数据样本,其中包含这样的缩放器。想象一下,如果任何转换后的特征落在[0, 1]
范围之外,缩放器确实会抛出错误并停止。现在考虑这样一种情况,例如,在一批 500K 数据样本中,只有几个,其中的特征在转换后确实超出了[0, 1]
范围。所以,整个管道就崩溃了……
在这种情况下谁会高兴? (暂定答案:nobody)。
负责的数据科学家或 ML 工程师是否可以声称“但是为什么,这是正确的做法,因为显然存在错误的数据”? 不,绝对不是……
概念漂移的概念,即流数据的底层分布随时间发生不可预见的变化,是一个巨大 ML子主题,具有极大的实际意义和intense research 的区域。这里的想法(即在这些情况下不抛出错误的函数背后)是,如果建模者有理由相信在实践中可能会发生类似的事情(它几乎总是确实 em>),因此使他们的 ML 结果在很大程度上毫无用处,他们有责任在他们部署的系统中明确处理它。将如此严肃的工作交给(不起眼的......)缩放功能在很大程度上是不合适的,而且归根结底是一个错误。
将讨论概括一下:MimMaxScaler 只是一个辅助函数;使用它的基本假设(实际上是整个 scikit-learn 和类似的库)是 我们知道自己在做什么,而且我们不仅仅是随机转动旋钮和按下按钮的无脑傻瓜直到我们的模型似乎“工作”。当我们尝试真正毫无意义的事情时,Keras 是否应该警告我们,比如在回归问题中要求分类准确度?好吧,it does not - 使用它时当然假定存在最低限度的知识,我们不应该真的期望框架本身能够保护我们免受我们自己建模中的此类错误。
与此类似,我们的工作是意识到转换后的新数据可能会出现超出范围的值,并相应地处理这种情况; 不是 MinMaxScaler(或任何其他类似的转换器)的工作代表该过程停止。
回到你自己的玩具例子,或者我自己的假设:总是可以在新数据的转换之后集成额外的逻辑,以便相应地处理这种情况;即使只是检查哪些(以及有多少)样本是有问题的,在这种转换之后也可以说比以前容易得多(因此提供了可能的概念漂移的第一个粗略警报) .通过不抛出错误(从而停止整个过程),scikit-learn 为你,建模者提供了以你身份进行的所有选项em> 认为合适,前提是你知道你的东西。在这里仅仅抛出一个错误并拒绝继续是没有效率的,scikit-learn 开发人员的设计选择似乎非常合理。
【讨论】:
【参考方案2】:如果您将 MinMaxScaler
视为另一个 ML 模型,那么您的测试成绩就很差。这与测试集上的 R 平方为 0.01 相同 - 测试数据与训练数据的差异如此之大,以至于模型无法为其产生良好的结果。
现在,当您的模型的准确度为 0.07 时,为什么 SciKit-Learn 不会引发错误?或者当损失函数的值超出图表时?可能是因为它不知道什么适应度得分足够差(或者甚至使用什么适应度得分)。
另外,fit
函数 computes the minimum and maximum to be used for later scaling,因此您在训练数据上“训练”了“模型”,该模型基本上计算并存储其最小值和最大值。当您transform
ed train 数据时,会运行以下公式(参见上面的链接):
X_scaled = X_std * (max - min) + min
这里,max
和min
用于训练数据,只有X_scaled
涉及您应用“模型”的数据。所以当然模型给出了“不正确”的预测——因为测试集的最小值和最大值与用于“训练”模型的不同。
【讨论】:
OP 的问题不是为什么 sklearn 在精度太低时不返回错误,而是为什么它不这样“当 test_data 值超出 MinMaxScaler 所在数据的值范围时正在安装中”。 @desertnaut,这在我的答案的后半部分进行了解释 - 这是因为min
和 max
值来自 train 数据集
我的意思是您的第二段看起来无关紧要(这从来都不是问题),而且恕我直言有点奇怪。另外,您在最后一部分中使用的术语“不正确的预测”是相当不幸的 - 它们并非不正确(考虑到函数应该做什么)。
(续)如果我们认为该函数给出了“不正确”的预测,那么它不应该像 OP 暗示的那样引发错误吗? (回答:不,但这正是这里的 OP 可能要求的解释)。
他们不需要分数 - 只需检查(任何)返回值是否在安装缩放器时提供的 feature_range
之外就可以了;这就是为什么您的第二段在这里无关紧要的原因-它解决了一个实际上没有被问到的不同问题。 OP 的问题是 为什么 sklearn 不这样做并且在发生这种情况时不会抛出错误。这是关于函数的设计及其基本原理的问题(或者在我看来……)以上是关于为啥 sklearn MinMaxScaler() 返回超出范围的值而不是错误?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 sklearn MinMaxScaler() 的值转换回实际值?
Python,sklearn:使用 MinMaxScaler 和 SVC 的管道操作顺序
[转]sklearn中MinMaxScaler/StandardScaler的区别
使用Sklearn的MinMaxScaler做最简单的归一化