SciKit-Learn教程

介绍

Scikit-learn(简称sklearn)是开源的Python机器学习库,它基于Numpy和Scipy,提供了大量用于数据挖掘和分析的工具,包括数据预处理、交叉验证、算法与可视化算法等一系列接口。

sklearn的官方网站是http://scikit-learn.org/stable/,在上面可以找到相关的Scikit-Learn的资源,模块下载,文档,例程等。
sklearn的基本功能主要被分为六个部分,分类,回归,聚类,数据降维,模型选择,数据预处理,具体可以参考官方网站上的文档。

Reference:

Scikit-Learn简介

通用学习模式

1、导入数据、模型

2、获取特征数据与对应标记

3、训练集/测试集划分(K折交叉验证)

4、模型训练

5、模型性能评估(predict、score)

K近邻

1、导入数据、模型

1
2
3
from sklearn import datasets
from sklearn.model_selection import train_test_split # 划分训练集/测试集的模块
from sklearn.neighbors import KNeighborsClassifier

2、获取特征数据与标记

1
2
3
iris = datasets.load_iris()
iris_X = iris.data
iris_y = iris.target

3、训练集/测试集划分(随机打乱数据后按照给定参数划分训练集/测试集)

1
X_train,X_test,y_train,y_test = train_test_split(iris_X,iris_y,test_size=0.3)

4、模型训练

1
2
knn = KNeighborsClassifier()
knn.fit(X_train,y_train)

5、模型性能评估(predict、score)

1
2
print(knn.predict(X_test))
print(y_test)
1
2
3
4
[0 2 1 2 0 2 1 0 1 2 2 1 0 0 1 2 1 0 2 2 2 1 2 1 0 2 1 2 0 0 0 2 1 2 0 1 0
0 2 2 0 2 2 0 1]
[0 2 1 1 0 2 1 0 1 2 2 1 0 0 1 2 1 0 2 2 2 1 2 1 0 2 1 2 0 0 0 1 1 2 0 1 0
0 2 2 0 2 2 0 1]

参数

1
knn.get_params    # 获得之前模型设置的参数
<bound method BaseEstimator.get_params of KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
           metric_params=None, n_jobs=1, n_neighbors=5, p=2,
           weights='uniform')>

线性回归

1、导入模块

1
2
from sklearn import datasets
from sklearn.linear_model import LinearRegression

2、载入数据

1
2
3
loaded_data = datasets.load_boston() # boston房价与一些特征数据
data_X = loaded_data.data # 特征数据,即:面积、楼层、离市中心远近等等
data_y = loaded_data.target # 房价

3、模型选择、模型训练

1
2
model = LinearRegression()  # 线性回归模型
model.fit(data_X,data_y)

4、模型性能评估

1
2
3
# 预测第0、1、2、3个样本的房价 单位:/万
print(model.predict(data_X[:4,:]))
print(data_y[:4])
[ 30.00821269  25.0298606   30.5702317   28.60814055]
[ 24.   21.6  34.7  33.4]

模型的参数

模型不同特征所对应的斜率:

1
print(model.coef_)
array([ -1.07170557e-01,   4.63952195e-02,   2.08602395e-02,
         2.68856140e+00,  -1.77957587e+01,   3.80475246e+00,
         7.51061703e-04,  -1.47575880e+00,   3.05655038e-01,
        -1.23293463e-02,  -9.53463555e-01,   9.39251272e-03,
        -5.25466633e-01])

模型的截距(与y轴的交点):

1
print(model.intercept_)
36.491103280361983

创造一些数据

1
import matplotlib.pyplot as plt

参数说明:

make_regression():生成一些适用于回归模型的样本

  • n_samples:生成的样本数
  • n_features:特征个数
  • n_targets:标记个数
  • noise:样本噪声,越大样本越离散
1
X,y = datasets.make_regression(n_samples=100,n_features=1,n_targets=1,noise=5)

样本可视化

1
2
plt.scatter(X,y)
plt.show()

正规化 Normalization

数据标准化

1
2
from sklearn import preprocessing #标准化数据模块
import numpy as np
1
2
3
4
a = np.array([[10,2.7,3.6],
[-100, 5, -2],
[120, 20, 40]
],dtype = np.float64)

将Normalized前的a打印出来:

1
print(a)
1
2
3
[[  10.     2.7    3.6]
[-100. 5. -2. ]
[ 120. 20. 40. ]]

将Normalized后的a打印出来:

1
print(preprocessing.scale(a))
[[ 0.         -0.85170713 -0.55138018]
 [-1.22474487 -0.55187146 -0.852133  ]
 [ 1.22474487  1.40357859  1.40351318]]

数据标准化对机器学习性能的影响

1、模块导入

1
2
3
4
5
6
7
8
9
10
from sklearn import preprocessing#标准化数据模块
import numpy as np
# 划分训练集/测试集的模块
from sklearn.model_selection import train_test_split
# 生成适合做classification资料的模块
from sklearn.datasets.samples_generator import make_classification
# Support Vector Machine中的Support Vector Classifier
from sklearn.svm import SVC
# 可视化数据的模块
import matplotlib.pyplot as plt

