Scikit Learn - 建模过程

本章介绍 Sklearn 中的建模过程。让我们详细了解该过程,并从数据集加载开始。

数据集加载

数据集合称为数据集。它包含以下两个组成部分:−

特征 − 数据的变量称为特征。它们也称为预测变量、输入或属性。

  • 特征矩阵 − 如果有多个特征,则为特征的集合。

  • 特征名称 − 是所有特征名称的列表。

响应 − 是输出变量,主要依赖于特征变量。它们也称为目标、标签或输出。

  • 响应向量 − 用于表示响应列。通常,我们只有一个响应列。

  • 目标名称 − 表示响应向量可能取的值。

Scikit-learn 有一些示例数据集,例如用于分类的 iris 和 digits,以及用于回归的 Boston house prices。

示例

以下是加载 iris 数据集的示例 −

from sklearn.datasets import load_iris
iris = load_iris()
X = iris.data
y = iris.target
feature_names = iris.feature_names
target_names = iris.target_names
print("Feature names:", feature_names)
print("Target names:", target_names)
print("
First 10 rows of X:
", X[:10])

输出

Feature names: ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
Target names: ['setosa' 'versicolor' 'virginica']
First 10 rows of X:
[
   [5.1 3.5 1.4 0.2]
   [4.9 3. 1.4 0.2]
   [4.7 3.2 1.3 0.2]
   [4.6 3.1 1.5 0.2]
   [5. 3.6 1.4 0.2]
   [5.4 3.9 1.7 0.4]
   [4.6 3.4 1.4 0.3]
   [5. 3.4 1.5 0.2]
   [4.4 2.9 1.4 0.2]
   [4.9 3.1 1.5 0.1]
]

分割数据集

为了检查模型的准确性,我们可以将数据集分成两部分:训练集和测试集。使用训练集训练模型,使用测试集测试模型。之后,我们可以评估模型的表现。

示例

以下示例将数据按 70:30 的比例分割,即 70% 的数据将用作训练数据,30% 的数据将用作测试数据。数据集是如上例所示的鸢尾花数据集。

from sklearn.datasets import load_iris
iris = load_iris()

X = iris.data
y = iris.target

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 = 1
)

print(X_train.shape)
print(X_test.shape)

print(y_train.shape)
print(y_test.shape)

输出

(105, 4)
(45, 4)
(105,)
(45,)

如上例所示,它使用 scikit-learn 的 train_test_split() 函数来分割数据集。该函数包含以下参数 −

  • X, y − 其中,X 是特征矩阵,y 是响应向量,需要进行分割。

  • test_size − 表示测试数据占给定数据总量的比例。如上例所示,我们为 X 的 150 行设置 test_data = 0.3。它将生成 150*0.3 = 45 行的测试数据。

  • random_size − 用于保证拆分始终相同。这在需要可重复结果的情况下非常有用。

训练模型

接下来,我们可以使用数据集来训练一些预测模型。如上所述,scikit-learn 拥有丰富的机器学习 (ML) 算法,这些算法具有一致的接口,可用于拟合、预测准确率、召回率等。

示例

在下面的示例中,我们将使用 KNN(K 最近邻)分类器。无需深入探讨 KNN 算法的细节,因为后面会专门有一章来介绍。本示例仅用于帮助您理解具体实现部分。

from sklearn.datasets import load_iris
iris = load_iris()
X = iris.data
y = iris.target
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
   X, y, test_size = 0.4, random_state=1
)
from sklearn.neighbors import KNeighborsClassifier
from sklearn import metrics
classifier_knn = KNeighborsClassifier(n_neighbors = 3)
classifier_knn.fit(X_train, y_train)
y_pred = classifier_knn.predict(X_test)
# 通过比较实际响应值 (y_test) 和预测响应值 (y_pred) 来计算准确率
print("Accuracy:", metrics.accuracy_score(y_test, y_pred))
# 提供样本数据,模型将根据该数据进行预测

sample = [[5, 5, 3, 2], [2, 4, 3, 5]]
preds = classifier_knn.predict(sample)
pred_species = [iris.target_names[p] for p in preds] print("Predictions:", pred_species)

输出

Accuracy: 0.9833333333333333
Predictions: ['versicolor', 'virginica']

模型持久化

模型训练完成后,最好将其持久化以供将来使用,这样就无需反复训练。这可以借助 joblib 包中的 dump 和 load 功能来实现。

请考虑以下示例,我们将保存上述训练好的模型 (classifier_knn) 以供将来使用 −

from sklearn.externals import joblib
joblib.dump(classifier_knn, 'iris_classifier_knn.joblib')

上述代码将模型保存到名为 iris_classifier_knn.joblib 的文件中。现在,可以使用以下代码从文件中重新加载对象 −

joblib.load('iris_classifier_knn.joblib')

数据预处理

