Python机器学习----第4部分 模型评估和参数调优

1、流水线集成数据转换和训练

  一般为了优化性能,提高准确率,一个常见的流程如下:对数据进行标准化转换,在采用上篇文章介绍的PCA(主成分分析)技术做特征抽取进行降维;最后在使用学习算法训练模型,并评价模型性能。

from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
pipe_lr = Pipeline([('scl', StandardScaler()), 
                    ('pca', PCA(n_components = 2)), 
                    ('clf', LogisticRegression(random_state=1))])
pipe_lr.fit(X_train, Y_train)
pipe_lr.score(X_test, Y_test) #用测试集评估准确率
2、K折交叉验证

为了降低所选训练数据和测试数据对模型评估对影响,引入K折交叉验证法。即不重复的将训练数据划分为K个子集,其中K-1个用于训练,剩余1个用于测试。重复这个过程K次,得到K个准确率值,可取均值进行评估。

from sklearn.cross_validation import Cross_Val_Score
scores = Cross_Val_Score(estimator = pipe_lr,
                         X = X_train,
                         Y = Y_train,
                         CV = 10,    #指定K的值
                         n_jobs = 1)
np.mean(scores)  #平均准确率
np.std(scores)   #计算标准差  标准差是评估数据离散的程度
如果训练的分类数据比例相差较大,需要保证每个分块中各类别数据的比例不变(与全部训练数据的比例一致)。这时需要采用分层交叉验证:

import numpy as np
from sklearn.cross_validation import StratifiedKFold
kfold = StratifiedKFold(y = Y_train,
                        n_folds = 10,
                        random_state = 1)
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)
在模型调优过程中,我们使用K折交叉验证法找到最优超参,在用此超参做正常训练和评估。
3、绘制学习曲线得到样本数与准确率的关系

from sklearn.learning_curve import learning_curve
train_size, train_scores, test_scores = leanrning_curve(estimator=pipe_lr,
                                                    X=X_train,
                                                    Y=Y_train,
                                                    train_sizes=np.linspace(0.1, 1, 10),#在0.1和1间线性的取10个值
                                                    cv = 10,
                                                    n_jobs = 1)
train_mean = np.mean(train_scores, axis=1) #对得分矩阵train_scores各行取均值得到m列的向量 对十次评分取均值
test_mean = np.mean(test_scores, axis=1)   #对得分矩阵test_scores各行取均值得到m列的向量  对十次评分取均值
取得评分均值后,分别使用train_mean + train_size、test_mean + train_size绘制点阵图,观察样本数据量与训练准确率、测试准确率的关系。进而评估出模型是过拟合还是欠拟合。
4、绘制验证曲线得到超参和准确率关系

from sklearn.learning_curve import validation_curve
param_range = [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='clf_C',#针对管道中名称为clf的模型,调整其参数C
              param_range=param_range,#指定参数取值范围
              cv = 10)
train_mean = np.mean(train_scores, axis=1)
text_mean = np.mean(text_scores, axis=1)
取得评分均值后,分别使用train_mean + train_size、test_mean + train_size绘制点阵图,观察模型超参与训练准确率、测试准确率的关系。进而评估模型最优超参。
5、网格搜索调优超参

from sklearn.grid_search import GridSearchCV
from sklearn.svm import SVC
pipe_scv = Pipeline([('scl', StandardScaler()),
                     ('clf', SVC(random_state=1))])
param_range=[0.0001, 0.001, 0.01, 0.1, 1.0, 10.0, 100.0, 1000.0]
param_grid=[{'clf_C':param_range, 'clf_kernel': ['linear']},
            {'clf_C':param_range, 'clf_gamma':param_range, 'clf_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)
gs.best_score_ #最优准确率
gs.best_params #最优超参组合

#获取最优模型进行评估
clf = gs.best_estimator_
clf.fit(X_train, Y_train)
clf.score(X_test, Y_test)
网格搜索计算成本较高,为提高速度,可采用RandomizedSearchCV类。
6、选择最优算法

上面使用GridSearchCVC得到算法的最优参数和最优准确率,使用同样的方式对多个算法进行横向比较,进而得到最优算法。

gs = GridSearchCV(estimator = pipe_svc,#更换其他算法进行比较
                  param_grid = param_grid,
                  scoring='accuracy',
                  cv = 10,
                  n_jobs = -1)
scores = cross_val_score(gs, X, Y, scroing = 'accuracy', sv = 5)
np.mean(scores)
np.std(scores)
注意:这里将GridSearchCV和cross_val_score组合起来比较算法准确率。

7、模型性能评估指标

在上面评估模型性能的时候,我们只是简单的采用准确率这个指标,在一些场景下,还可以采用其他评估方式。比如我们在分析肿瘤诊断结果时,更为关注的是正确检测出的恶性肿瘤,使得病人得到恰当治疗;当然降低良性肿瘤错误划分为恶性肿瘤的概率也很重要,但对患者影响并不大。这里我们就可以关注真正率。

根据模型验证结果,可以得到混淆矩阵(2X2矩阵,分别是真正、假负、假正、真负)


真正:正确分类的正样本数

假正:错误分类的负样本数

真负:正确分类的负样本数

假负:错误分类的正样本数

from sklearn.metrics import confusion_metrix
pipe_svc.fit(X_train, Y_train)
Y_pred = pipe_scv.predict(X_test)
confmat = confusion_metrix(y_true = Y_test, y_pred = Y_pred)
误差率 = (假正+假负) / (真正 + 真负 + 假正 + 假负)

准确率 = 1 - 误差率 = (真正 + 真负)/ (真正 + 真负 + 假正 + 假负)

真正率 = 真正 / (真正 + 假负)

假正率 = 假正 / (真负 + 假正)

针对正样本的三个评估指标:

准确率=真正 / (真正 + 假正)----正样本的正确预测率

召回率 = 真正 / (真正 + 假负)----正样本正确分类的概率

F1 = (准确率 X 召回率 / (准确率 + 召回率)

from sklearn.metrics import precision_score, recall_score, f1_score
pipe_svc.fit(X_train, Y_train)
Y_pred = pipe_scv.predict(X_test)
precision_score(y_true=Y_test,y_pred=Y_pred) #计算准确率
recall_score(y_true=Y_test,y_pred=Y_pred)    #计算召回率
f1_score(y_true=Y_test,y_pred=Y_pred)        #计算f1
GridSearchCV构造函数有一个scoring参数(以前传递的是'accuracy'),可以指定上述三个评估指标进而改变评估标准:

from sklearn.metrics import precision_score, recall_score, f1_score
scorer = make_scorer(f1_score, pos_label=0)
gs = GridSearchCV(estimator = pipe_svc,
                  param_grid = param_grid,
                  scoring = scorer,  #指定了其他评估方法
                  cv = 10)
如果要基于真正率和假正率这两个指标评估分类模型,可绘制出ROC(受试者工作特征)曲线,完美曲线为真正率为1,假正率为0(横轴0与纵轴1组成的折线),绘制各个分类模型的ROC曲线,选择最接近完美曲线的模型。

如果只是想得到ROC AUC评分,可使用roc_auc_score函数:

pipe_svc = pipe_svc.fit(X_train, Y_train)
Y_pred = pipe_svc.predict(X_test)
from sklearn.metrics import roc_auc_score,accuracy_score
roc_auc_score(y_true = Y_test, y_score = Y_pred)#得到roc auc评分
accuracy_score(y_true = Y_test, y_pred = Y_pred)#准确率
ROC AUC评分可以进一步评估分类器在类别不均衡样本上的性能。



猜你喜欢

转载自blog.csdn.net/henreash/article/details/79089279