You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Streamlit欺诈预测应用无法显示模型预测结果求助

Streamlit欺诈预测应用提交后无结果且返回主页的问题解决

问题分析

  1. 按钮与表单作用域错误:你用if col2.button()包裹了整个表单,Streamlit中按钮状态会在页面刷新(如点击表单提交按钮)时重置为False,导致表单被隐藏,后续if submitted:代码块完全无法执行。
  2. 代码缩进混乱:Python对缩进要求严格,原代码中表单控件、if submitted:代码块的缩进不符合语法规范,会引发逻辑执行异常。
  3. 分类变量未编码:表单获取的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 16:43:21