由于我们处理的是大量原始数据,因此在将数据输入机器学习算法之前,我们需要将其转换为有意义的数据。此过程称为数据预处理。Scikit-learn 有一个名为 preprocessing 的包用于此目的。preprocessing 包包含以下技术 −

二值化

当我们需要将数值转换为布尔值时,可以使用此预处理技术。

示例

import numpy as np
from sklearn import preprocessing
Input_data = np.array(
   [2.1, -1.9, 5.5],
   [-1.5, 2.4, 3.5],
   [0.5, -7.9, 5.6],
   [5.9, 2.3, -5.8]]
)
data_binarized = preprocessing.Binarizer(threshold=0.5).transform(input_data)
print("
Binarized data:
", data_binarized)

在上面的例子中,我们使用了阈值 = 0.5,因此所有高于 0.5 的值都会转换为 1,而所有低于 0.5 的值都会转换为 0。

输出

Binarized data:
[
   [ 1. 0. 1.]
   [ 0. 1. 1.]
   [ 0. 0. 1.]
   [ 1. 1. 0.]
]

均值消除

此技术用于消除特征向量中的均值,使每个特征都以零为中心。

示例

import numpy as np
from sklearn import preprocessing
Input_data = np.array(
   [2.1, -1.9, 5.5],
   [-1.5, 2.4, 3.5],
   [0.5, -7.9, 5.6],
   [5.9, 2.3, -5.8]]
)

#显示输入数据的平均值和标准差
print("Mean=", input_data.mean(axis=0))
print("Stddeviation = ", input_data.std(axis=0))
#去除输入数据的平均值和标准差

data_scaled = preprocessing.scale(input_data)
print("Mean_removed=", data_scaled.mean(axis=0))
print("Stddeviation_removed=", data_scaled.std(axis=0))

输出

Mean = [ 1.75 -1.275 2.2 ]
Stddeviation = [ 2.71431391 4.20022321 4.69414529]
Mean_removed = [ 1.11022302e-16 0.00000000e+00 0.00000000e+00]
Stddeviation_removed = [ 1. 1. 1.]

缩放

我们使用这种预处理技术来缩放特征向量。特征向量的缩放非常重要,因为特征不应该合成地过大或过小。

示例

import numpy as np
from sklearn import preprocessing
Input_data = np.array(
   [
      [2.1, -1.9, 5.5],
      [-1.5, 2.4, 3.5],
      [0.5, -7.9, 5.6],
      [5.9, 2.3, -5.8]
   ]
)
data_scaler_minmax = preprocessing.MinMaxScaler(feature_range=(0,1))
data_scaled_minmax = data_scaler_minmax.fit_transform(input_data)
print ("
Min max scaled data:
", data_scaled_minmax)

输出

Min max scaled data:
[
   [ 0.48648649 0.58252427 0.99122807]
   [ 0. 1. 0.81578947]
   [ 0.27027027 0. 1. ]
   [ 1. 0.99029126 0. ]
]

归一化

我们使用这种预处理技术来修改特征向量。为了使特征向量能够以通用尺度进行测量,必须对特征向量进行归一化。归一化有两种类型:−

L1 归一化

它也被称为最小绝对值偏差。它以这样的方式修改值,使每行的绝对值之和始终保持在 1 以内。以下示例展示了对输入数据实施 L1 归一化的方法。

示例

import numpy as np
from sklearn import preprocessing
Input_data = np.array(
   [
      [2.1, -1.9, 5.5],
      [-1.5, 2.4, 3.5],
      [0.5, -7.9, 5.6],
      [5.9, 2.3, -5.8]
   ]
)
data_normalized_l1 = preprocessing.normalize(input_data, norm='l1')
print("
L1 normalized data:
", data_normalized_l1)

输出

L1 normalized data:
[
   [ 0.22105263 -0.2 0.57894737]
   [-0.2027027 0.32432432 0.47297297]
   [ 0.03571429 -0.56428571 0.4 ]
   [ 0.42142857 0.16428571 -0.41428571]
]

L2 正则化

也称为最小二乘法。它以某种方式修改值,使每行的平方和始终保持在 1 左右。以下示例展示了如何对输入数据进行 L2 正则化。

示例

import numpy as np
from sklearn import preprocessing
Input_data = np.array(
   [
      [2.1, -1.9, 5.5],
      [-1.5, 2.4, 3.5],
      [0.5, -7.9, 5.6],
      [5.9, 2.3, -5.8]
   ]
)
data_normalized_l2 = preprocessing.normalize(input_data, norm='l2')
print("
L1 normalized data:
", data_normalized_l2)

输出

L2 normalized data:
[
   [ 0.33946114 -0.30713151 0.88906489]
   [-0.33325106 0.53320169 0.7775858 ]
   [ 0.05156558 -0.81473612 0.57753446]
   [ 0.68706914 0.26784051 -0.6754239 ]
]