一、原理
數據標准化(Normalization):將數據按照一定比例進行縮放,使其落入到一個特定的小區間。
數據標准化的類別:
- Min-Max標准化
- Z-Score標准化(Standard Score,標准分數)
- 小數定標(Decimal scaling)標准化
- 均值歸一化
- 向量歸一化
- 指數轉換
1、Min-Max標准化
Min-Max標准化,指對原始數據進行線性變換,將值映射到[0,1]之間。
公式:
式中,x為原始數據的數據,xmin為原始數據的最小值,xmax為原始數據的最大值。
2、Z-Score標准化
又稱為Standard Score(標准分數),指基於原始數據的均值(mean)和標准差(standard deviation)來進行數據的標准化。
公式:
式中,x為原始數據的數據,μ為原始數據的均值,σ為原始數據的標准差。
3、小數定標(Deciaml scaling)標准化
指通過移動小數點的位置來進行數據的標准化。小數點移動的位數取決於原始數據中的最大絕對值。
公式:
式中,x為原始數據,10j的j表示最大絕對值的位數。
例如,現在有一個數組[-309, -10, -43, 87, 344, 970],其中最大絕對值為970,即j=3,標准化為的數據為[-0.309, -0.01, -0.043, 0.087, 0.344, 0.97]
4、均值歸一化
指通過原始數據中的均值、最大值和最小值來進行數據的標准化。
公式:
式中,x為原始數據,μ為原始數據的均值,xmin為原始數據的最小值,xmax為原始數據的最大值。當然,分母部分也可以使用xmax代替。
5、向量歸一化
指通過原始數據中的每個值除以所有數據之和來進行數據的標准化。
公式:
式中,x為原始數據,分母為所有數據之和。
6、指數轉換
指通過對原始數據的值進行相應的指數函數變換來進行數據的標准化。進行指數轉換常見的函數方法有lg函數、Softmax函數和Sigmod函數。
公式:
(1)lg函數:
式中,x為原始數據,為原始數據的最大值。
(2)Softmax函數:
式中,x為原始數據,e為自然對數,分母表示的是原始數據中每個數據對e求指數后的和。
(3)Sigmoid函數:
二、代碼實現數據的標准化
import numpy as np import math class DataNum: def __init__(self): self.arr = [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0] self.x_max = max(self.arr) # 最大值
self.x_min = min(self.arr) # 最小值
self.x_mean = sum(self.arr) / len(self.arr) # 平均值
self.x_std = np.std(self.arr) # 標准差
print("原始數據:\n{}".format(self.arr)) def Min_Max(self): arr_ = list() distance = self.x_max-self.x_min for x in self.arr: arr_.append(round((x-self.x_min)/distance,4)) # 保留4位小數
print("Min_Max標准化結果:\n{}".format(arr_)) def Z_Score(self): arr_ = list() for x in self.arr: arr_.append(round((x-self.x_mean)/self.x_std,4)) print("Z_Score標准化結果:\n{}".format(arr_)) def DecimalScaling(self): arr_ = list() j = self.x_max // 10 if self.x_max % 10 == 0 else self.x_max // 10 + 1
for x in self.arr: arr_.append(round(x/(math.pow(10,j)),4)) # 保留4位小數
print("DecimalScaling標准化結果:\n{}".format(arr_)) def Mean(self): arr_ = list() distance = self.x_max - self.x_min for x in self.arr: arr_.append(round((x - self.x_mean) / distance, 4)) # 保留4位小數
print("Mean標准化結果:\n{}".format(arr_)) def Vector(self): arr_ = list() arr_sum = sum(self.arr) for x in self.arr: arr_.append(round(x / arr_sum, 4)) # 保留4位小數
print("Vector標准化結果:\n{}".format(arr_)) def exponential(self): arr_1 = list() # lg
arr_2 = list() # SoftMax
arr_3 = list() # Sigmoid
sum_e = sum([math.exp(x) for x in self.arr]) for x in self.arr: arr_1.append(round(math.log10(x) / math.log10(self.x_max), 4)) # 保留4位小數
arr_2.append(round(math.exp(x) / sum_e, 4)) # 保留4位小數
arr_3.append(round(1 / (1+math.exp(-x)), 4)) # 保留4位小數
print("lg標准化結果:\n{}".format(arr_1)) print("SoftMax標准化結果:\n{}".format(arr_2)) print("Sigmod標准化結果:\n{}".format(arr_3)) def do(self): dn.Min_Max() dn.Z_Score() dn.DecimalScaling() dn.Mean() dn.Vector() dn.exponential() if __name__ == '__main__': dn = DataNum() dn.do()
運行結果: