基于Tkinter的天气预测代码运行报错:joblib加载模型失败求助
问题
在VS Code中运行基于Tkinter的天气预测项目,已安装scikit-learn、numpy、pandas、geocoder、pillow等必要依赖库,但在conda环境中多次尝试运行仍报错。报错信息显示加载dtm.joblib时出现dtype不兼容的ValueError。
项目代码:
import tkinter as tk from tkinter import messagebox import joblib from tkinter.font import Font from PIL import Image, ImageTk import geocoder from datetime import datetime classifier = joblib.load('dtm.joblib') window = tk.Tk() window.title("Weather") window.geometry("700x580") window.configure(bg="#396285") def predict_weather(event=None): precipitation = float(entry_precipitation.get()) temp_max = float(entry_temp_max.get()) temp_min = float(entry_temp_min.get()) wind = float(entry_wind.get()) if wind > 15: messagebox.showwarning("Alert", "Cyclone Alert: Heavy wind \n National Disaster Response Force (NDRF): 011-26107953") elif precipitation > 10: messagebox.showwarning("Alert", "Flood Alert: Heavy precipitation (cm) \n National Emergency Response Center (NERC): 011-26701728, 011-26701729") elif temp_max < -5: messagebox.showwarning("Alert", "Heavy Snowfall Alert: Very Low Temperature (°C) \n Tip: Stay Away from Remote Locations") elif temp_min > 38: messagebox.showwarning("Alert", "Drought Alert: Very High temperature (°C) \n Tip: Save Enough Water, don't waste it") else: prediction = classifier.predict([[precipitation, temp_max, temp_min, wind]]) label_result.configure(text=" Predicted weather for today is " + prediction[0], font=("Helvetica", 20), justify="center") def update_time(): current_time = datetime.now().strftime("%I:%M %p") current_date = datetime.now().strftime("%d %B %Y") current_day = datetime.now().strftime("%A") label_datetime.config(text=f"{current_time}\n{current_date}\n{current_day}") window.after(1000, update_time) heading_font = Font(family="Helvetica", size=20, weight="bold") label_title = tk.Label(window, text="WEATHER FORECAST AND ALERT SYSTEM", font=heading_font, bg="#396285", fg="white") label_title.pack(pady=(10, 20)) frame_inputs = tk.Frame(window, bg="#396285") frame_inputs.pack(padx=50, pady=20, anchor="w") label_font = Font(family="Helvetica", size=14, weight="bold") label_precipitation = tk.Label(frame_inputs, text="Precipitation", bg="#396285", fg="white", font=label_font) label_precipitation.grid(row=0, column=0, padx=10, sticky="w") entry_precipitation = tk.Entry(frame_inputs) entry_precipitation.grid(row=0, column=1) label_unit_precipitation = tk.Label(frame_inputs, text="cm", bg="#396285", fg="white", font=label_font) label_unit_precipitation.grid(row=0, column=2) entry_precipitation.bind('<Return>', lambda e: entry_temp_max.focus()) label_temp_max = tk.Label(frame_inputs, text="Maximum Temperature", bg="#396285", fg="white", font=label_font) label_temp_max.grid(row=1, column=0, padx=10, sticky="w") entry_temp_max = tk.Entry(frame_inputs) entry_temp_max.grid(row=1, column=1) label_unit_temp_max = tk.Label(frame_inputs, text="°C", bg="#396285", fg="white", font=label_font) label_unit_temp_max.grid(row=1, column=2) entry_temp_max.bind('<Return>', lambda e: entry_temp_min.focus()) label_temp_min = tk.Label(frame_inputs, text="Minimum Temperature", bg="#396285", fg="white", font=label_font) label_temp_min.grid(row=2, column=0, padx=10, sticky="w") entry_temp_min = tk.Entry(frame_inputs) entry_temp_min.grid(row=2, column=1) label_unit_temp_min = tk.Label(frame_inputs, text="°C", bg="#396285", fg="white", font=label_font) label_unit_temp_min.grid(row=2, column=2) entry_temp_min.bind('<Return>', lambda e: entry_wind.focus()) label_wind = tk.Label(frame_inputs, text="Wind Speed", bg="#396285", fg="white", font=label_font) label_wind.grid(row=3, column=0, padx=10, sticky="w") entry_wind = tk.Entry(frame_inputs) entry_wind.grid(row=3, column=1) label_unit_wind = tk.Label(frame_inputs, text="mph", bg="#396285", fg="white", font=label_font) label_unit_wind.grid(row=3, column=2) entry_wind.bind('<Return>', predict_weather) predict_image = Image.open("predict.png") predict_image = predict_image.resize((150, 50), Image.LANCZOS) predict_photo = ImageTk.PhotoImage(predict_image) button_predict = tk.Button(window, image=predict_photo, command=predict_weather, bd=0, bg="#396285", activebackground="#396285") button_predict.pack(pady=(0, 20), anchor="w", padx=155) label_result = tk.Label(window, text="", bg="#396285", fg="white", font=("Helvetica", 12, "bold"), justify="center") label_result.pack(anchor="w") frame_black = tk.Frame(window, bg="black", height=250) frame_black.pack(fill="both", expand=True) g = geocoder.ip('me') country = g.country if country == 'IN': country = 'India' current_location = g.city + ', ' + country label_location = tk.Label(frame_black, text=current_location, bg="black", fg="white", font=("Helvetica", 36, "bold", "italic")) label_location.pack(side="top", padx=(60, 0), pady=(0, 4)) label_datetime = tk.Label(frame_black, text="", bg="black", fg="white", font=("Helvetica", 35)) label_datetime.pack(side="top", pady=(0, 20)) update_time() window.mainloop()
报错信息:
Traceback (most recent call last): File "c:\Users\nanda\Desktop\Weather-Prediction-main\Weather-Prediction-main\main.py", line 9, in <module> classifier = joblib.load('dtm.joblib') File "C:\Users\nanda\.vscode\New folder\envs\my\lib\site-packages\joblib\numpy_pickle.py", line 658, in load obj = _unpickle(fobj, filename, mmap_mode) File "C:\Users\nanda\.vscode\New folder\envs\my\lib\site-packages\joblib\numpy_pickle.py", line 577, in _unpickle obj = unpickler.load() File "C:\Users\nanda\.vscode\New folder\envs\my\lib\pickle.py", line 1212, in load dispatch[key[0]](self) File "C:\Users\nanda\.vscode\New folder\envs\my\lib\site-packages\joblib\numpy_pickle.py", line 402, in load_build Unpickler.load_build(self) File "C:\Users\nanda\.vscode\New folder\envs\my\lib\pickle.py", line 1717, in load_build setstate(state) File "sklearn\tree\_tree.pyx", line 865, in sklearn.tree._tree.Tree.__setstate__ File "sklearn\tree\_tree.pyx", line 1571, in sklearn.tree._tree._check_node_ndarray ValueError: node array from the pickle has an incompatible dtype: - expected: {'names': ['left_child', 'right_child', 'feature', 'threshold', 'impurity', 'n_node_samples', 'weighted_n_node_samples', 'missing_go_to_left'], 'formats': ['<i8', '<i8', '<i8', '<f8', '<f8', '<i8', '<f8', 'u1'], 'offsets': [0, 8, 16, 24, 32, 40, 48, 56], 'itemsize': 64} - got : [('left_child', '<i8'), ('right_child''', '<i8'), ('feature', '<i8'), ('''threshold''', '<f8'), ('impurity', '<f8'), ('n_node_samples', '<i8'), ('weighted_n_node_samples', '<f8')]
解决方法
匹配scikit-learn版本
这个错误核心是保存dtm.joblib时的scikit-learn版本和当前运行环境的版本不一致,决策树的节点结构在不同版本中发生了格式变化。- 若知道保存模型时的scikit-learn版本,直接安装对应版本:
把# conda环境安装 conda install scikit-learn==x.x.x # 或pip安装 pip install scikit-learn==x.x.xx.x.x替换为保存模型时的具体版本号。 - 若不知道旧版本,重新训练模型:在当前conda环境中运行训练该决策树模型的代码,生成新的
dtm.joblib文件替换旧文件。
- 若知道保存模型时的scikit-learn版本,直接安装对应版本:
检查模型文件完整性
确认dtm.joblib文件没有损坏或被修改,若文件异常,重新获取或重新训练生成。统一环境依赖
确保训练模型和运行预测的环境依赖版本完全一致,包括numpy、scikit-learn等核心库:- 在训练模型的环境中导出依赖清单:
pip freeze > requirements.txt - 在当前运行环境中安装相同依赖:
pip install -r requirements.txt
- 在训练模型的环境中导出依赖清单:
内容的提问来源于stack exchange,提问作者Deepthi
相关产品推荐
相关产品推荐

