赞
踩
本文通过Python实现三种常见的数据规范化方法,包括最小-最大规范化,零-均值规范化,小数定标规范化。
最小-最大规范化(Min-max): x ∗ = x − m i n m a x − m i n x^*=\frac{x-min}{max-min} x∗=max−minx−min,min表示最小值,max表示最大值
零-均值规范化(Z-score): x ∗ = x − x ˉ σ x^*=\frac{x-\bar{x}}{\sigma} x∗=σx−xˉ, x ˉ \bar{x} xˉ表示均值, σ \sigma σ表示方差
小数定标规范化: x ∗ = x 1 0 k x^*=\frac{x}{10^k} x∗=10kx,k表示小数点移动的位数
实现代码
import numpy as np import pandas as pd # 原始数据,每一行表示一个样本,每一列表示一个特征 raw_data = np.array([ [78, 521, 602, 2862], [144, -600, -521, 2245], [95, -457, 468, -1283], [69, 596, 695, 1054], [190, 527, 691, 2051], [101, 403, 470, 2487] ]) data = pd.DataFrame(raw_data) # 最小-最大规范化 min_max = (data-data.min()) / (data.max()-data.min()) # 零-均值规范化 z_score = (data-data.mean()) / data.std() # 小数定标规范化 decimal_scaling = data / 10**np.ceil(np.log10(data.abs().max())) # 打印结果 print(min_max) print(z_score) print(decimal_scaling)
输出结果
min_max Out[26]: 0 1 2 3 0 0.074380 0.937291 0.923520 1.000000 1 0.619835 0.000000 0.000000 0.851146 2 0.214876 0.119565 0.813322 0.000000 3 0.000000 1.000000 1.000000 0.563812 4 1.000000 0.942308 0.996711 0.804343 5 0.264463 0.838629 0.814967 0.909530 z_score Out[27]: 0 1 2 3 0 -0.759445 0.656051 0.434805 0.848567 1 0.679503 -1.409773 -1.992464 0.443540 2 -0.388807 -1.146247 0.145175 -1.872406 3 -0.955665 0.794264 0.635816 -0.338289 4 1.682407 0.667108 0.627171 0.316189 5 -0.257993 0.438596 0.149498 0.602400 decimal_scaling Out[28]: 0 1 2 3 0 0.078 0.521 0.602 0.2862 1 0.144 -0.600 -0.521 0.2245 2 0.095 -0.457 0.468 -0.1283 3 0.069 0.596 0.695 0.1054 4 0.190 0.527 0.691 0.2051 5 0.101 0.403 0.470 0.2487
实现代码
from sklearn import preprocessing import numpy as np # 原始数据,每一行表示一个样本,每一列表示一个特征 raw_data = np.array([ [78, 521, 602, 2862], [144, -600, -521, 2245], [95, -457, 468, -1283], [69, 596, 695, 1054], [190, 527, 691, 2051], [101, 403, 470, 2487] ]) # 最小-最大规范化 # 将数据进行[0,1]规范化;最小最大值区间可以指定,默认是映射到[0,1]区间 min_max_scaler = preprocessing.MinMaxScaler() min_max = min_max_scaler.fit_transform(raw_data) # 零-均值规范化 z_score = preprocessing.scale(raw_data) # 小数定标规范化 # 主要是通过NumPy库来计算小数点的位数 k = np.ceil(np.log10(np.max(abs(raw_data)))) decimal_scaling = raw_data / (10**k) # 打印结果 print(min_max) print(z_score) print(decimal_scaling)
输出结果
min_max Out[10]: array([[0.07438017, 0.93729097, 0.92351974, 1. ], [0.61983471, 0. , 0. , 0.85114596], [0.21487603, 0.11956522, 0.81332237, 0. ], [0. , 1. , 1. , 0.56381182], [1. , 0.94230769, 0.99671053, 0.80434258], [0.26446281, 0.83862876, 0.81496711, 0.90952955]]) z_score Out[11]: array([[-0.83193017, 0.71866807, 0.47630463, 0.92955909], [ 0.74435857, -1.54432887, -2.18263537, 0.4858732 ], [-0.4259164 , -1.2556504 , 0.15903129, -2.0511184 ], [-1.04687863, 0.87007286, 0.69650179, -0.37057719], [ 1.84298406, 0.73078046, 0.68703095, 0.34636743], [-0.28261743, 0.48045787, 0.16376671, 0.65989587]]) decimal_scaling Out[12]: array([[ 0.0078, 0.0521, 0.0602, 0.2862], [ 0.0144, -0.06 , -0.0521, 0.2245], [ 0.0095, -0.0457, 0.0468, -0.1283], [ 0.0069, 0.0596, 0.0695, 0.1054], [ 0.019 , 0.0527, 0.0691, 0.2051], [ 0.0101, 0.0403, 0.047 , 0.2487]])
观察仔细的小伙伴,应该就可以发现,两种方法得到的结果存在差异。这是为什么呢?
主要原因还是两种方法的实现不同,处理的对象主体也不同。我们可以通过测试每一步的输出,以及查看源码来发现和解决问题。
接下来,主要针对两种方法进行小数定标规范化后,得到的结果存在差异的原因,进行分析。
在方法一中,处理的数据是 DataFrame 对象。原始数据(raw_data)被转换成 Pandas 的 DataFrame 对象(data),对 data 执行统计计算,例如求均值,方差,最大值时,默认是对每一列求均值,方差,最大值。(也可以通过修改axis的取值,对每一行执行操作。)本例中的 data 有4列,对 data 求最大值,则有4个结果。
decimal_scaling = data / 10**np.ceil(np.log10(data.abs().max())) data Out[42]: 0 1 2 3 0 78 521 602 2862 1 144 -600 -521 2245 2 95 -457 468 -1283 3 69 596 695 1054 4 190 527 691 2051 5 101 403 470 2487 type(data) # data是DataFrame类型 Out[43]: pandas.core.frame.DataFrame data.describe() # 对data的描述 Out[44]: 0 1 2 3 count 6.000000 6.000000 6.000000 6.000000 mean 112.833333 165.000000 400.833333 1569.333333 std 45.866836 542.640581 462.659882 1523.351656 min 69.000000 -600.000000 -521.000000 -1283.000000 25% 82.250000 -242.000000 468.500000 1303.250000 50% 98.000000 462.000000 536.000000 2148.000000 75% 133.250000 525.500000 668.750000 2426.500000 max 190.000000 596.000000 695.000000 2862.000000 data.abs().max() # 对data的每一列取绝对值后,再求每一列的最大值 Out[45]: 0 190 1 600 2 695 3 2862 dtype: int32
方法二中,处理的数据是 numpy 的数组 ndarray。当对数据取均值,最大值等统计值时,是以整个数组为主体,最后求得的均值,最大值,都分别只有一个。
k = np.ceil(np.log10(np.max(abs(raw_data)))) decimal_scaling = raw_data / (10**k) raw_data Out[13]: array([[ 78, 521, 602, 2862], [ 144, -600, -521, 2245], [ 95, -457, 468, -1283], [ 69, 596, 695, 1054], [ 190, 527, 691, 2051], [ 101, 403, 470, 2487]]) type(raw_data) Out[14]: numpy.ndarray np.mean(raw_data) # 求均值 Out[15]: 562.0 # 对所有数值求绝对值后,再求出所有数值当中的最大值,只返回一个结果 np.abs(raw_data).max() Out[17]: 2862
结论:具体问题具体分析,根据实际场景的需要,选择合适的计算方式。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。