目录
线性变换
Z-score变换
归一化变换
归一化至[0,1]
归一化至[-1,1]
归一化极端值处理
离群值检测
公式:
利用numpy表示为:
import numpy as np
import pandas as pd
np_data = np.array([1,4,10,15,23])
z_data = (np_data - np_data.mean()) / np_data.std()
z_data
输出:
array([-1.22077743, -0.83928449, -0.07629859, 0.55952299, 1.57683752])
利用pandas表示为:
data = pd.Series(np_data)
z_data = ((data - data.mean()) / data.std())
z_data
输出:(输出结果不一致)
0 -1.091897 1 -0.750679 2 -0.068244 3 0.500453 4 1.410366 dtype: float64
原因:pandas的方差var()和标准差std()的ddof值默认为1,ddof表示统计学中的自由度。即标准差公式中分母为n-1,ddof为k公式中分母则为n-k。 Numpy中默认ddof为0。
data = pd.Series(np_data)
z_data = ((data - data.mean() )/ data.std(ddof=0))
z_data
输出:
0 -1.220777 1 -0.839284 2 -0.076299 3 0.559523 4 1.576838 dtype: float64
使用sklearn现有数据预处理库进行Z-score变换
from sklearn.preprocessing import StandardScaler
data = pd.DataFrame(np_data.reshape(-1,1))
ss = StandardScaler().fit_transform(data)
ss
输出:
array([[-1.22077743], [-0.83928449], [-0.07629859], [ 0.55952299], [ 1.57683752]])
new_data = (data-data.min()) / (data.max()-data.min())
new_data
输出:
0 0.000000 1 0.136364 2 0.409091 3 0.636364 4 1.000000 dtype: float64
使用sklearn现有数据预处理库进行归一化
from sklearn.preprocessing import MinMaxScaler
data1 = pd.DataFrame(np_data.reshape(-1,1))
ms = MinMaxScaler().fit_transform(data1)
# print('最小值',MinMaxScaler().fit(data).data_min_)
# print('最大值',MinMaxScaler().fit(data).data_max_)
ms
输出:
array([[0. ], [0.13636364], [0.40909091], [0.63636364], [1. ]])
new_data = (new_data -new_data.mean())
new_data = new_data / (new_data.abs().max())
new_data
输出:
0 -0.774194 1 -0.532258 2 -0.048387 3 0.354839 4 1.000000 dtype: float64
利用sklearn归一化至[-1,1]
from sklearn.preprocessing import MinMaxScaler
ms = MinMaxScaler(feature_range=(-1,1)).fit_transform(data)
ms
输出:
array([[-1. ], [-0.72727273], [-0.18181818], [ 0.27272727], [ 1. ]])
data = pd.Series(data.tolist() + [100]) #数据中添加异常值200
new_max = data.nlargest(2).iloc[-1] #使用第二大值代替最大值
# new_max = data.quantile(0.8) #使用分位数代替最大值
new_data = (data-data.min()) / (new_max - data.min())
new_data
输出:
0 0.000000 1 0.136364 2 0.409091 3 0.636364 4 1.000000 5 4.500000 dtype: float64
使用LOF算法检测离群值并剔除
from sklearn.neighbors import LocalOutlierFactor
import matplotlib.pyplot as plt
s = pd.Series([-10]+list(np.random.rand(1000))+[10])
clf = LocalOutlierFactor()
label = clf.fit_predict(s.values[:,None])
s_fix2 = s[label==1]
print(s[label==1]) #离群值为-10和10
plt.boxplot(s_fix2)
plt.show()
输出:
0 -10.0 1001 10.0 dtype: float64
总结:归一化对于离群值的处理,先是检测离群值并剔除后,再进行归一化变换。