2、生成数据

1
2
3
4
5
X, y = make_classification(
n_samples=300, n_features=2,
n_redundant=0, n_informative=2,
random_state=22, n_clusters_per_class=1,
scale=100)

3、数据可视化

1
2
3
#可视化数据
plt.scatter(X[:, 0], X[:, 1], c=y)
plt.show()

数据标准化前的模型准确率

1
2
3
4
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3)
clf = SVC()
clf.fit(X_train,y_train)
print("数据标准化之前,准确率为:",clf.score(X_test,y_test))
数据标准化之前,准确率为: 0.477777777778

数据标准化之后的模型准确率

1
2
3
4
5
6
X = preprocessing.scale(X) # Nomalization
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
clf = SVC()
clf.fit(X_train, y_train)
print("数据标准化之后,准确率为:",clf.score(X_test, y_test))
# 0.9
数据标准化之后,准确率为: 0.977777777778

显而易见,数据标准化之后,模型的准确率有了巨大的提升

交叉验证

Model 基础验证法

1
2
3
4
5
# iris数据集
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
# K最近邻(kNN,k-NearestNeighbor)分类算法
from sklearn.neighbors import KNeighborsClassifier
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#加载iris数据集
iris = load_iris()
X = iris.data
y = iris.target

#分割数据并
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=4)

#建立模型
knn = KNeighborsClassifier()

#训练模型
knn.fit(X_train, y_train)

#将准确率打印出
print(knn.score(X_test, y_test))
# 0.973684210526
0.973684210526

Model 交叉验证法(Cross Validation)

将一个数据集,在每轮次训练前,划分成不同的Train_Set和Test_Set

使用K折交叉验证模块:
scores = cross_val_score(knn, X, y, cv=5, scoring=’accuracy’)

参数说明:

cross_val_score():模型的交叉验证法,使模型性能评估更加精准,更加可靠

  • 第一个参数:使用的算法模型
  • 第二个参数:数据集
  • 第三个参数:数据集所对应的标记
  • cv:k折交叉验证,的K值
  • scoring:使用什么方法来进行性能评分
    • ‘accuracy’(精确率)一般用于分类模型
    • ‘mean_squared_error’(平均方差)一般用于回归模型,使用此值函数输出会是负值,所以需要在函数前边加一个负号

1
2
3
4
5
6
7
8
9
10
from sklearn.cross_validation import cross_val_score # K折交叉验证模块

#使用K折交叉验证模块
scores = cross_val_score(knn, X, y, cv=5, scoring='accuracy')

#将5次的预测准确率打印出
print(scores)

#将5次的预测准确平均率打印出
print(scores.mean())
[ 0.96666667  1.          0.93333333  0.96666667  1.        ]
0.973333333333

以准确率判断

​ 一般来说准确率(accuracy)会用于判断分类(Classification)模型的好坏。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import matplotlib.pyplot as plt #可视化模块

#建立测试参数集
k_range = range(1, 31)

k_scores = []

#藉由迭代的方式来计算不同参数对模型的影响,并返回交叉验证后的平均准确率
for k in k_range:
knn = KNeighborsClassifier(n_neighbors=k)
scores = cross_val_score(knn, X, y, cv=10, scoring='accuracy')
k_scores.append(scores.mean())

#可视化数据
plt.plot(k_range, k_scores)
plt.xlabel('Value of K for KNN')
plt.ylabel('Cross-Validated Accuracy')
plt.show()

从图中可以得知,选择12~18的k值最好。高过18之后,准确率开始下降则是因为过拟合(Over fitting)的问题。

以平均方差(Mean squared error)

​ 一般来说平均方差(Mean squared error)会用于判断回归(Regression)模型的好坏。

1
2
3
4
5
6
7
8
9
10
11
12
import matplotlib.pyplot as plt
k_range = range(1, 31)
k_scores = []
for k in k_range:
knn = KNeighborsClassifier(n_neighbors=k)
loss = -cross_val_score(knn, X, y, cv=10, scoring='mean_squared_error')
k_scores.append(loss.mean())

plt.plot(k_range, k_scores)
plt.xlabel('Value of K for KNN')
plt.ylabel('Cross-Validated MSE')
plt.show()

由图可以得知,平均方差越低越好,因此选择13~18左右的K值会最好。

Learning curve 检视过拟合

参数说明:

learning_curve():模型的交叉验证法,使模型性能评估更加精准,更加可靠

  • 第一个参数:算法模型

  • 第二个参数:数据集

  • 第三个参数:数据集所对应的标记

  • cv:k折交叉验证,的K值

  • scoring:使用什么方法来进行性能评分

    • ‘accuracy’(精确率)一般用于分类模型
    • ‘mean_squared_error’(平均方差)一般用于回归模型,使用此值函数输出会是负值,所以需要在函数前边加一个负号
  • train_sizes:元素取值为0-1的列表,表示第百分之几个样本记录一次

  • 返回值:一个元组(p1,p2 ,p3 )

    • train_sizes(每次记录时,第几个样本正在训练),
    • train_loss(二维列表,每行对应train_sizes的一个元素,行中存储K次训练集交叉验证的误差记录, len(train_sizes) 行,K列)
    • test_loss(二维列表,每行对应train_sizes的一个元素,行中存储K次测试集交叉验证的误差记录, len(train_sizes) 行,K列)

