GaussianNB对象无var_属性问题求助:Flask项目提交时报错
问题:Flask项目中GaussianNB模型pickle加载后调用predict_proba报错AttributeError: 'GaussianNB' object has no attribute 'var_'
开发Python Flask项目时,编译正常,但提交表单后触发错误。使用的库包括numpy、flask、pickle、Pandas、Matplotlib。
错误信息
Traceback (most recent call last): File "C:\Users\sumit\AppData\Local\Programs\Python\Python310\lib\site-packages\flask\app.py", line 2091, in __call__ return self.wsgi_app(environ, start_response) File "C:\Users\sumit\AppData\Local\Programs\Python\Python310\lib\site-packages\flask\app.py", line 2076, in wsgi_app response = self.handle_exception(e) File "C:\Users\sumit\AppData\Local\Programs\Python\Python310\lib\site-packages\flask\app.py", line 2073, in wsgi_app response = self.full_dispatch_request() File "C:\Users\sumit\AppData\Local\Programs\Python\Python310\lib\site-packages\flask\app.py", line 1519, in full_dispatch_request rv = self.handle_user_exception(e) File "C:\Users\sumit\AppData\Local\Programs\Python\Python310\lib\site-packages\flask\app.py", line 1517, in full_dispatch_request rv = self.dispatch_request() File "C:\Users\sumit\AppData\Local\Programs\Python\Python310\lib\site-packages\flask\app.py", line 1503, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args) File "f:\Projects\Heart Disease Predictor\HeartDiseasesPredictor-master\main.py", line 31, in hello_world infProb = clf.predict_proba([enter]) File "C:\Users\sumit\AppData\Local\Programs\Python\Python310\lib\site-packages\sklearn\naive_bayes.py", line 123, in predict_proba return np.exp(self.predict_log_proba(X)) File "C:\Users\sumit\AppData\Local\Programs\Python\Python310\lib\site-packages\sklearn\naive_bayes.py", line 102, in predict_log_proba jll = self._joint_log_likelihood(X) File "C:\Users\sumit\AppData\Local\Programs\Python\Python310\lib\site-packages\sklearn\naive_bayes.py", line 487, in _joint_log_likelihood n_ij = -0.5 * np.sum(np.log(2.0 * np.pi * self.var_[i, :])) AttributeError: 'GaussianNB' object has no attribute 'var_'
相关代码
Main.py代码
from flask import Flask, render_template, request import pickle app = Flask(__name__) file = open('model.pkl','rb') clf = pickle.load(file) file.close() @app.route('/', methods = ["GET","POST"]) def hello_world(): if request.method == "POST": myDict = request.form print(myDict) name = myDict['name'] cp = int(myDict['cp']) trestbps = int(myDict['trestbps']) sex = int(myDict['sex']) age = int(myDict['age']) fbs= int(myDict['fbs']) chol = int(myDict['chol']) restecg = int(myDict['restecg']) slope = int(myDict['slope']) ca = int(myDict['ca']) thalach = int(myDict['thalach']) exang = int(myDict['exang']) oldpeak = float(myDict['oldpeak']) thal = int(myDict['thal']) print(myDict) enter = [age,sex,cp,trestbps,chol,fbs,restecg,thalach,exang,oldpeak,slope,ca,thal] print(enter) infProb = clf.predict_proba([enter]) x = infProb[0][1]*100 return render_template('show.html',uname=name,inf = int(x)) return render_template('index.html') if __name__ == '__main__': app.run(debug=True)
my_training.py代码
import numpy as np import matplotlib.pyplot as plt import pandas as pd import pickle dataset = pd.read_csv('heart.csv') X = dataset.iloc[:, :-1].values y = dataset.iloc[:, -1].values from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 0) #Naive Bayes Classifier from sklearn.naive_bayes import GaussianNB classifier = GaussianNB() classifier.fit(X_train, y_train) infProb = classifier.predict_proba([[58,1,2,140,211,1,0,165,0,0,2,0,2]]) print(infProb[0][1]*100) #creating the file to save the model file = open('model.pkl', 'wb') pickle.dump(classifier, file) file.close()
解决方案
这个错误核心原因是训练模型和加载模型时的scikit-learn版本不一致。var_是GaussianNB在新版本scikit-learn中训练后生成的属性,若训练用旧版本、加载用新版本,就会出现属性缺失问题。
解决步骤:
- 统一环境版本:
- 查看Flask运行环境的scikit-learn版本:
pip show scikit-learn - 在训练环境安装相同版本:
pip install scikit-learn==x.x.x(替换x.x.x为查到的版本)
- 查看Flask运行环境的scikit-learn版本:
- 重新运行
my_training.py生成新的model.pkl - 重启Flask服务测试
另外,推荐用joblib替代pickle保存scikit-learn模型,对这类模型的序列化支持更友好:
- 修改训练代码的保存部分:
import joblib joblib.dump(classifier, 'model.joblib') - 修改Main.py的加载部分:
import joblib clf = joblib.load('model.joblib')
内容的提问来源于stack exchange,提问作者Sumit
相关产品推荐
相关产品推荐

