Ver código fonte

加入模型

Administrator 1 mês atrás
pai
commit
1f9e0d75fe
3 arquivos alterados com 237 adições e 0 exclusões
  1. 72 0
      train_corrector.py
  2. 112 0
      参考.py
  3. 53 0
      模型调用.py

+ 72 - 0
train_corrector.py

@@ -0,0 +1,72 @@
+import pandas as pd
+import joblib
+from sklearn.ensemble import RandomForestRegressor
+from sklearn.model_selection import train_test_split
+
+# === 步骤1:读取CSV并预处理 ===
+csv_path = 'C:\\Users\\Administrator\\Desktop\\defrost\\feedback_data.csv'
+df = pd.read_csv(csv_path, parse_dates=["t_formula", "t_real"], encoding='gbk')
+
+# 确保类型一致
+df["material_name"] = df["material_name"].astype(str)
+df["manufactured_goods"] = df["manufactured_goods"].astype(str)
+
+# 计算真实解冻时长(单位:小时)
+df["t_real_hours"] = (df["t_real"] - df["t_formula"]).dt.total_seconds() / 3600
+
+# 特征列(不包括物料名称和产品名称)
+feature_columns = [
+    "w", "rho_coal", "rho_ice", "C_coal", "C_ice", "L", "k_coal", "k_ice", "h",
+    "T_air", "T_initial", "T_m", "a", "b", "c"
+]
+
+# 模型输入和标签
+X = df[feature_columns].copy()
+y = df["t_real_hours"]
+
+# === 步骤2:训练模型 ===
+X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
+model = RandomForestRegressor(n_estimators=100, random_state=42)
+model.fit(X_train, y_train)
+
+# === 步骤3:保存模型 ===
+joblib.dump(model, "defrost_time_corrector.pkl")
+print("模型训练完成并已保存为 defrost_time_corrector.pkl")
+
+# === 步骤4:测试一个新样本并判断是否为相同样本类型 ===
+new_sample_info = {
+    "material_name": "国产动力煤",
+    "manufactured_goods": "龙家堡洗混煤-5206",
+    "w": 12,
+    "rho_coal": 3000,
+    "rho_ice": 917,
+    "C_coal": 800,
+    "C_ice": 2100,
+    "L": 334000,
+    "k_coal": 20,
+    "k_ice": 2.2,
+    "h": 300,
+    "T_air": 90,
+    "T_initial": -20,
+    "T_m": 0,
+    "a": 13,
+    "b": 2.72,
+    "c": 1.6
+}
+
+# 构造 DataFrame
+new_sample = pd.DataFrame([new_sample_info])
+
+# 一致性判断
+is_known = ((df["material_name"] == new_sample_info["material_name"]) &
+            (df["manufactured_goods"] == new_sample_info["manufactured_goods"])).any()
+
+# 只传入特征列用于模型预测
+X_new = new_sample[feature_columns]
+predicted_time = model.predict(X_new)[0]
+
+print(f"\n📊 预测真实解冻时间: {predicted_time:.2f} 小时")
+if is_known:
+    print("该样本与历史数据中存在相同物料和制造品,可以认为是同一类样本。")
+else:
+    print("该样本是新的物料或产品组合,可能存在偏差,请注意验证。")

+ 112 - 0
参考.py

