目录
一、开篇前言
二、数据集
三、集成管道方法训练模型
四、k折交叉验证评估模型
五、可视化模型效果
1、学习曲线
2、验证曲线
六、超参数调优:网格搜索
七、性能评估指标:精度、召回率、F1-score
八、最后
一、开篇前言
本篇详细记录最近学习的机器学习模型评估和超参数调优知识,通过一个项目的实践基本掌握评估我们构建出的模型的性能,并不断微调超参进一步优化模型效果。接下来将介绍详细的步骤,主要使用到python的第三方库sklearn,功能很强大,包含了机器学习中许多算法和处理技术,如PCA降维、数据标准化、k折交叉验证、SVM支持向量机等。
二、数据集
本次使用到的数据集来自UCI机器学习存储库的wdbc.data(威斯康星乳腺癌数据集),其中包含了569个正常和异常的细胞样本,特征共30个,因此,我们的任务就是通过这些特征值建立一个好的模型来预测标签。
上图是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_))
获取标签结果以及转换为整型如图:
现在已经完成最初一步,先看看项目使用到哪些模块/第三方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()
可以直观看到模型随着训练样本的增加,准确率也有所提高,达到比较好的结果。关键学习使用函数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()
如图,该模型很好的拟合了数据。
六、超参数调优:网格搜索
这是机器学习构建出模型并初步评估之后下一个步骤:调参。网格搜索属于一种方法,暴力穷举类型。 以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则是两者之间的平和度量,研究意义更重要。 这里需要用到混淆矩阵:
应用到本次实践项目具体实现:
# 精度,召回率,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.