基于sklearn库的机器学习模型与调优实践详细步骤

98
0
2021年1月14日 09时40分

目录

一、开篇前言
二、数据集
三、集成管道方法训练模型
四、k折交叉验证评估模型
五、可视化模型效果
    1、学习曲线
    2、验证曲线
六、超参数调优:网格搜索
七、性能评估指标:精度、召回率、F1-score
八、最后

 

一、开篇前言

本篇详细记录最近学习的机器学习模型评估和超参数调优知识,通过一个项目的实践基本掌握评估我们构建出的模型的性能,并不断微调超参进一步优化模型效果。接下来将介绍详细的步骤,主要使用到python的第三方库sklearn,功能很强大,包含了机器学习中许多算法和处理技术,如PCA降维、数据标准化、k折交叉验证、SVM支持向量机等。

二、数据集

本次使用到的数据集来自UCI机器学习存储库的wdbc.data(威斯康星乳腺癌数据集),其中包含了569个正常和异常的细胞样本,特征共30个,因此,我们的任务就是通过这些特征值建立一个好的模型来预测标签。

 

wdbc数据

 

上图是wdbc.data数据集的情况。

接下来,先读取数据文件。文件路径使用了相对路径,文件结构可参考:

 

文件结构

 

import pandas as pd
df = pd.read_csv('wdbc.data', header=None)
X = df.loc[:, 2:].values
y = df.loc[:, 1].values
le = LabelEncoder()
y = le.fit_transform(y)
# 分类标签
print(le.classes_)
# 将字符串型分类标签转化为整型[0,1]
print(le.transform(le.classes_))

 

获取标签结果以及转换为整型如图:

 

3

 

现在已经完成最初一步,先看看项目使用到哪些模块/第三方python库,可添加至文件头,后面会使用到。

import pandas as pd
import numpy as np
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.model_selection import train_test_split, StratifiedKFold, cross_val_score, learning_curve, \
    validation_curve, GridSearchCV
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import confusion_matrix, precision_score, recall_score, f1_score, roc_curve, auc
from sklearn.decomposition import PCA
from sklearn.svm import SVC
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import make_pipeline
import matplotlib.pyplot as plt

三、集成管道方法训练模型

划分数据集并构建初步模型,使用8:2进行划分成为训练集和测试集。另外,需要对特征列进行标准化处理,才能输入到模型如逻辑回归线性分类器,并使用PCA技术降维提取主成分。这个过程通过使用管道来连接拟合模型。

# 划分训练集和测试集8:2
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, stratify=y, random_state=1)
# 使用管道将数据标准化,降维和拟合模型
pipe_lr = make_pipeline(StandardScaler(), PCA(n_components=2), LogisticRegression(random_state=1))
pipe_lr.fit(X_train, y_train)
print('Test acc:%.3f' % pipe_lr.score(X_test, y_test))

 

结果输出:Test acc:0.956

这部分关键是学习到sklearn的pipeline管道,将标准化和PCA两个步骤作为输入进行构建,fit方法来拟合模型,predict方法来预测。

 

四、k折交叉验证评估模型

k折交叉验证的原理很容易理解,对于小样本数据,进行无替换的重复采样,每次划分不同部分为训练集和验证集,最优标准k取10,实验证明此时达到了偏差和方差的最佳平衡。另外,可以根据数据集规模大小合理选择k值,k值越大,训练模型花费的计算时间越多。

 

对应这次项目实践,使用10折交叉验证,为了更好理解工作机制,自行实现具体代码:

# k折交叉验证评估模型性能,工作机制
kfold = StratifiedKFold(n_splits=10, random_state=2021, shuffle=True).split(X_train, y_train)  #
scores = []
for k, (train, test) in enumerate(kfold):
    pipe_lr.fit(X_train[train], y_train[train])
    score = pipe_lr.score(X_train[test], y_train[test])
    scores.append(score)
    print('Fold', k + 1, ",Acc:%.3f" % score)
print('Mean Acc:%.3f' % np.mean(scores), '+/- %.3f' % np.std(scores))

 

执行结果:

Fold 1 ,Acc:0.913
Fold 2 ,Acc:0.957
Fold 3 ,Acc:0.891
Fold 4 ,Acc:0.913
Fold 5 ,Acc:0.935
Fold 6 ,Acc:0.978
Fold 7 ,Acc:0.933
Fold 8 ,Acc:0.956
Fold 9 ,Acc:1.000
Fold 10 ,Acc:1.000
Mean Acc:0.948 +/- 0.035

也可以更简洁地使用封装好的交叉验证函数:

# 使用k折交叉验证得分器更简洁地评估模型
scores1 = cross_val_score(estimator=pipe_lr, X=X_train, y=y_train, cv=10, n_jobs=1)
print('Acc score:', scores1)
print('CV Acc:%.3f' % np.mean(scores1))

 

结果:Acc score: [0.93478261 0.93478261 0.95652174 0.95652174 0.93478261 0.95555556 0.97777778 0.93333333 0.95555556 0.95555556]
CV Acc:0.950

 

五、可视化模型效果

1、学习曲线

可视化的方法能更直观看到模型的效果,学习曲线就是训练数据过程中模型不断学习的可视化表示,能够看出模型是否高偏差、高方差,目的为后续调参提供帮助,使模型更好地拟合数据,向好的偏差和方差折中方向优化。

 

可视化学习曲线的具体实现如下,使用matplotlib画出曲线图。

# 可视化学习曲线评估模型
pipe_lr = make_pipeline(StandardScaler(), LogisticRegression(penalty='l2', random_state=1))
train_sizes, train_scores, test_scores = learning_curve(estimator=pipe_lr, X=X_train, y=y_train,
                                                        train_sizes=np.linspace(0.1, 1.0, 10), cv=10, n_jobs=1)
