Streamlit欺诈预测应用无法显示模型预测结果求助
Streamlit欺诈预测应用提交后无结果且返回主页的问题解决
问题分析
- 按钮与表单作用域错误:你用
if col2.button()包裹了整个表单,Streamlit中按钮状态会在页面刷新(如点击表单提交按钮)时重置为False,导致表单被隐藏,后续if submitted:代码块完全无法执行。 - 代码缩进混乱:Python对缩进要求严格,原代码中表单控件、
if submitted:代码块的缩进不符合语法规范,会引发逻辑执行异常。 - 分类变量未编码:表单获取的
Sí/No等字符串类型数据直接传入Scaler,而Scaler仅支持数值型数据,即便解决前面的作用域问题,这一步也会报错。
修复步骤与代码
核心修复点
- 用
st.session_state保存表单显示状态,避免页面刷新后表单消失 - 修正所有代码缩进,保证语法正确
- 将表单字符串选项转换为模型训练时对应的数值格式
修复后的完整代码:
import streamlit as st import pandas as pd import pickle # 初始化会话状态,控制表单显示 if "show_form" not in st.session_state: st.session_state.show_form = False col1, col2 = st.columns(2) if col2.button('Entrada manual de datos'): st.session_state.show_form = not st.session_state.show_form # 根据会话状态显示表单 if st.session_state.show_form: with st.form('Entrada manual de datos'): # Selección del día de la transacción day = st.slider('Día de la transacción', 1, 31) # Caja de entrada para números hour = st.slider('Hora de la transacción', 1, 24) # Caja de entrada para cantidad amount = st.number_input('Cantidad de la transacción', min_value=1) # Caja de entrada para retirada de fondos type_CASH_OUT = st.radio("¿Es una retirada de fondos?", ('Sí', 'No')) # Caja de entrada para transferencias type_TRANSFER = st.radio("¿Es una transferencia?", ('Sí', 'No')) # Caja de entrada para quien inicia la transacción nameorig_C = st.radio("¿Quién origina la transacción?", ('Cliente', 'Comercio')) # Caja de entrada para beneficiario namedest_C = st.radio("¿El beneficiario de la transacción es otro cliente?", ('Sí', 'No')) # Caja de entrada para beneficiario namedest_M = st.radio("¿El beneficiario de la transacción es un comercio?", ('Sí', 'No')) submitted = st.form_submit_button("Submit") if submitted: # 将分类变量转换为数值,匹配模型训练格式 def str_to_num(val): return 1 if val == 'Sí' or val == 'Cliente' else 0 X_test = pd.DataFrame({ 'day': [day], 'hour': [hour], 'amount': [amount], 'type_CASH_OUT': [str_to_num(type_CASH_OUT)], 'type_TRANSFER': [str_to_num(type_TRANSFER)], 'nameorig_C': [str_to_num(nameorig_C)], 'namedest_C': [str_to_num(namedest_C)], 'namedest_M': [str_to_num(namedest_M)] }) st.write("Datos de prueba:") st.write(X_test) # 加载Scaler并处理数据 ruta_scaler = 'C:/Users/lydia/OneDrive/Escritorio/Proyecto final_fraude/src/modelos/scaler.pkl' scaler = pickle.load(open(ruta_scaler, 'rb')) scaled_X_test = scaler.transform(X_test) # 加载PCA并降维 ruta_pca = 'C:/Users/lydia/OneDrive/Escritorio/Proyecto final_fraude/src/modelos/pca.pkl' pca = pickle.load(open(ruta_pca, 'rb')) X_test_pca = pd.DataFrame(pca.transform(scaled_X_test), columns=['PC1', 'PC2', 'PC3', 'PC4', 'PC5']) st.write("Datos transformados (X_test_pca):") st.write(X_test_pca) # 加载模型并预测 my_model = pickle.load(open('C:/Users/lydia/OneDrive/Escritorio/Proyecto final_fraude/src/modelos/my_model.pkl', 'rb')) y_pred = my_model.predict(X_test_pca) st.write("Predicción (y_pred):") st.write(y_pred) # 显示预测结果 prediction_label = "Es una transacción fraudulenta" if y_pred[0] == 1 else "Es una transacción segura" st.write("Resultado de la predicción:", prediction_label)
关键说明
st.session_state会在页面刷新时保留状态,确保点击提交按钮后表单不会隐藏,if submitted:代码块能正常执行str_to_num函数将表单字符串转换为数值,避免Scaler和模型因数据类型不匹配报错- 修正后的缩进保证了Python代码的语法正确性
内容的提问来源于stack exchange,提问作者Lidia
相关产品推荐
相关产品推荐

