相关链接:
Github地址
简书地址
CSDN地址
总所周知,对于机器学习任务,特别是对于深度学习任务,我们需要创建训练集,因此需要收集大量的数据.然而,在实际中,我们收集的数据极易受噪声、缺失值和数据不一致的影响。通常我们对数据进行如下几种预处理:
本文主要针对缺失值处理和数据向量化两种与处理方法进行讲解,整个处理过程分为6步:
下面我们将通过实例来一步步详细介绍这些操作。
numpy 和 pandas 是利用 Python 进行科学计算时非常重要两个科学计算库。其中 numpy 负责提供基本的数学计算函数,起运算对象事针对张量或矩阵;而 pandas 库则用来导入和管理数据集。起导入规则如下:
import numpy as np
import pandas as pd
pandas 是一个管理数据的函数库,我为我们提供了许多读取和操作数据的接口:
.csv
格式文件是我们保存数据的一种常用格式,其格式简单,其默认格式是以 ,(英文逗号)分割数据集,显示效果和 excel 表格类似。 pandas 为我们提供了访问 .csv
的接口,其 pd.read_csv()
用来进行读取 .csv
格式数据,该函数常用的参数如下:
dataset = pd.read_csv('Data.csv')
X = dataset.iloc[ : , :-1].values
Y = dataset.iloc[ : , 3].values
Data.csv是我们访问的数据集,其内容如下:
Country,Age,Salary,Purchased
France,44,72000,No
Spain,27,48000,Yes
Germany,30,54000,No
Spain,38,61000,No
Germany,40,,Yes
France,35,58000,Yes
Spain,,52000,No
France,48,79000,Yes
Germany,50,83000,No
France,37,67000,Yes
pd.read_csv()
返回的数据类型为DataFrame(把他就像成一张表),其没有原始的下表操作,我们访问内容通过如下几个函数:
.value
属性则是将 DataFrame 转成 numpy类型,以便后续的数值计算。
print(type(dataset), type(X), type(Y))
print(X.shape, Y.shape)
输出:
<class 'pandas.core.frame.DataFrame'> <class 'numpy.ndarray'> <class 'numpy.ndarray'>
(10, 3) (10,)
[['France' 44.0 72000.0]
['Spain' 27.0 48000.0]
['Germany' 30.0 54000.0]
['Spain' 38.0 61000.0]
['Germany' 40.0 nan]
['France' 35.0 58000.0]
['Spain' nan 52000.0]
['France' 48.0 79000.0]
['Germany' 50.0 83000.0]
['France' 37.0 67000.0]]
从数据集我们可以发现,某些数据为空,这时我们需要对这些缺失值进行处理。我么可以对缺失值进行均值和中值处理,即用整个数据集的该列数据的均值或中值来替换缺失的值。在sklearn的preprocessing包中包含了对数据集中缺失值的处理,主要是应用Imputer类进行处理。代码如下:
from sklearn.preprocessing import Imputer
imputer = Imputer(missing_values = "NaN", strategy = "mean", axis = 0)
imputer = imputer.fit(X[ : , 1:3])
X[ : , 1:3] = imputer.transform(X[ : , 1:3])
该代码首先导入 Imputer 类,然后通过一些参数来创建 Imputer 实例,参数意思大致如下:
pandas.read_csv()
会将确实的值默认设置为 Nan,所以这里其类型为 Nan
。注意: sklearn 库预处理操作有个特征是,其处理分为两步: fit 和 transform,fit 大致可以理解为我们对那些数据进行操作或统计,transform 表示实际进行操作。这一点和 sklearn 中的机器学习算法类似,两个固定接口: fit 和 predict。
由于我们数据库中的数据只有第2、3 列才是数值数据,我们也只能对这两列数据进行预处理,所欲第三行我们在 .fit
中指出要操作的数据,在其内部分别计算了这两列的均值,以供后面处理使用。
第四行代码执行缺失值处理,通过第三行已经计算出 相应的均值,所以这行代码实际执行缺失值处理
第三行和第四行代码可以通过.fit_transform
函数来一步执行。这也是 sklearn 的一个特点。
print(X)
输出:
[['France' 44.0 72000.0]
['Spain' 27.0 48000.0]
['Germany' 30.0 54000.0]
['Spain' 38.0 61000.0]
['Germany' 40.0 63777.77777777778]
['France' 35.0 58000.0]
['Spain' 38.77777777777778 52000.0]
['France' 48.0 79000.0]
['Germany' 50.0 83000.0]
['France' 37.0 67000.0]]
对于我们计算机进行科学计算只针对数值,而不能对文本进行数值计算,因此我们需要对文本进行数据向量化。如何用数值表示文本呢? 最常用的的格式就是 one-hot 格式,这种格式将文本表示成一个向量,该向量只有一个元素的值为1,其余全为0.
比如,我们数据集有”a”, “b”, “c”, “d”四个文本,此时我们的向量长度则为4,则这四个文本表示如下:
a: [1, 0, 0, 0]
b: [0, 1, 0, 0]
c: [0, 0, 1, 0]
d: [0, 0, 0, 1]
因此我们需要先统计数据库中所有的文本,并对每个文本从 0 开始进行编号.该过程也通过sklearn库来进行实现:
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
labelencoder_X = LabelEncoder()
X[ : , 0] = labelencoder_X.fit_transform(X[ : , 0])
由于对于特征(数据集中的最后一列是标签),只有第一列是文本,因此我们需要对第一列进行文本统计.上面代码就是将第一列的文本用自己的编号来进行表示.
print(X)
输出:
[[0 44.0 72000.0]
[2 27.0 48000.0]
[1 30.0 54000.0]
[2 38.0 61000.0]
[1 40.0 63777.77777777778]
[0 35.0 58000.0]
[2 38.77777777777778 52000.0]
[0 48.0 79000.0]
[1 50.0 83000.0]
[0 37.0 67000.0]]
如何将这些编号表示的文本转换成one-hot形式呢?这就需要使用 sklearn.preprocessing 中的 OneHotEncoder 进行编号.
onehotencoder = OneHotEncoder(categorical_features = [0])
X = onehotencoder.fit_transform(X).toarray()
labelencoder_Y = LabelEncoder()
Y = labelencoder_Y.fit_transform(Y)
categorical_features 参数指定了我们需要对哪些列进行one-hot编码,这里为0,表示对第一列,然后利用’.fit_transform’ 进行编码.由于对于标签我们只需要其标签类型,因此不需要进行 one-hot 编码.
print(X[0])
print(Y)
输出:
[1.0e+00 0.0e+00 0.0e+00 4.4e+01 7.2e+04]
[0 1 0 0 1 1 0 1 0 1]
因为第一列总共有三种文本,因此其one-hot向量长度为3,且第一个样本的 index 为0, 故其 one-hot 为 [1, 0, 0],总的就如上所示.
对于机器学习任务,我们需要将数据集按照比例划分成两个部分: 训练集和测试集.训练接用于训练模型,测试集用于测试我们模型的性能.对于数据的划分,我们使用 sklearn.cross_validation 的 train_test_split 对数据集按比例进行划分.
from sklearn.cross_validation import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split( X , Y , test_size = 0.2, random_state = 0)
print(X.shape, X_train.shape, X_test.shape)
输出:
(10, 5) (8, 5) (2, 5)
通过我们需要对数据进行标准化处理,这样可以减小噪声的影响.通常将其标准化为:均值为0, 方差为1的数据范围.
标准化之前的方差和均值:
print(np.mean(X_train), np.std(X_train))
print(np.mean(X_test), np.std(X_test))
输出:
12527.338888888888 25395.495797239782
13708.2 28152.896706378193
进行标准化:
from sklearn.preprocessing import StandardScaler
sc_X = StandardScaler()
X_train = sc_X.fit_transform(X_train)
X_test = sc_X.fit_transform(X_test)
标准化之后的均值和方法:
print(np.mean(X_train), np.std(X_train))
print(np.mean(X_test), np.std(X_test))
输出:
7.771561172376095e-17 1.0
0.0 0.6324555320336759
感谢大家的支持, 欢迎大家上星..该博客的原始Github项目地址点击这里