一些有用的机器学习data cleaning的方法,也是训练机器学习模型前对数据集的常见处理。
- missing value
- scaling
- normalization
- encoding
- classes balancement
1missing value
真实世界中,大多数数据集都包含缺失值,通常包括:空白值,nan或其他占位符。这样的值与scikit-learn estimators不兼容。我们也可以丢弃所有有缺失的行或列,但这么做的代价是数据集的不完整,一种更好的方法是计算缺失值,从已有的部分推断他们。
1.1 单变量特征 Imputation
SimpleImputer类提供了输入缺失值的基本策略。缺失值可以通过提供的常量来估算,也可以使用缺失值所在的每列的统计数据(平均值、中位数或出现次数最多的值)。这个类还允许使用不同的缺失值。
import numpy as np
from sklearn.impute import SimpleImputer
imp = SimpleImputer(missing_values=np.nan, strategy='mean')
imp.fit([[1, 2], [np.nan, 3], [7, 6]])
SimpleImputer()
X = [[np.nan, 2], [6, np.nan], [7, 6]]
print(imp.transform(X))
当使用strategy为most_frequency时,还支持以字符串值或pandas categorical表示的数据
import pandas as pd
df = pd.DataFrame([["a", "x"],
[np.nan, "y"],
["a", np.nan],
["b", "y"]], dtype="category")
imp = SimpleImputer(strategy="most_frequent")
print(imp.fit_transform(df))
1.2 多变量特征 imputation
更复杂的方法是使用IterativeImputer类,它将每个缺失值的特征建模为其他特征的函数,并使用该估计进行估算,它以迭代循环的方式完成:在每一步中,一个特征列被指定为输出y,其他特征列被视为输入X。对于已知的y,基于(X, y)进行拟合,得到一个regressor。然后,这个regressor被用来预测y的缺失值。
import numpy as np
from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import IterativeImputer
imp = IterativeImputer(max_iter=10, random_state=0)
imp.fit([[1, 2], [3, 6], [4, 8], [np.nan, 3], [7, np.nan]])
X_test = [[np.nan, 2], [6, np.nan], [np.nan, 6]]
# the model learns that the second feature is double the first
print(np.round(imp.transform(X_test)))
1.3 Nearest neighbors imputation
KNNImputer类提供了使用k近邻方法填充缺失值的输入。默认情况下,使用支持缺失值的欧几里得距离度量nan_euclidean_distances来查找最近的邻居。
import numpy as np
from sklearn.impute import KNNImputer
nan = np.nan
X = [[1, 2, nan], [3, 4, 3], [nan, 6, 5], [8, 8, 7]]
imputer = KNNImputer(n_neighbors=2, weights="uniform")
imputer.fit_transform(X)
2 scaling(标准化)
scaling是许多机器学习模型的共同需求,如果特征不是标准分布的数据(0均值,单位方差),那么有可能模型结果会很差。如果数据某特征的方差比其他大几个数量级,那么这个特征就会支配目标函数,并使模型无法按正确的方式从其他特征中学习
在实践中,我们可以忽略数据分布的形状,只通过减去平均值来使数据居中,然后除标准差对其放缩。
2.1Standard Scaling
from sklearn import preprocessing
import numpy as np
X_train = np.array([[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]])
X_scaled = preprocessing.scale(X_train)
X_scaled
2.2 Min Max Scaling
将特征缩放到给定的最小值和最大值之间,通常在0到1之间.
X_train = np.array([[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]])
min_max_scaler = preprocessing.MinMaxScaler()
X_train_minmax = min_max_scaler.fit_transform(X_train)
X_train_minmax
2.3 Max Abs Scaling
MaxAbsScaler也类似,但是通过除以每个特征中的最大值使结果在-1到1之间,它适用于已经中心在0的数据或者稀疏数据。
X_train = np.array([[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]])
max_abs_scaler = preprocessing.MaxAbsScaler()
X_train_maxabs = max_abs_scaler.fit_transform(X_train)
X_train_maxabs
2.4 映射为均匀分布
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
X, y = load_iris(return_X_y=True)
quantile_transformer = preprocessing.QuantileTransformer(random_state=0,n_quantiles=112)
X_trans = quantile_transformer.fit_transform(X)
2.5 映射为高斯分布
X, y = load_iris(return_X_y=True)
quantile_transformer = preprocessing.QuantileTransformer(random_state=0,n_quantiles=112, output_distribution='normal')
X_trans = quantile_transformer.fit_transform(X)
3 Normalization(归一化)
归一化是将单个样本缩放为具有单位范数的过程,如果准备使用二次形式(如点积或任何其他核)来量化样本的相似性,那么这个过程可能很有用。
函数normalize使用l1或l2规范,提供了一种快速简便的方法进行归一化。
from sklearn import preprocessing
X = [[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]]
X_normalized = preprocessing.normalize(X, norm='l2')
X_normalized
3.1 l1 norm vs l2 norm
from numpy import array
from numpy.linalg import norm
a = array([1, 2, 3])
print(a)
l1 = norm(a, 1)
print(l1)
# l2 norm of a vector
from numpy import array
from numpy.linalg import norm
a = array([1, 2, 3])
print(a)
l2 = norm(a)
print(l2)