Как попасть в конечную точку API с помощью модели sklearn?

#python #python-3.x #api #flask

#python #python-3.x #API #flask

Вопрос:

В настоящее время я застрял, пытаясь загрузить модель, чтобы сделать прогноз и загрузить результат в конечную точку API. У меня есть этот код, который содержит модель и сохраняет модель в виде файла pickle.

 from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import pickle
from sklearn import datasets#Iris Dataset
iris = datasets.load_iris()
X = iris.data#KMeans
km = KMeans(n_clusters=3)
km.fit(X)
km.predict(X)
labels = km.labels_#Plotting
fig = plt.figure(1, figsize=(7,7))
ax = Axes3D(fig, rect=[0, 0, 0.95, 1], elev=48, azim=134)
ax.scatter(X[:, 3], X[:, 0], X[:, 2],
          c=labels.astype(np.float), edgecolor="k", s=50)
ax.set_xlabel("Petal width")
ax.set_ylabel("Sepal length")
ax.set_zlabel("Petal length")
plt.title("K Means", fontsize=14)

with open('C:\Users\ryans\kmeans.pkl', 'wb') as f:
    pickle.dump(km, f)
  

Кажется, это работает нормально, но последние две строки, чтобы выделить файл и сохранить его, кажутся необходимыми ТОЛЬКО при первом запуске. Если я открою файл, используя приведенный ниже код, я не вижу необходимости повторно сохранять выбранный файл. В любом случае, вот код, который я тестирую, чтобы попасть в конечную точку API.

 from flask import Flask, jsonify
import pickle
import pandas as pd
import requests

api = Flask(__name__)
@api.route('/predict', methods=['POST'])
def predict():
     json_features = requests.json
     query_df = pd.DataFrame(json_features)
     features = pd.get_dummies(query_df)
     prediction = kmeans.predict(features)
     return jsonify({'prediction': list(prediction)})
 
if __name__ == '__main__':
     try:
         kmeans = pickle.load(open("C:\Users\ryans\kmeans.pkl", "rb"))
         api.run(debug=True, port=8000)
         traceback.print_exc(file=sys.stdout)
     except:
        print("Exception in user code:")
        print('-'*60)
        traceback.print_exc(file=sys.stdout)
        print('-'*60)
  

Когда я запускаю этот код, я получаю эту ошибку.

  * Serving Flask app "untitled41" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Restarting with windowsapi reloader
Exception in user code:
------------------------------------------------------------
Traceback (most recent call last):
  File "<ipython-input-48-1749e4d56106>", line 19, in <module>
    api.run(debug=True, port=8000)
  File "C:UsersryansAnaconda3libsite-packagesflaskapp.py", line 990, in run
    run_simple(host, port, self, **options)
  File "C:UsersryansAnaconda3libsite-packageswerkzeugserving.py", line 1050, in run_simple
    run_with_reloader(inner, extra_files, reloader_interval, reloader_type)
  File "C:UsersryansAnaconda3libsite-packageswerkzeug_reloader.py", line 339, in run_with_reloader
    sys.exit(reloader.restart_with_reloader())
SystemExit: 1
------------------------------------------------------------
  

Вероятно, здесь проще дополнить мой первоначальный пост моими выводами, основанными на том, что вы предложили.

Я добавил это:

 api.run(debug=True, port=8000, use_reloader=False)
  

Теперь я захожу в свой браузер и ввожу это: ‘http://localhost:8000/predict ‘

Я вижу этот результат:

 Not Found

The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
  

Я протестировал очень простой пример сценария:

 from flask import Flask

app = Flask(__name__)

@app.route('/api', methods=['GET','POST','DELETE'])
def api():
    return 'YOU MADE IT!'

if __name__ == '__main__':
    app.run(debug=True, port=8000, use_reloader=False)
  

Для меня это работает абсолютно нормально!

Наконец, я не понимаю эту часть:

 export FLASK_APP=my_app.py
export FLASK_DEBUG=1
flask run
  

Выполняется ли это в конце ‘kmeans.py ‘ скрипт? Когда я добавляю это, я получаю «Недопустимый синтаксис» в первой из трех строк.

Комментарии:

1. Вы записываете этот код flask в записную книжку?

2. Нет, я запускаю его в Spyder. Я заметил, что была какая — то ошибка в ‘app.py . Я подумал, что в какой-то момент что-то могло быть повреждено, поэтому я просто удалил Flask, а затем переустановил Flask. Я все еще получаю то же сообщение об ошибке.

3. можете ли вы попробовать мою рекомендацию и сообщить мне, поможет ли это?

Ответ №1:

Я предполагаю, что вы используете код flask в notebook (среда Ipython) и debug=True заставляете процесс перезагружаться, что вызывает эту проблему, вы можете установить use_reload на False

 api.run(debug=True, port=8000, use_reloader=False)
  

Кроме того, попробуйте запустить его в скрипте с помощью команды flask (из командной строки / консоли) вместо этого, сначала сохранив код в файле (например app.py ) и устанавливаем имя скрипта и режим отладки, как показано ниже

 export FLASK_APP=my_app.py
export FLASK_DEBUG=1
flask run
  

Комментарии:

1. Я попробовал ваше предложение и обновил свой первоначальный пост своими выводами.

2. Если первая часть работает для вас, вам не понадобится вторая вещь, это просто способ запустить flask из командной строки. Пожалуйста, не стесняйтесь голосовать и примите это как ответ, если это сработает

3. Это не работает. Когда я ввожу ‘ localhost: 8000 / predict ‘ или ‘ 127.0.0.1: 8000 / predict ‘, я получаю это: ‘Метод не разрешен Метод не разрешен для запрошенного URL.’. Я, должно быть, упускаю что-то простое. Кажется, что это довольно близко, и я думаю, что код в значительной степени имеет смысл, но что-то здесь все еще не так.

4. Во-первых, ваша основная проблема, связанная с этим вопросом, решена, будучи опытным пользователем stackoverflow, вы должны знать, что вам нужно создать другой вопрос для другой проблемы. Во-вторых, в вашем коде вы перехватываете запрос POST, и здесь вы отправляете запрос get в / predict