美文网首页
实战演练网格搜索与模型调参

实战演练网格搜索与模型调参

作者: 人工智能遇见磐创 | 来源:发表于2019-01-11 10:34 被阅读82次

    超参数是模型外部的变量,它的值不能根据数据集来估计。超参数的值必须在学习过程开始之前就设置。例如,支持向量机中的 c,k-最近邻中的 k,神经网络中隐藏层的数目。

    相反得是,参数是模型内部的变量,它的值和数据相关。例如,线性/逻辑回归的β系数或支持向量机中的支持向量。

    网格搜索用于寻找模型的最佳超参数,从而得到最“准确”的预测。

    我们通过使用网格搜索构建一个乳腺癌数据集的分类模型。

    1. 导入数据集

    导入数据集并查看前10行。

    # 导入数据
    data = pd.read_csv('breast-cancer-wisconsin.csv',header=None)
    
    # 设置列名
    data.columns = ['Sample Code Number','Clump Thickness','Uniformity of Cell Size',
                                                            'Uniformity of Cell Shape','Marginal Adhesion','Single Epithelial Cell Size',
                                                            'Bare Nuclei','Bland Chromatin','Normal Nucleoli','Mitoses','Class']
    # 查看前10行
    data.head(10)
    

    输出:

    数据集中的每一行都有两个可能的分类之一:良性(用2表示)和恶性(用4表示)。此外,数据集中还有其他10个属性(如上所示)用于预测。

    2. 清理数据

    清理数据并将模型的分类值重命名为0和1(其中1表示恶性情况),并查看分布情况

    data = data.drop(['Sample Code Number'],axis=1) # 去掉第一列
    data = data[data['Bare Nuclei'] != '?'] # 去掉丢失数据的行
    data['Class'] = np.where(data['Class'] ==2,0,1) # 改变分类的表示
    data['Class'].value_counts() # 计算
    

    输出:

    其中良性病例444例,恶性病例239例。

    3. 构建虚拟分类器

    在构建分类模型之前,先构建一个虚拟分类器来确定“基准”性能。这可以回答一个问题: “如果只是简单的预测,该模型的成功率会是多少?” 使用虚拟分类器可以简单地预测多数分类。

    # 将数据分为属性和分类
    X = data.drop(['Class'],axis=1)
    y = data['Class']
    
    # 进行训练和 分割测试集
    from sklearn.model_selection import train_test_split
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
    
    # 虚拟分类器
    from sklearn.dummy import DummyClassifier
    clf = DummyClassifier(strategy= 'most_frequent').fit(X_train,y_train)
    y_pred = clf.predict(X_test)
    
    # y测试集的分布
    print('y actual : \n' +  str(y_test.value_counts()))
    
    # y预测的分布
    print('y predicted : \n' + str(pd.Series(y_pred).value_counts()))
    

    输出:


    从输出可以看出,测试数据集中有68个恶性病例和103个良性病例。但是,我们的分类器将所有情况预测为良性(因为它是多数分类)。

    4. 评估模型的性能

    # 模型评估指标 
    from sklearn.metrics import accuracy_score,recall_score,precision_score,f1_score
    print('Accuracy Score : ' + str(accuracy_score(y_test,y_pred)))
    print('Precision Score : ' + str(precision_score(y_test,y_pred)))
    print('Recall Score : ' + str(recall_score(y_test,y_pred)))
    print('F1 Score : ' + str(f1_score(y_test,y_pred)))
    
    # 虚拟分类器混淆矩阵
    from sklearn.metrics import confusion_matrix
    print('Confusion Matrix : \n' + str(confusion_matrix(y_test,y_pred)))
    

    输出:


    模型的准确度为60.2%,但这种情况下,准确度可能不是评估模型的最佳指标。先看看其他的评估指标。

    上图是混淆矩阵,添加了标签和颜色(代码)。混淆矩阵总结:TRUE POSITIVES(TP)= 0,TRUE NEGATIVES(TN)= 103,FALSE POSITIVES(FP)= 0,FALSE NEGATIVES(FN)= 68.

    评估指标的公式如下:

    由于该模型没有正确地对任何恶性病例进行分类,因此召回率和精确度指标为0。

    5. 用默认参数构建逻辑回归模型

    现在已经有了基准精度,接着用默认参数构建逻辑回归模型并评估。

    # 逻辑回归
    from sklearn.linear_model import LogisticRegression
    
    clf = LogisticRegression().fit(X_train,y_train)
    y_pred = clf.predict(X_test)
    
    # 模型评估指标
    from sklearn.metrics import accuracy_score,recall_score,precision_score,f1_score
    print('Accuracy Score : ' + str(accuracy_score(y_test,y_pred)))
    print('Precision Score : ' + str(precision_score(y_test,y_pred)))
    print('Recall Score : ' + str(recall_score(y_test,y_pred)))
    print('F1 Score : ' + str(f1_score(y_test,y_pred)))
    
    # 逻辑回归分类器混淆矩阵
    from sklearn.metrics import confusion_matrix
    print('Confusion Matrix : \n' + str(confusion_matrix(y_test,y_pred)))
    

    输出:


    通过使用默认参数拟合逻辑回归模型,我们得到了一个“更好”的模型。准确度为94.7%,同时精度达到了惊人的98.3%。现在再次看一下这个模型的混淆矩阵:

    观察错误分类的情况,可以看到有8例恶性病例被错误地归类为良性(假阴性)。此外,只有一个良性病例被归类为恶性病例(假阳性)。

    假阴性更严重,因为疾病被忽视,可能导致患者死亡。同时,误报会导致不必要的治疗,产生额外费用。

    让我们使用网格搜索来找到最佳参数,尽量减少误报。网格搜索可用于改进任何特定的评估指标。

    需要关注的减少漏报的指标是召回率。

    6. 网格搜索最大化召回率

    # 网格搜索
    from sklearn.model_selection import GridSearchCV
    clf = LogisticRegression()
    grid_values = {'penalty': ['l1', 'l2'],'C':[0.001,.009,0.01,.09,1,5,10,25]}
    grid_clf_acc = GridSearchCV(clf, param_grid = grid_values,scoring = 'recall')
    grid_clf_acc.fit(X_train, y_train)
    
    # 新参数预测值
    y_pred_acc = grid_clf_acc.predict(X_test)
    
    # 新模型的评估指标
    print('Accuracy Score : ' + str(accuracy_score(y_test,y_pred_acc)))
    print('Precision Score : ' + str(precision_score(y_test,y_pred_acc)))
    print('Recall Score : ' + str(recall_score(y_test,y_pred_acc)))
    print('F1 Score : ' + str(f1_score(y_test,y_pred_acc)))
    
    # 逻辑回归(网格搜索)混淆矩阵
    confusion_matrix(y_test,y_pred_acc)
    

    输出:


    我们要调整的超参数是:

    1. 罚项:l1l2
    2. C:正则化函数的反函数 - 较小的C值指定较强的正则化。

    此外,在网格搜索函数中,我们有评分参数,可以在其中指定评估模型的指标(我们选择召回作为指标)。在下面的混淆矩阵中,我们可以看到假阴性的数量已经减少,但是这是以增加误报为代价的。网格搜索后的召回率从88.2%升高至91.1%,而精度则从98.3%下降至87.3%。

    您可以使用“f1”得分作为评估指标,进一步调整模型以在精度和召回率之间取得平衡。

    网格搜索为指定的每个超参数组合构建模型,并评估每个模型。用于超参数调整的更有效的技术是随机化搜索,使用超参数的随机组合来找到最佳解决方案。

    相关文章

      网友评论

          本文标题:实战演练网格搜索与模型调参

          本文链接:https://www.haomeiwen.com/subject/muitdqtx.html