归一化报错原理解释

关于归一化报错问题——以Python为例

不少小伙伴在开始数据处理,进行归一化的时候,会出现以下报错问题
ValueError: non-broadcastable output operand with shape (8,1) doesn’t match the broadcast shape (8,6)
本文将讲述报错原因以及如何改正。在改错之前,首先要了解归一化的原理。

归一化介绍

通常,在做数据分析的时候,数据归一化是必不可少的一步,特别是对于多维的数据。Why?,简而言之,数据归一化就是将数据中的每一个元素映射到一个较小的区间,这样,多维数据间的数字差距就会减小,消除量纲的影响。特别是在分析多维数据对标签的影响时更为重要。
常见的归一化方法主要有:

Min-Max
x − m i n X m a x X − m i n X \frac{x - minX}{maxX- minX} maxXminXxminX
Min-Max归一化方法将所有的值映射到[0, 1]。

Z-score
x − μ σ \frac{x-\mu}{\sigma} σxμ
Z-score方法,其中 μ \mu μ为处理数据中的均值, σ \sigma σ为处理数据中的方差。该方法将数据归一化为均值为0,方差为1。对于服从正态分布类的数据而言,适用于该归一化方法。
除上述两种归一化方法,在机器学习中,还有常见的Sigmoid归一化函数、tanh函数……,这里就不一一赘述了。

报错原理

我们以Min-Max归一化方法为例,我们将下面矩阵归一化处理:
[ A B C D 245 602 751 712 43 308 522 439 308 653 499 329 522 499 457 170 439 329 170 765 1257 977 968 798 1005 953 617 767 2143 1863 1863 1677 ] \left[ \begin{matrix} A &B &C &D\\ 245 &602 &751 &712\\ 43 &308 &522 &439\\ 308 &653 &499 &329\\ 522 &499 &457 &170\\ 439 &329 &170 &765\\ 1257 &977 &968 &798\\ 1005 &953 &617 &767\\ 2143 &1863 &1863 &1677 \end{matrix} \right] A24543308522439125710052143B6023086534993299779531863C7515224994571709686171863D7124393291707657987671677

import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler
w = pd.read_excel("data.xlsx")
origin = np.array(w)
sc = MinMaxScaler()
data = sc.fit_transform(origin)

处理后得到如下归一化矩阵:

[ A B C D 0.09619048 0.18906752 0.34317779 0.35965494 0 0 0.20791494 0.17850033 0.12619048 0.22186495 0.19432959 0.10550763 0.22809524 0.12282958 0.16952156 0 0.18857143 0.01350482 0 0.39482415 0.57809524 0.43022508 0.47135263 0.41672196 0.45809524 0.414791 0.26402835 0.39615129 1 1 1 1 ] \left[ \begin{matrix} A&B&C&D\\ 0.09619048& 0.18906752& 0.34317779& 0.35965494\\ 0 &0 &0.20791494 &0.17850033\\ 0.12619048& 0.22186495 &0.19432959& 0.10550763\\ 0.22809524 &0.12282958 &0.16952156& 0 \\ 0.18857143& 0.01350482 &0 &0.39482415\\ 0.57809524& 0.43022508& 0.47135263 &0.41672196\\ 0.45809524 &0.414791 & 0.26402835& 0.39615129\\ 1 &1 &1 &1 \end{matrix} \right] A0.0961904800.126190480.228095240.188571430.578095240.458095241B0.1890675200.221864950.122829580.013504820.430225080.4147911C0.343177790.207914940.194329590.1695215600.471352630.264028351D0.359654940.178500330.1055076300.394824150.416721960.396151291
根据上面个归一化数据可知,对于数据框,Sklearn库中归一化方法是将数据分列进行处理的。现在,我们将A列数据反归一化。返回原来的值:

#对第一列数据进行反归一化操作
w2 = data[::, 0]
#改变数据维度,不然会报错
w2 = w2.reshape(8, 1)
pr_data = sc.inverse_transform(w2)
print(pr_data)

此时报错:
ValueError: non-broadcastable output operand with shape (8,1) doesn’t match the broadcast shape (8,4)
这是因为我们上面是将一个数据框进行归一化,而当我们在反归一化时只对其中的一列数据进行操作。而程序无法判断我们进行操作的数据对应数据框的哪一列,自然就无法进行反归一化。
注意:从数据框中提取数据需要重新塑造维度,若没有改变数据维度,则会报错:
ValueError: Expected 2D array, got 1D array instead

解决方案

针对以上的报错,这里提供两种解决方法:

1. 用需要反归一化的数据,替换掉历史的数据。

例如现在用A,B,C前三列数据分析D列数据,得到新的一列数据E需要与原数据D进行比较,这时候我们只需要加上两行代码将新数据E代替D列,再反归一化即可。

data = pd.DataFrame(data)
data.iloc[:, 3] = new_data	#新数据列替换D列数据
data = sc.inverse_transform(data)	#反归一化

注意:系统会利用归一化中存储的最值进行反一化操作,因此在反归一化数据是允许出现在[0,1]外的。

2. 自己编写归一化函数

并且实际的数据处理中,对于样本量较小的情况下,调用归一化函数是不合理的。因为小样本数据不符合大数定律,无法客观反映事件的整体特性,即数学语言中的均值,方差,最值等。此时建议对数据归一化处理时所需的数字特征另外获取,并根据数据特性编写归一化代码

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值