很多演算法对数据范围非常的敏感。因此为了要让模型训练的更强大,通常的做法是对特徵进行调节,使得数据更适合这些演算法。一般来说,我们在做机器学习时往往会做特徵的正规化。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import load_iris
np.set_printoptions(suppress=True)
今天的范例我们延续昨天的例子,鸢尾花朵资料集进行资料正规化的示范。
iris = load_iris()
df_data = pd.DataFrame(data= np.c_[iris['data'], iris['target']],
columns= ['SepalLengthCm','SepalWidthCm','PetalLengthCm','PetalWidthCm','Species'])
df_data
使用 numpy 所提供的函式来检查是否有 NA 缺失值,假设有缺失值使用 dropna()
来移除。使用的时机在於当只有少量的缺失值适用,若遇到有大量缺失值的情况,或是本身的资料量就很少的情况下建议可以透过机器学习的方法补值来预测缺失值。
X = df_data.drop(labels=['Species'],axis=1).values # 移除Species并取得剩下栏位资料
y = df_data['Species']
# checked missing data
print("checked missing data(NAN mount):",len(np.where(np.isnan(X))[0]))
输出结果:
checked missing data(NAN mount): 0
由於 Sklearn 所提供的资料集非常乾净,若你收集到的资料有许多的缺失值或是本身资料量就不多的强况下,建议好好的去处理这些缺漏的值。通常补值的方法可分为手动填值与插值法。首先手动填值可以以该栏位所有资料的算术平均数或中位数做填补的依据。再者使用以出现频率最高的值做填补也是常见的补值方式。另一种差值法是透过时间或空间上的技巧处理这些缺值,例如当资料是有时间序列的因素存在时,可以利用该笔缺失栏位附近的时间点的资料加总并平均。
我们透过 Sklearn 所提供的 train_test_split()
方法来为我们的资料进行训练集与测试集的切割。在此方法中我们可以设定一些参数来让我们切割的资料更多样性。其中 test_size
参数就是设定测试集的比例,范例中我们设定 0.3 即代表训练集与测试集的比例为 7:3。另外预设资料切割的方式是随机切割 shuffle=True
对原始数据进行随机抽样,以保证随机性。若想要每次程序执行时切割结果都是一样的可以设定乱数随机种子 random_state
并给予一个随机数值。最後一个是 stratify
分层随机抽样,特别是在原始数据中样本标签分布不均衡时非常有用。使用时机是确保分类问题 y 的类别数量分布要与原资料集一致。以免资料集切割不平均导致模型训练时有很大的偏差。
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y)
print('train shape:', X_train.shape)
print('test shape:', X_test.shape)
输出结果:
train shape: (105, 4)
test shape: (45, 4)
将所有特徵标准化,也就是高斯分布。使得数据的平均值为 0,方差为 1。适合的使用时机於当有些特徵的方差过大时,使用标准化能够有效地让模型快速收敛。
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
# scaled之後的资料零均值,单位方差
print('资料集 X 的平均值 : ', X_train.mean(axis=0))
print('资料集 X 的标准差 : ', X_train.std(axis=0))
print('\nStandardScaler 缩放过後训练集的平均值 : ', X_train_scaled.mean(axis=0))
print('StandardScaler 缩放过後训练集的标准差 : ', X_train_scaled.std(axis=0))
输出结果:
资料集 X 的平均值 : [5.87333333 3.0552381 3.7847619 1.20571429]
资料集 X 的标准差 : [0.85882164 0.45502087 1.77553646 0.77383751]
StandardScaler 缩放过後训练集的平均值 : [ 0. -0. -0. -0.]
StandardScaler 缩放过後训练集 X 的标准差 : [1. 1. 1. 1.]
训练集的 Scaler 拟合完成後,我们就能做相同的转换在测试集上。
X_test_scaled = scaler.transform(X_test)
print('\nStandardScaler 缩放过後测试集的平均值 : ', X_test_scaled.mean(axis=0))
print('StandardScaler 缩放过後测试集的标准差 : ', X_test_scaled.std(axis=0))
输出结果:
StandardScaler 缩放过後测试集的平均值 : [0.40925926 0.44259259 0.44750958 0.45185185]
StandardScaler 缩放过後测试集的标准差 : [0.20457725 0.15915694 0.29647499 0.30224923]
如果想将转换後的资料还原可以使用 inverse_transform()
将数值还原成原本的输入。
# 将缩放的资料还原
X_test_inverse = scaler.inverse_transform(X_test_scaled)
在MinMaxScaler中是给定了一个明确的最大值与最小值。每个特徵中的最小值变成了0,最大值变成了1。数据会缩放到到[0,1]之间。
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
X_train_scaled = scaler.fit_transform(X_train)
# scaled 之後的资料最小值、最大值
print('资料集 X 的最小值 : ', X_train.min(axis=0))
print('资料集 X 的最大值 : ', X_train.max(axis=0))
print('\nStandardScaler 缩放过後训练集的最小值 : ', X_train_scaled.min(axis=0))
print('StandardScaler 缩放过後训练集的最大值 : ', X_train_scaled.max(axis=0))
输出结果:
资料集 X 的最小值 : [4.3 2. 1.1 0.1]
资料集 X 的最大值 : [7.9 4.4 6.9 2.5]
StandardScaler 缩放过後训练集的最小值 : [0. 0. 0. 0.]
StandardScaler 缩放过後训练集的最大值 : [1. 1. 1. 1.]
X_test_scaled = scaler.transform(X_test)
print('\nStandardScaler 缩放过後测试集的最小值 : ', X_test_scaled.min(axis=0))
print('StandardScaler 缩放过後测试集的最大值 : ', X_test_scaled.max(axis=0))
StandardScaler 缩放过後测试集的最小值 : [ 0.02777778 0.125 -0.01724138 0.04166667]
StandardScaler 缩放过後测试集的最大值 : [0.83333333 0.83333333 0.89655172 0.95833333]
MaxAbsScaler 与 MinMaxScaler 类似,所有数据都会除以该列绝对值後的最大值。 数据会缩放到到[-1,1]之间。
from sklearn.preprocessing import MaxAbsScaler
scaler = MaxAbsScaler().fit(X)
X_scaled = scaler.transform(X)
X_test_scaled = scaler.transform(X_test)
可以有效的缩放带有outlier的数据,透过Robust如果数据中含有异常值在缩放中会舍去。
from sklearn.preprocessing import RobustScaler
scaler = RobustScaler().fit(X)
X_scaled = scaler.transform(X)
X_test_scaled = scaler.transform(X_test)
本系列教学内容及范例程序都可以从我的 GitHub 取得!
在上一篇,我们介绍了登录档的结构和物理位置,现在你意识到他的存在,那今天就是接续前一篇最後的预告,我...
在Project新增Create→C# Script取名为ChangeScene 撰写程序码 usi...
资料结构及型别 JavaScript 定义了七种资料型别: 1.Boolean布林 : false ...
前言 JS 30 是由加拿大的全端工程师 Wes Bos 免费提供的 JavaScript 简单应用...
接下来开始建立前端专案,接下来依序介绍预期使用的工具与套件。 工具与套件 Vue、Vuex 图片来源...