@@ -0,0 +1,112 @@
+import numpy as np
+from sklearn.model_selection import train_test_split
+from sklearn.ensemble import RandomForestRegressor
+from sklearn.metrics import mean_squared_error
+from scipy.optimize import minimize
+
+
+# 解冻时间计算函数
+def calculate_defrost_time(w, T_initial):
+    # 物理参数
+    rho_coal = 1400  # 煤的密度
+    rho_ice = 917  # 冰的密度
+    C_coal = 1000  # 煤的比热容
+    C_ice = 2100
+    L = 334000  # 物体长度(米)
+    k_coal = 0.3  # 煤的导热系数
+    k_ice = 2.2
+    h = 10  # 近似导热系数(W/m²·K)
+    T_air = 20  # 空气温度(摄氏度)
+    T_m = 0  # 熔点温度(摄氏度)
+    a, b, c = 13, 2.72, 1.6  # 物体的尺寸(长、宽、高)
+    # 计算体积和表面积
+    V = a * b * c
+    A = 2 * (a * b) + 2 * (b * c) + 2 * (a * c)
+    # 计算混合密度
+    rho_mix = (1 - w) * rho_coal + w * rho_ice
+    # 计算混合比热容
+    C_mix = (1 - w) * C_coal + w * C_ice
+    # 计算特征长度
+    L_char = V / A
+    # 计算体积分数
+    phi = (w * rho_coal) / rho_ice
+    # 计算有效导热系数
+    k_eff = (k_coal * (2 * k_coal + k_ice - 2 * phi * (k_coal - k_ice)) /
+             (2 * k_coal + k_ice + phi * (k_coal - k_ice))) + 1.1
+    # 初步解冻时间 t1(小时)
+    t1 = ((0.2 * rho_mix * C_mix * L_char ** 2) / k_eff *
+          ((T_m - T_initial) / (T_air - T_initial))) / 3600
+    # 进一步解冻时间 t2(小时)
+    k_char = h  # 近似处理 k_char
+    t2 = ((rho_mix * w * L * L_char * L_char / (k_eff * (T_air - T_m))) *
+          ((0.5 + k_eff / (k_char * L_char)) / 6)) / 3600
+    # 总解冻时间
+    t_total = t1 + t2
+    return t_total
+
+
+# 模拟生成数据
+np.random.seed(42)
+n_samples = 500
+# 含水量,范围 10% - 15%
+w = np.random.uniform(0.1, 0.15, n_samples)
+# 初始温度,范围 -10 到 20 摄氏度
+T_initial = np.random.uniform(-10, 20, n_samples)
+# 计算解冻时间
+original_times = []
+for i in range(n_samples):
+    original_times.append(calculate_defrost_time(w[i], T_initial[i]))
+
+# 模拟实际作业时长(实际时长和计算时长有一定随机误差)
+y = np.array(original_times) + np.random.normal(0, 0.2, n_samples)
+
+# 准备特征
+X = np.column_stack((w, T_initial, original_times))
+
+# 划分训练集和测试集
+X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
+
+# 选择模型并训练
+model = RandomForestRegressor(n_estimators=100, random_state=42)
+model.fit(X_train, y_train)
+
+# 模型评估
+y_pred = model.predict(X_test)
+mse = mean_squared_error(y_test, y_pred)
+print(f"Mean Squared Error: {mse}")
+
+
+# 反推函数
+def reverse_calculate(time):
+    def objective_function(vars):
+        w, T_initial = vars
+        calculated_time = calculate_defrost_time(w, T_initial)
+        return abs(calculated_time - time)
+
+    bounds = [(0.1, 0.15), (-10, 20)]  # 含水量和初始温度的范围
+    num_trials = 5  # 尝试的次数
+    best_result = None
+    best_error = np.inf
+    for _ in range(num_trials):
+        # 随机生成初始猜测值
+        initial_guess = [np.random.uniform(0.1, 0.15), np.random.uniform(-10, 20)]
+        result = minimize(objective_function, initial_guess, bounds=bounds)
+        error = result.fun
+        if error < best_error:
+            best_error = error
+            best_result = result
+    return best_result.x[0], best_result.x[1]
+
+
+# 输入实际解冻时间
+try:
+    test_time = float(input("请输入实际解冻时间(小时): "))
+    w_result, T_result = reverse_calculate(test_time)
+    print(f"反推得到的含水量: {w_result}")
+    print(f"反推得到的初始温度: {T_result}")
+    recalculated_time = calculate_defrost_time(w_result, T_result)
+    print(f"重新计算的解冻时间: {recalculated_time}")
+except ValueError:
+    print("输入无效,请输入有效的数字。")
+
+    

+ 53 - 0
模型调用.py

@@ -0,0 +1,53 @@
+from flask import Flask, request, jsonify
+import joblib
+import pandas as pd
+
+app = Flask(__name__)
+model = joblib.load("defrost_time_corrector.pkl")
+
+feature_columns = ["w", "rho_coal", "rho_ice", "C_coal", "C_ice", "L",
+                   "k_coal", "k_ice", "h", "T_air", "T_initial", "T_m",
+                   "a", "b", "c"]
+# 加载训练过的样本信息(用于判断是否相同物料)
+csv_path = 'C:\\Users\\Administrator\\Desktop\\defrost\\feedback_data.csv'
+df_train = pd.read_csv(csv_path, parse_dates=["t_formula", "t_real"], encoding='gbk')
+df_train["material_name"] = df_train["material_name"].astype(str)
+df_train["manufactured_goods"] = df_train["manufactured_goods"].astype(str)
+
+@app.route("/predict_defrost_time", methods=["POST"])
+def predict():
+    data = request.get_json()
+    material = str(data.get("material_name", "")).strip()
+    goods = str(data.get("manufactured_goods", "")).strip()
+
+    print("传递的物料名称为"+material)
+    print("传递的制造品名称为"+goods)
+    # 强制要求必须传物料+制造品名
+    if not material or not goods:
+        return jsonify({
+            "error": "请提供 material_name 和 manufactured_goods 字段"
+        }), 400
+
+    # 判断是否是训练数据中见过的组合
+    is_known = ((df_train["material_name"] == material) &
+                (df_train["manufactured_goods"] == goods)).any()
+
+    if not is_known:
+        return jsonify({
+            "predicted_hours": None,
+            "is_known_sample": False,
+            "error": "未知物料组合,无法预测"
+        })
+
+    # 进行预测
+    df = pd.DataFrame([data])
+    X = df[feature_columns]
+    y_pred = model.predict(X)[0]
+
+    return jsonify({
+        "predicted_hours": round(y_pred, 2),
+        "is_known_sample": True
+    })
+
+if __name__ == '__main__':
+    app.run(host='127.0.0.1', port=9994)