train_mean = np.mean(train_scores, axis=1)
train_std = np.std(train_scores, axis=1)
test_mean = np.mean(test_scores, axis=1)
test_std = np.std(test_scores, axis=1)
plt.plot(train_sizes, train_mean, color='blue', marker='o', markersize=5, label='training acc')
plt.fill_between(train_sizes, train_mean + train_std, train_mean - train_std, alpha=0.15, color='blue')

plt.plot(train_sizes, test_mean, color='green', linestyle='--', marker='s', markersize=5, label='test acc')
plt.fill_between(train_sizes, test_mean + test_std, test_mean - test_std, alpha=0.15, color='green')

plt.grid()
plt.xlabel('Number of training samples')
plt.ylabel('Acc')
plt.legend(loc='lower right')
plt.ylim([0.8, 1.025])
plt.show()

 

Figure_1学习曲线

 

可以直观看到模型随着训练样本的增加,准确率也有所提高,达到比较好的结果。关键学习使用函数learning_curve,拟合数据并画出曲线。

 

2、验证曲线

同理,验证曲线也是为了更好地优化模型,帮助解决模型过拟合或者欠拟合的问题。使用到函数validation_curve。

具体类似实现代码:

# 可视化验证曲线解决过拟合和欠拟合问题

param = [0.001, 0.01, 0.1, 1.0, 10.0, 100.0]
train_scores, test_scores = validation_curve(estimator=pipe_lr, X=X_train, y=y_train,
                                             param_name='logisticregression__C',
                                             param_range=param, cv=10)
train_mean = np.mean(train_scores, axis=1)
train_std = np.std(train_scores, axis=1)
test_mean = np.mean(test_scores, axis=1)
test_std = np.std(test_scores, axis=1)
plt.plot(param, train_mean, color='blue', marker='o', markersize=5, label='training acc')
plt.fill_between(param, train_mean + train_std, train_mean - train_std, alpha=0.15, color='blue')

plt.plot(param, test_mean, color='green', linestyle='--', marker='s', markersize=5, label='test acc')
plt.fill_between(param, test_mean + test_std, test_mean - test_std, alpha=0.15, color='green')

plt.grid()
plt.xscale('log')
plt.xlabel('Parameter C')
plt.ylabel('Acc')
plt.legend(loc='lower right')
plt.ylim([0.8, 1.0])
plt.show()

 

Figure_2验证曲线

如图,该模型很好的拟合了数据。

 

六、超参数调优:网格搜索

这是机器学习构建出模型并初步评估之后下一个步骤:调参。网格搜索属于一种方法,暴力穷举类型。

 

以SVM支持向量机为例,预定义好一些超参,让算法寻找最佳组合。使用到GridSearchCV函数。

# 网格搜索调优超参数,支持向量机模型
pipe_svc = make_pipeline(StandardScaler(), SVC(random_state=1))
param = [0.0001, 0.001, 0.01, 0.1, 1.0, 10.0, 100.0, 1000.0]
param_grid = [{'svc__C': param, 'svc__kernel': ['linear']},
              {'svc__C': param, 'svc__gamma': param, 'svc__kernel': ['rbf']}]
gs = GridSearchCV(estimator=pipe_svc, param_grid=param_grid, scoring='accuracy', cv=10, n_jobs=1)
gs = gs.fit(X_train, y_train)
print('Best score:', gs.best_score_)
print('Best param:', gs.best_params_)

 

得到结果 Best score: 0.9846859903381642 Best param: {‘svc__C’: 100.0, ‘svc__gamma’: 0.001, ‘svc__kernel’: ‘rbf’}

 

# 模型应用找到的最优参数
clf = gs.best_estimator_
clf.fit(X_train, y_train)
print('Train Acc:%.3f' % clf.score(X_train, y_train))
print('Test Acc:%.3f' % clf.score(X_test, y_test))

 

结果:

Train Acc:0.989
Test Acc:0.974

 

很明显,这个方法是寻找最优参数的有力手段,但也有计算成本高的缺点。

 

七、性能评估指标:精度、召回率、F1-score

众所周知,一个模型的性能评估会使用多种度量方式,对模型在测试集/验证集不同方面进行评价。常用的有准确率、精度、召回率和F1-score。准确率作为评估指标前面已经使用多次,它的实际意义也很容易理解,衡量有多少的样本在测试集的预测是正确的。

 

而精度和召回率的性能指标是真正性(TP)和假正性(FP)的比率。F1-score则是两者之间的平和度量,研究意义更重要。

这里需要用到混淆矩阵:

 

Figure_3混淆矩阵

 

应用到本次实践项目具体实现:

# 精度,召回率,F1-score
print('Precision:%.3f' % precision_score(y_true=y_test, y_pred=y_pred))
print('Recall:%.3f' % recall_score(y_true=y_test, y_pred=y_pred))
print('F1-score:%.3f' % f1_score(y_true=y_test, y_pred=y_pred))

 

输出结果:

 

Precision:0.976
Recall:0.952
F1-score:0.964

八、最后

本篇通过一个项目的实践学习掌握评估我们构建出的模型的性能,并不断微调超参进一步优化模型效果。详细介绍看最近学习的机器学习模型评估和超参数调优知识,自行实现一遍之后,可以举一反三,在以后不同的机器学习任务中,应用类似的思想和方法步骤,来训练我们的模型。

本次实战后,学习更多关于sklearn库,功能很强大,包含了机器学习中许多算法和处理技术,如PCA降维、数据标准化、k折交叉验证、SVM支持向量机等。

如果觉得不错欢迎三连哦,点赞收藏关注,一起加油进步!原创作者:Charzous.

发表评论

后才能评论