1、加载对应模块

1
2
3
4
5
from sklearn.learning_curve import learning_curve #学习曲线模块
from sklearn.datasets import load_digits #digits数据集
from sklearn.svm import SVC #Support Vector Classifier
import matplotlib.pyplot as plt #可视化模块
import numpy as np

2、加载digits数据集,其包含的是手写体的数字,从0到9。数据集总共有1797个样本,每个样本由64个特征组成, 分别为其手写体对应的8×8像素表示,每个特征取值0~16。

1
2
3
digits = load_digits()
X = digits.data
y = digits.target

3、设置观察样本由小到大的学习曲线变化参数, 采用K折交叉验证 cv=10, 选择平均方差检视模型效能 scoring=’mean_squared_error’, 样本由小到大分成5轮检视学习曲线(10%, 25%, 50%, 75%, 100%):

1
2
3
4
5
6
7
train_sizes, train_loss, test_loss = learning_curve(
SVC(gamma=0.01), X, y, cv=10, scoring='mean_squared_error',
train_sizes=[0.1, 0.25, 0.5, 0.75, 1])

#平均每一轮所得到的平均方差(共5轮,分别为样本10%、25%、50%、75%、100%)
train_loss_mean = -np.mean(train_loss, axis=1)
test_loss_mean = -np.mean(test_loss, axis=1)

4、可视化图形:

1
2
3
4
5
6
7
8
9
plt.plot(train_sizes, train_loss_mean, 'o-', color="r",
label="Training")
plt.plot(train_sizes, test_loss_mean, 'o-', color="g",
label="Cross-validation")

plt.xlabel("Training examples")
plt.ylabel("Loss")
plt.legend(loc="best")
plt.show()

gamma = 0.001时:

gamma = 0.01时:

很明显以gamma = 0.01的参数来训练模型时,模型出现了严重的Overfitting(过拟合)问题

validation_curve 检视过拟合

​ 使用validation_curve验证SVC中的一个参数gamma,在什么范围内能使 model 产生好的结果。以及过拟合和 gamma取值的关系

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from sklearn.learning_curve import validation_curve #validation_curve模块
from sklearn.datasets import load_digits
from sklearn.svm import SVC
import matplotlib.pyplot as plt
import numpy as np

#digits数据集
digits = load_digits()
X = digits.data
y = digits.target

#建立参数测试集
param_range = np.logspace(-6, -2.3, 5)

#使用validation_curve快速找出参数对模型的影响
train_loss, test_loss = validation_curve(
SVC(), X, y, param_name='gamma', param_range=param_range, cv=10, scoring='mean_squared_error')

#平均每一轮的平均方差
train_loss_mean = -np.mean(train_loss, axis=1)
test_loss_mean = -np.mean(test_loss, axis=1)

#可视化图形
plt.plot(param_range, train_loss_mean, 'o-', color="r",
label="Training")
plt.plot(param_range, test_loss_mean, 'o-', color="g",
label="Cross-validation")

plt.xlabel("gamma")
plt.ylabel("Loss")
plt.legend(loc="best")
plt.show()

由图中可以明显看到gamma值大于0.001,模型就会有过拟合(Overfitting)的问题。

保存模型

首先简单建立与训练一个SVC Model

1
2
3
4
5
6
7
from sklearn import svm
from sklearn import datasets

clf = svm.SVC()
iris = datasets.load_iris()
X, y = iris.data, iris.target
clf.fit(X,y)

使用pickle保存

使用pickle保存读取训练好的Model

1
2
3
4
5
6
7
8
9
10
11
12
13
import pickle #pickle模块

#保存Model(注:save文件夹要预先建立,否则会报错)
with open('save/clf.pickle', 'wb') as f:
pickle.dump(clf, f)

#读取Model
with open('save/clf.pickle', 'rb') as f:
clf2 = pickle.load(f)
#测试读取后的Model 预测类别
print(clf2.predict(X[0:1]))

# [0]

使用保存joblib保存

joblib是sklearn的外部模块。

1
2
3
4
5
6
7
8
9
10
11
12
from sklearn.externals import joblib #jbolib模块

#保存Model(注:save文件夹要预先建立,否则会报错)
joblib.dump(clf, 'save/clf.pkl')

#读取Model
clf3 = joblib.load('save/clf.pkl')

#测试读取后的Model 准确率评估
print(clf3.score(X,y))

# 0.986666666667

joblib在使用上比较容易,读取速度也相对pickle快。

所以直接选择使用joblib即可。

Author:morvanzhou