import streamlit as st import plotly.express as px import plotly.graph_objects as go import pandas as pd import numpy as np import joblib import os from datetime import datetime from sklearn.preprocessing import MinMaxScaler # 页面函数定义 def show_optimized_parameter_adjustment(): # 页面标题 st.title("优化版挤出机参数调节建议") # 添加操作指引 with st.expander("📖 操作指引", expanded=True): st.markdown(""" 欢迎使用优化版挤出机参数调节建议功能!本功能基于多目标优化算法,根据您输入的米重数据和当前参数,为您提供科学合理的参数调整建议。 **操作步骤:** 1. 选择一个已训练好的模型 2. 输入米重标准值、上下限和当前挤出机参数 3. 输入当前实际米重测量值 4. 调整优化参数(可选) 5. 点击"计算优化调节建议"按钮 6. 查看系统生成的参数调整建议 **注意事项:** - 请确保输入的参数值在设备允许的范围内 - 优化算法会平衡米重偏差和调整幅度 - 历史调节记录可在页面底部查看 """) # 初始化会话状态 if 'optimized_adjustment_history' not in st.session_state: st.session_state['optimized_adjustment_history'] = [] # 1. 模型选择区域 with st.expander("🔍 模型选择", expanded=True): # 创建模型目录(如果不存在) model_dir = "saved_models" os.makedirs(model_dir, exist_ok=True) # 获取所有已保存的模型文件 model_files = [f for f in os.listdir(model_dir) if f.endswith('.joblib')] model_files.sort(reverse=True) # 最新的模型排在前面 if not model_files: st.warning("尚未保存任何模型,请先训练模型并保存。") return # 模型选择下拉框 selected_model_file = st.selectbox( "选择已保存的模型", options=model_files, help="选择要用于预测的模型文件" ) # 加载并显示模型信息 if selected_model_file: model_path = os.path.join(model_dir, selected_model_file) model_info = joblib.load(model_path) # 显示模型基本信息 st.subheader("📊 模型信息") info_cols = st.columns(2) with info_cols[0]: st.metric("模型类型", model_info['model_type']) st.metric("创建时间", model_info['created_at'].strftime('%Y-%m-%d %H:%M:%S')) st.metric("使用稳态数据", "是" if model_info.get('use_steady_data', False) else "否") with info_cols[1]: st.metric("R² 得分", f"{model_info['r2_score']:.4f}") st.metric("均方误差 (MSE)", f"{model_info['mse']:.6f}") st.metric("均方根误差 (RMSE)", f"{model_info['rmse']:.6f}") # 显示模型特征 st.write("🔑 模型使用的特征:") st.code(", ".join(model_info['features'])) # 如果是深度学习模型,显示序列长度 if 'sequence_length' in model_info: st.metric("序列长度", model_info['sequence_length']) # 保存模型信息到会话状态 st.session_state['selected_model'] = model_info st.session_state['selected_model_file'] = selected_model_file # 2. 参数输入区域 st.subheader("📝 参数输入") # 2.1 米重标准值、上下限输入 with st.expander("⚖️ 米重标准与上下限", expanded=True): weight_cols = st.columns(3) with weight_cols[0]: standard_weight = st.number_input( "标准米重", key="standard_weight", value=5.20, min_value=0.01, max_value=10.0, step=0.0001, format="%.4f", help="输入目标米重标准值" ) st.caption("单位: Kg/m") with weight_cols[1]: upper_limit = st.number_input( "米重上限", key="upper_limit", value=5.46, min_value=standard_weight, max_value=10.0, step=0.0001, format="%.4f", help="输入米重允许的上限值" ) st.caption("单位: Kg/m") with weight_cols[2]: lower_limit = st.number_input( "米重下限", key="lower_limit", value=5.02, min_value=0.01, max_value=standard_weight, step=0.0001, format="%.4f", help="输入米重允许的下限值" ) st.caption("单位: Kg/m") # 2.2 挤出机当前参数输入 with st.expander("🔧 挤出机当前参数", expanded=True): param_cols = st.columns(3) with param_cols[0]: current_screw_speed = st.number_input( "螺杆转速", key="current_screw_speed", value=230.0, min_value=0.0, max_value=500.0, step=0.1, help="输入当前螺杆转速" ) st.caption("单位: rpm") current_head_pressure = st.number_input( "机头压力", key="current_head_pressure", value=0.26, min_value=0.0, max_value=500.0, format="%.4f", step=1.0, help="输入当前机头压力" ) st.caption("单位: bar") current_process_speed = st.number_input( "流程主速", key="current_process_speed", value=6.6, min_value=0.0, max_value=300.0, step=0.1, help="输入当前流程主速" ) st.caption("单位: m/min") with param_cols[1]: current_screw_temperature = st.number_input( "螺杆温度", key="current_screw_temperature", value=79.9, min_value=0.0, max_value=300.0, step=1.0, help="输入当前螺杆温度" ) st.caption("单位: °C") current_rear_barrel_temperature = st.number_input( "后机筒温度", key="current_rear_barrel_temperature", value=79.9, min_value=0.0, max_value=300.0, step=1.0, help="输入当前后机筒温度" ) st.caption("单位: °C") with param_cols[2]: current_front_barrel_temperature = st.number_input( "前机筒温度", key="current_front_barrel_temperature", value=80.1, min_value=0.0, max_value=300.0, step=1.0, help="输入当前前机筒温度" ) st.caption("单位: °C") current_head_temperature = st.number_input( "机头温度", key="current_head_temperature", value=95.1, min_value=0.0, max_value=300.0, step=1.0, help="输入当前机头温度" ) st.caption("单位: °C") # 2.3 当前实际米重测量值输入 with st.expander("📏 当前实际米重", expanded=True): actual_weight = st.number_input( "当前实际米重", key="actual_weight", value=5.115, min_value=0.01, max_value=10.0, step=0.0001, format="%.4f", help="输入当前实际测量的米重值" ) st.caption("单位: Kg/m") # 3. 优化参数设置 st.subheader("⚙️ 优化参数设置") with st.expander("🎯 多目标优化参数", expanded=True): # 目标权重设置 st.write("### 目标权重") st.markdown("调整以下权重来平衡米重偏差和调整幅度的重要性:") weight_cols = st.columns(2) with weight_cols[0]: weight_deviation = st.slider( "米重偏差权重", min_value=0.1, max_value=1.0, value=0.8, step=0.1, help="权重越高,越优先考虑减少米重偏差" ) with weight_cols[1]: weight_adjustment = st.slider( "调整幅度权重", min_value=0.1, max_value=1.0, value=0.2, step=0.1, help="权重越高,越优先考虑减少调整幅度" ) # 调整权重,确保总和为1 total_weight = weight_deviation + weight_adjustment weight_deviation = weight_deviation / total_weight weight_adjustment = weight_adjustment / total_weight st.write(f"### 调整后权重(总和为1)") st.write(f"- 米重偏差权重: {weight_deviation:.2f}") st.write(f"- 调整幅度权重: {weight_adjustment:.2f}") # 参数调整约束 st.write("### 参数调整约束") constraint_cols = st.columns(2) with constraint_cols[0]: max_screw_speed_adjust = st.slider( "螺杆转速最大调整幅度(%)", min_value=5.0, max_value=20.0, value=15.0, step=1.0, help="单次调整的最大百分比" ) with constraint_cols[1]: max_process_speed_adjust = st.slider( "流程主速最大调整幅度(%)", min_value=3.0, max_value=15.0, value=10.0, step=1.0, help="单次调整的最大百分比" ) # 4. 计算优化调节建议 st.subheader("🚀 计算优化调节建议") if st.button("📊 计算优化调节建议", key="calculate_optimized_adjustment"): # 参数验证 validation_errors = [] if standard_weight <= 0: validation_errors.append("标准米重必须大于0") if upper_limit <= standard_weight: validation_errors.append("米重上限必须大于标准米重") if lower_limit >= standard_weight: validation_errors.append("米重下限必须小于标准米重") if current_screw_speed <= 0: validation_errors.append("螺杆转速必须大于0") if current_process_speed <= 0: validation_errors.append("流程主速必须大于0") if actual_weight <= 0: validation_errors.append("实际米重必须大于0") if validation_errors: st.error("参数输入错误:") for error in validation_errors: st.error(f"- {error}") else: with st.spinner("正在计算优化调节建议..."): # 获取选中的模型 if 'selected_model' not in st.session_state: st.error("请先选择一个模型") return model_info = st.session_state['selected_model'] model = model_info['model'] # 检查是否有缩放器 has_scalers = ('scaler_X' in model_info and model_info['scaler_X'] is not None and 'scaler_y' in model_info and model_info['scaler_y'] is not None) if has_scalers: scaler_X = model_info['scaler_X'] scaler_y = model_info['scaler_y'] features = model_info['features'] # 多目标优化算法 - 粒子群优化 def predict_weight(screw_speed, process_speed): """使用模型预测米重""" # 准备输入数据 input_data = { '螺杆转速': screw_speed, '机头压力': current_head_pressure, '流程主速': process_speed, '螺杆温度': current_screw_temperature, '后机筒温度': current_rear_barrel_temperature, '前机筒温度': current_front_barrel_temperature, '机头温度': current_head_temperature } # 根据模型特征创建输入DataFrame input_df = pd.DataFrame([input_data])[features] if model_info['model_type'] in ['LSTM', 'GRU', 'BiLSTM']: # 深度学习模型处理逻辑 import torch # 检查是否有缩放器 if has_scalers: scaled_input = scaler_X.transform(input_df) else: scaled_input = input_df.values # 获取序列长度 sequence_length = model_info.get('sequence_length', 10) # 创建序列数据 input_seq = np.tile(scaled_input, (sequence_length, 1)).reshape(1, sequence_length, -1) # 转换为PyTorch张量 device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') input_tensor = torch.tensor(input_seq, dtype=torch.float32).to(device) # 预测 model.eval() with torch.no_grad(): y_pred_scaled_tensor = model(input_tensor) y_pred_scaled = y_pred_scaled_tensor.cpu().numpy().ravel()[0] if has_scalers: # 反缩放预测结果 predicted_weight = scaler_y.inverse_transform(np.array([[y_pred_scaled]]))[0][0] else: predicted_weight = y_pred_scaled elif has_scalers: # 特征缩放 scaled_input = scaler_X.transform(input_df) # 模型预测 scaled_prediction = model.predict(scaled_input)[0] # 反缩放预测结果 predicted_weight = scaler_y.inverse_transform(np.array([[scaled_prediction]]))[0][0] else: # 直接预测,不使用缩放器 predicted_weight = model.predict(input_df)[0] return predicted_weight def objective_function(params): """多目标目标函数""" screw_speed_val, process_speed_val = params # 预测米重 predicted_weight_val = predict_weight(screw_speed_val, process_speed_val) # 计算目标1:米重偏差 deviation_val = abs(predicted_weight_val - standard_weight) deviation_percent_val = abs((predicted_weight_val - standard_weight) / standard_weight * 100) # 计算目标2:调整幅度 screw_speed_adjustment_val = abs(screw_speed_val - current_screw_speed) process_speed_adjustment_val = abs(process_speed_val - current_process_speed) screw_speed_adjustment_percent_val = abs((screw_speed_val - current_screw_speed) / current_screw_speed * 100) process_speed_adjustment_percent_val = abs((process_speed_val - current_process_speed) / current_process_speed * 100) # 加权目标函数 objective_val = (weight_deviation * deviation_percent_val + weight_adjustment * (screw_speed_adjustment_percent_val + process_speed_adjustment_percent_val) / 2) return objective_val, predicted_weight_val, deviation_percent_val, \ screw_speed_adjustment_percent_val, process_speed_adjustment_percent_val # 参数约束 def is_within_constraints(params): """检查参数是否在约束范围内""" screw_speed, process_speed = params # 螺杆转速约束 if not (30 <= screw_speed <= 500): return False # 流程主速约束 if not (0 <= process_speed <= 200): return False # 单次调整幅度约束 screw_speed_adjustment_percent = abs((screw_speed - current_screw_speed) / current_screw_speed * 100) if screw_speed_adjustment_percent > max_screw_speed_adjust: return False process_speed_adjustment_percent = abs((process_speed - current_process_speed) / current_process_speed * 100) if process_speed_adjustment_percent > max_process_speed_adjust: return False return True # 粒子群优化算法 def particle_swarm_optimization(objective, constraints, bounds, n_particles=30, n_iterations=50): """粒子群优化算法""" # 初始化粒子 particles = [] velocities = [] best_positions = [] best_scores = [] # 边界 (screw_speed_min, screw_speed_max), (process_speed_min, process_speed_max) = bounds for _ in range(n_particles): # 随机初始化位置 while True: screw_speed = np.random.uniform(screw_speed_min, screw_speed_max) process_speed = np.random.uniform(process_speed_min, process_speed_max) pos = [screw_speed, process_speed] if constraints(pos): break particles.append(pos) velocities.append([0.0, 0.0]) best_positions.append(pos.copy()) # 计算初始得分 score, _, _, _, _ = objective(pos) best_scores.append(score) # 全局最优 global_best_idx = np.argmin(best_scores) global_best_position = best_positions[global_best_idx].copy() global_best_score = best_scores[global_best_idx] # PSO参数 w = 0.5 # 惯性权重 c1 = 1.5 # 认知系数 c2 = 1.5 # 社会系数 # 迭代优化 for _ in range(n_iterations): for i in range(n_particles): # 更新速度 r1, r2 = np.random.rand(), np.random.rand() velocities[i][0] = (w * velocities[i][0] + c1 * r1 * (best_positions[i][0] - particles[i][0]) + c2 * r2 * (global_best_position[0] - particles[i][0])) velocities[i][1] = (w * velocities[i][1] + c1 * r1 * (best_positions[i][1] - particles[i][1]) + c2 * r2 * (global_best_position[1] - particles[i][1])) # 更新位置 new_pos = [ particles[i][0] + velocities[i][0], particles[i][1] + velocities[i][1] ] # 检查约束 if constraints(new_pos): particles[i] = new_pos # 更新个体最优 current_score, _, _, _, _ = objective(new_pos) if current_score < best_scores[i]: best_scores[i] = current_score best_positions[i] = new_pos.copy() # 更新全局最优 if current_score < global_best_score: global_best_score = current_score global_best_position = new_pos.copy() return global_best_position, global_best_score # 设置参数边界 screw_speed_bounds = [ current_screw_speed * (1 - max_screw_speed_adjust / 100), current_screw_speed * (1 + max_screw_speed_adjust / 100) ] process_speed_bounds = [ current_process_speed * (1 - max_process_speed_adjust / 100), current_process_speed * (1 + max_process_speed_adjust / 100) ] # 执行优化 best_params, best_score = particle_swarm_optimization( objective_function, is_within_constraints, [(screw_speed_bounds[0], screw_speed_bounds[1]), (process_speed_bounds[0], process_speed_bounds[1])] ) # 获取最优参数的详细信息 best_screw_speed, best_process_speed = best_params best_objective, best_predicted_weight, best_deviation_percent, \ best_screw_adjust_percent, best_process_adjust_percent = objective_function(best_params) # 计算当前参数的预测结果 current_predicted_weight = predict_weight(current_screw_speed, current_process_speed) current_deviation_percent = abs((current_predicted_weight - standard_weight) / standard_weight * 100) # 生成调整建议文本 def generate_recommendation(): """生成调整建议文本""" screw_speed_change = "提高" if best_screw_speed > current_screw_speed else "降低" process_speed_change = "提高" if best_process_speed > current_process_speed else "降低" recommendation = f"米重偏差 {current_deviation_percent:.2f}%,建议调整:\n" recommendation += f"1. 将螺杆转速从 {current_screw_speed:.1f} rpm {screw_speed_change} 至 {best_screw_speed:.1f} rpm " recommendation += f"( {screw_speed_change} {abs(best_screw_adjust_percent):.2f}% )\n" recommendation += f"2. 将流程主速从 {current_process_speed:.1f} m/min {process_speed_change} 至 {best_process_speed:.1f} m/min " recommendation += f"( {process_speed_change} {abs(best_process_adjust_percent):.2f}% )\n" recommendation += f"\n预期效果:米重偏差将降至 {best_deviation_percent:.2f}%" return recommendation recommendation = generate_recommendation() # 构建调整结果 adjustment_result = { 'status': '正常范围' if best_predicted_weight >= lower_limit and best_predicted_weight <= upper_limit else \ '超上限' if best_predicted_weight > upper_limit else '超下限', 'real_time_weight': actual_weight, 'standard_weight': standard_weight, 'upper_limit': upper_limit, 'lower_limit': lower_limit, 'current_screw_speed': current_screw_speed, 'current_process_speed': current_process_speed, 'new_screw_speed': best_screw_speed, 'new_process_speed': best_process_speed, 'predicted_weight': best_predicted_weight, 'current_predicted_weight': current_predicted_weight, 'deviation_percentage': (actual_weight - standard_weight) / standard_weight * 100, 'current_predicted_deviation_percent': current_deviation_percent, 'predicted_deviation_percent': best_deviation_percent, 'screw_speed_adjustment': best_screw_speed - current_screw_speed, 'process_speed_adjustment': best_process_speed - current_process_speed, 'screw_speed_adjust_percent': best_screw_adjust_percent, 'process_speed_adjust_percent': best_process_adjust_percent, 'recommendation': recommendation, 'weight_deviation': weight_deviation, 'weight_adjustment': weight_adjustment, 'best_objective_score': best_score } # 保存到历史记录 history_record = { 'timestamp': datetime.now(), 'model_file': st.session_state.get('selected_model_file', '未知模型'), 'standard_weight': standard_weight, 'upper_limit': upper_limit, 'lower_limit': lower_limit, 'actual_weight': actual_weight, 'current_screw_speed': current_screw_speed, 'current_process_speed': current_process_speed, 'adjustment_result': adjustment_result } # 添加到会话状态的历史记录 st.session_state['optimized_adjustment_history'].append(history_record) # 限制历史记录数量 if len(st.session_state['optimized_adjustment_history']) > 100: st.session_state['optimized_adjustment_history'] = st.session_state['optimized_adjustment_history'][-100:] # 5. 结果展示 st.success("优化调节建议计算完成!") st.subheader("📋 优化调节建议结果") # 5.1 米重状态 if adjustment_result['status'] == "正常范围": st.success(f"米重状态: {adjustment_result['status']}") else: st.warning(f"米重状态: {adjustment_result['status']}") # 5.2 偏差信息 st.markdown("### 📊 偏差信息") info_cols = st.columns(3) info_cols[0].metric("实时米重", f"{adjustment_result['real_time_weight']:.4f} Kg/m") info_cols[1].metric("标准米重", f"{adjustment_result['standard_weight']:.4f} Kg/m") info_cols[2].metric("偏差百分比", f"{adjustment_result['deviation_percentage']:.2f}%") # 5.3 预测结果对比 st.markdown("### 📈 预测结果对比") pred_cols = st.columns(3) pred_cols[0].metric("当前参数预测米重", f"{adjustment_result['current_predicted_weight']:.4f} Kg/m") pred_cols[1].metric("优化后预测米重", f"{adjustment_result['predicted_weight']:.4f} Kg/m") pred_cols[2].metric("预测偏差改善", f"{adjustment_result['current_predicted_deviation_percent'] - adjustment_result['predicted_deviation_percent']:.2f}%") # 5.4 关键调整建议 st.markdown("### 🔑 关键调整建议") st.info(adjustment_result['recommendation']) # 5.5 参数调整对比 st.markdown("### 📊 参数调整对比") param_compare_df = pd.DataFrame({ '参数名称': ['螺杆转速', '流程主速'], '当前值': [adjustment_result['current_screw_speed'], adjustment_result['current_process_speed']], '优化建议值': [adjustment_result['new_screw_speed'], adjustment_result['new_process_speed']], '调整幅度': [f"{adjustment_result['screw_speed_adjust_percent']:.2f}%", f"{adjustment_result['process_speed_adjust_percent']:.2f}%"] }) # 高亮显示调整幅度 def highlight_adjustment(val): if isinstance(val, str) and '%' in val: try: percent = float(val.strip('%')) if percent > 0: return 'background-color: #90EE90' # 绿色表示增加 elif percent < 0: return 'background-color: #FFB6C1' # 红色表示减少 except: pass return '' styled_df = param_compare_df.style.applymap(highlight_adjustment, subset=['调整幅度']) st.dataframe(styled_df, use_container_width=True, hide_index=True) # 5.6 可视化对比 fig = go.Figure() fig.add_trace(go.Bar( x=param_compare_df['参数名称'], y=param_compare_df['当前值'], name='当前值', marker_color='blue' )) fig.add_trace(go.Bar( x=param_compare_df['参数名称'], y=param_compare_df['优化建议值'], name='优化建议值', marker_color='green' )) fig.update_layout( barmode='group', title='参数调整对比', yaxis_title='数值', height=400 ) st.plotly_chart(fig, use_container_width=True) # 5.7 优化效果可视化 st.markdown("### 📉 优化效果") # 目标函数值对比 fig_objective = go.Figure() fig_objective.add_trace(go.Bar( x=['当前参数', '优化后参数'], y=[ weight_deviation * current_deviation_percent + weight_adjustment * 0, weight_deviation * best_deviation_percent + weight_adjustment * \ (abs(best_screw_adjust_percent) + abs(best_process_adjust_percent)) / 2 ], marker_color=['red', 'green'] )) fig_objective.update_layout( title='多目标优化函数值对比', yaxis_title='目标函数值(越小越好)', height=300 ) st.plotly_chart(fig_objective, use_container_width=True) # 6. 历史记录展示 st.subheader("📚 历史调节记录") if 'optimized_adjustment_history' in st.session_state and st.session_state['optimized_adjustment_history']: # 显示历史记录数量 st.write(f"共 {len(st.session_state['optimized_adjustment_history'])} 条历史记录") # 分页显示 page_size = 10 total_pages = (len(st.session_state['optimized_adjustment_history']) + page_size - 1) // page_size page = st.selectbox( "选择页码", options=range(1, total_pages + 1), key="history_page" ) start_idx = (page - 1) * page_size end_idx = start_idx + page_size paginated_history = st.session_state['optimized_adjustment_history'][start_idx:end_idx] # 反向显示,最新记录在前面 for record in reversed(paginated_history): with st.expander(f"记录时间: {record['timestamp'].strftime('%Y-%m-%d %H:%M:%S')} | 模型: {record['model_file']}"): history_cols = st.columns(3) with history_cols[0]: st.write("**米重参数**") st.write(f"- 标准米重: {record['standard_weight']:.4f} Kg/m") st.write(f"- 米重上限: {record['upper_limit']:.4f} Kg/m") st.write(f"- 米重下限: {record['lower_limit']:.4f} Kg/m") st.write(f"- 实际米重: {record['actual_weight']:.4f} Kg/m") with history_cols[1]: st.write("**速度参数**") st.write(f"- 当前螺杆转速: {record['current_screw_speed']:.1f} rpm") st.write(f"- 当前流程主速: {record['current_process_speed']:.1f} m/min") st.write(f"- 建议螺杆转速: {record['adjustment_result']['new_screw_speed']:.1f} rpm") st.write(f"- 建议流程主速: {record['adjustment_result']['new_process_speed']:.1f} m/min") with history_cols[2]: st.write("**预测结果**") st.write(f"- 当前预测米重: {record['adjustment_result']['current_predicted_weight']:.4f} Kg/m") st.write(f"- 优化后预测米重: {record['adjustment_result']['predicted_weight']:.4f} Kg/m") st.write(f"- 当前预测偏差: {record['adjustment_result']['current_predicted_deviation_percent']:.2f}%") st.write(f"- 优化后预测偏差: {record['adjustment_result']['predicted_deviation_percent']:.2f}%") st.write("**调整建议**") st.write(record['adjustment_result']['recommendation']) else: st.info("暂无历史调节记录") # 7. 帮助说明 with st.expander("❓ 帮助说明"): st.markdown(""" ### 功能说明 本功能模块基于多目标优化算法,根据当前米重测量值和挤出机参数,为用户提供科学合理的参数调整建议。 ### 优化算法 - **算法类型**: 粒子群优化算法(PSO) - **优化目标**: 1. 最小化米重偏差 2. 最小化参数调整幅度 - **约束条件**: - 螺杆转速和流程主速上下限 - 单次最大调整幅度 ### 结果解读 - **米重状态**: 显示优化后预测米重是否在允许范围内 - **偏差信息**: 当前米重与标准米重的偏差 - **预测结果对比**: 当前参数和优化后参数的预测米重对比 - **调整建议**: 详细的参数调整建议 - **参数对比**: 直观展示参数调整幅度 - **优化效果**: 多目标优化函数值对比 ### 注意事项 1. 请确保输入的参数值准确反映设备当前状态 2. 优化建议仅供参考,实际操作时请结合现场经验 3. 建议在调整参数后密切观察米重变化 4. 定期更新模型以提高建议的准确性 """) # 页面入口 if __name__ == "__main__": show_optimized_parameter_adjustment()