如何从Dash下拉菜单中选择和运行模型并更新混淆矩阵图?

我正在基于这个乳腺癌数据集构建一个机器学习预测的Dash应用。

我想通过下拉菜单选择我的一个模型,运行拟合,并返回一个更新后的混淆矩阵(热图)。

我计划扩展脚本以包括表格、ROC曲线、学习曲线等(即,多输出回调),但首先我想让这部分工作,然后再实现其他元素。

我尝试了不同的东西。

例如,在当前代码(如下)之前,我尝试直接从下拉菜单调用模型,然后在回调中进行所有混淆矩阵计算,结果出现了AttributeError: ‘str’ object has no attribute ‘fit’的错误:

@app.callback(Output('conf_matrix', 'figure'), [Input('dropdown-5', 'value')])def update_cm_matix(model):    class_names=[0,1]    fitModel = model.fit(X_train, y_train)    y_pred = fitModel.predict(X_test)    cm = confusion_matrix(y_test, y_pred)    return {'data': [go.Heatmap(x=class_names, y=class_names, z=cm, showscale=True, colorscale='blues')],            'layout': dict(width=350, height=280, margin={'t': 10},                       xaxis=dict(title='预测类别', tickvals=[0, 1]),                       yaxis=dict(title='真实类别', tickvals=[0, 1], autorange='reversed'))}

(替换脚本中的app.callback和函数)。

我目前正在努力解决的版本是:

# -*- coding: utf-8 -*-import dashimport dash_core_components as dccimport dash_html_components as htmlimport dash_bootstrap_components as dbcimport pandas as pdimport numpy as npfrom sklearn.preprocessing import StandardScalerfrom sklearn.linear_model import LogisticRegressionfrom sklearn.model_selection import GridSearchCV, train_test_splitfrom sklearn.metrics import confusion_matrixfrom sklearn.feature_selection import RFEimport plotly.graph_objs as gofrom dash.dependencies import Input, Outputapp = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])server = app.serverapp.config.suppress_callback_exceptions = Truedf = pd.read_csv("breast_cancer.csv")y = np.array(df.diagnosis.tolist())data = df.drop('diagnosis', 1)X = np.array(data.values)scaler = StandardScaler()X = scaler.fit_transform(X)random_state = 42X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=random_state)# 第一种模型:逻辑模型 + 优化超参数log = LogisticRegression(random_state=random_state)param_grid = {'penalty': ['l2', 'l1'], 'C': [0.001, 0.01, 0.1, 1, 10, 100, 1000]}CV_log = GridSearchCV(estimator=log, param_grid,, scoring='accuracy', verbose=1, n_jobs=-1)CV_log.fit(X_train, y_train)log_best_params = CV_log.best_params_log_clf = LogisticRegression(C=log_best_params['C'], penalty=log_best_params['penalty'], random_state=random_state)# 第二种模型:带递归特征消除的逻辑模型(仅为示例,其他模型将被包含)rfe_selector = RFE(log_clf)# 应用布局app.layout = html.Div([    html.Div([        dcc.Dropdown(            id='dropdown-5',            options=[{'label': '逻辑回归', 'value': 'log_clf'},                     {'label': 'RFE', 'value': 'rfe_selector'}],            value='log_clf',            style={'width': '150px', 'height': '35px', 'fontSize': '10pt'}        )], style={}),    html.Div([        dcc.Graph(id='conf_matrix')    ])])# 运行选定模型的函数def ClassTrainEval(model):    fitModel = model.fit(X_train, y_train)    y_pred = fitModel.predict(X_test)    cm = confusion_matrix(y_test, y_pred)    return fitModel, y_pred, y_score, cmmodels = [log_clf, rfe_selector]class_names = [0,1]# dash回调@app.callback(Output('conf_matrix', 'figure'), [Input('dropdown-5', 'value')])def update_cm_matix(model):    for model in models:        ClassTrainEval(model)    return {'data': [go.Heatmap(x=class_names, y=class_names, z=cm, showscale=True, colorscale='blues')],            'layout': dict(width=350, height=280, margin={'t': 10},                           xaxis=dict(title='预测类别', tickvals=[0, 1]),                           yaxis=dict(title='真实类别', tickvals=[0, 1], autorange='reversed'))}if __name__ == '__main__':    app.run_server(debug=True)

在这里我得到了一个NameError: name ‘cm’ is not defined的错误。

我真的不确定如何继续推进以使其工作 – 所以我希望有人能指导我正确的方向。

谢谢!


回答:

你的代码中有多个错误。让我们先解决你的两次尝试。

dcc.Dropdown(        id='dropdown-5',        options=[{'label': '逻辑回归', 'value': 'log_clf'},                 {'label': 'RFE', 'value': 'rfe_selector'}],        value='log_clf',        style={'width': '150px', 'height': '35px', 'fontSize': '10pt'}    )], style={})

在你的下拉菜单中,模型是一个字符串(type('log_clf') == str),所以你不能训练它。你需要按以下方式编写回调:

models = {'逻辑回归':log_clf, 'RFE':rfe_selector}""""我跳过了代码的一些行"""dcc.Dropdown(        id='dropdown-5',        options=[{'label': v, 'value': v} for v in ['逻辑回归','RFE']],        value='逻辑回归',        style={'width': '150px', 'height': '35px', 'fontSize': '10pt'}    )

对于第二次尝试,你还需要一行来适应我所做的更改:

错误是:NameError: name 'cm' is not defined error(我假设它发生在回调中),这是因为你没有将函数的输出分配给变量:

函数是

# 运行选定模型的函数def ClassTrainEval(model):    fitModel = model.fit(X_train, y_train)    y_pred = fitModel.predict(X_test)    cm = confusion_matrix(y_test, y_pred)    return fitModel, y_pred, y_score, cm #注意,y_score从未定义,所以你需要删除它

然后在回调中你有:

# dash回调@app.callback(Output('conf_matrix', 'figure'), [Input('dropdown-5', 'value')])def update_cm_matix(model):    for model in models: #<-------不需要循环        ClassTrainEval(model) #<-------这里你需要分配输出    return {'data': [go.Heatmap(x=class_names, y=class_names, z=cm, showscale=True, colorscale='blues')],            'layout': dict(width=350, height=280, margin={'t': 10},                           xaxis=dict(title='预测类别', tickvals=[0, 1]),                           yaxis=dict(title='真实类别', tickvals=[0, 1], autorange='reversed'))}

你可能想要写:

@app.callback(Output('conf_matrix', 'figure'), [Input('dropdown-5', 'value')])def update_cm_matix(v):    model = models[v]    fitModel, y_pred, cm =  ClassTrainEval(model)    return {'data': [go.Heatmap(x=class_names, y=class_names, z=cm, showscale=True, colorscale='blues')],            'layout': dict(width=350, height=280, margin={'t': 10},                           xaxis=dict(title='预测类别', tickvals=[0, 1]),                           yaxis=dict(title='真实类别', tickvals=[0, 1], autorange='reversed'))}

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注