Flask REST API ile Python Makine Öğrenimi Tahmini

Yayınlanan: 2022-03-11

Bu makale, bir Flask REST API ile gerçek zamanlı tahminler yapmak için bir makine öğrenimi veya yapay zeka (AI) sistemi bağlamında Python'u kullanmakla ilgilidir. Burada ortaya çıkan mimari, makine öğrenimi uygulamaları için kavram kanıtından (PoC) minimum uygulanabilir ürüne (MVP) geçmenin bir yolu olarak görülebilir.

Python, gerçek zamanlı bir çözüm tasarlarken akla gelen ilk seçenek değildir. Ancak Tensorflow ve Scikit-Learn, Python tarafından desteklenen en çok kullanılan makine öğrenimi kitaplıklarından bazıları olduğundan, birçok Jupyter Notebook PoC'de rahatlıkla kullanılır.

Bu çözümü uygulanabilir kılan şey, eğitimin tahmin etmeye kıyasla çok zaman almasıdır. Eğitimi bir film izleme ve onunla ilgili soruların cevaplarını tahmin etme süreci olarak düşünürseniz, her yeni sorudan sonra filmi tekrar izlemek zorunda kalmamak oldukça verimli görünüyor.

Eğitim, bu “filmin” bir tür sıkıştırılmış görünümüdür ve tahmin, sıkıştırılmış görünümden bilgi almaktır. Film ister karmaşık ister uzun olsun, gerçekten hızlı olmalı.

Bunu Python'da hızlı bir [Flask] örneği ile uygulayalım!

Genel Makine Öğrenimi Mimarisi

Genel bir eğitim ve tahmin mimarisi akışının ana hatlarını çizerek başlayalım:

resim alt metni

İlk olarak, bir amaç fonksiyonuna göre geçmiş veriler hakkında bilgi edinmek için bir eğitim hattı oluşturulur.

Bu, iki temel öğeyi çıkarmalıdır:

  1. Özellik mühendisliği işlevleri : Eğitim zamanında kullanılan dönüşümler, tahmin zamanında yeniden kullanılmalıdır.
  2. Model parametreleri : Son olarak seçilen algoritma ve hiperparametreler kaydedilmeli, böylece tahmin zamanında yeniden kullanılabilirler

Tahmine uygulanabilir olması için eğitim süresi boyunca yapılan özellik mühendisliğinin dikkatli bir şekilde kaydedilmesi gerektiğini unutmayın. Yol boyunca ortaya çıkabilecek diğer pek çok sorun arasında olağan bir sorun, birçok algoritma için gerekli olan özellik ölçeklemedir .

X1 özelliği 1 değerinden 1000 değerine ölçeklenirse ve f(x) = x/max(X1) işleviyle [0,1] aralığına yeniden ölçeklenirse, tahmin kümesinin değeri 2000 olursa ne olur?

Eşleme işlevinin tahmin zamanında doğru olarak hesaplanacak tutarlı çıktılar döndürmesi için önceden bazı dikkatli ayarlamalar düşünülmelidir.

Makine Öğrenimi Eğitimi ve Tahmin Etme

Burada ele alınması gereken önemli bir soru var. Başlangıç ​​olarak neden eğitim ve tahmini ayırıyoruz?

Tüm verilerin (tahmin edilecek veriler dahil) önceden bilindiği makine öğrenimi örnekleri ve kursları bağlamında, tahmin ediciyi oluşturmanın çok basit bir yolunun eğitim ve tahmin verilerini (genellikle bir test seti).

Daha sonra, sonuçları almak için “eğitim seti” üzerinde eğitim ve “test seti” üzerinde tahmin yapmak, aynı zamanda hem tren hem de test verileri üzerinde özellik mühendisliği yapmak, aynı ve benzersiz ardışık düzende eğitim ve tahmin yapmak gerekir. .

Ancak gerçek hayattaki sistemlerde genellikle eğitim verileriniz vardır ve tahmin edilmesi gereken veriler işlenirken gelir. Başka bir deyişle, filmi bir kerede izliyorsunuz ve daha sonra filmle ilgili bazı sorularınız var, bu da cevapların kolay ve hızlı olması gerektiği anlamına geliyor.

Ayrıca, eğitim zaman aldığından (bazı görüntü kümeleri için haftalar sürebilir) ve zaman içinde yeterince kararlı olması gerektiğinden, her yeni veri geldiğinde tüm modeli yeniden eğitmek genellikle gerekli değildir.

Bu nedenle eğitim ve tahmin birçok sistemde net bir şekilde ayrılabilir ve hatta ayrılmalıdır ve bu aynı zamanda akıllı bir sistemin (yapay veya değil) nasıl öğrendiğini daha iyi yansıtır.

Overfitting ile Bağlantı

Eğitim ve tahminin ayrılması da aşırı uyum sorununu çözmenin iyi bir yoludur.

İstatistikte fazla uydurma, "belirli bir veri kümesine çok yakın veya tam olarak karşılık gelen ve bu nedenle ek verilere uymayı veya gelecekteki gözlemleri güvenilir bir şekilde tahmin etmeyi başaramayan bir analizin üretilmesidir".

resim alt metni

Yeşil çizgi fazla takılan bir modeli, siyah çizgi ise normalleştirilmiş bir modeli temsil ediyor. Yeşil çizgi eğitim verilerini en iyi şekilde takip ederken, bu verilere fazlasıyla bağımlıdır ve siyah çizgiye kıyasla yeni görünmeyen verilerde daha yüksek bir hata oranına sahip olması muhtemeldir._

Aşırı uyum, özellikle birçok özelliğe sahip veri kümelerinde veya sınırlı eğitim verisine sahip veri kümelerinde görülür. Her iki durumda da veriler, tahmin edici tarafından doğrulanabilecek bilgilerle karşılaştırıldığında çok fazla bilgiye sahiptir ve bunlardan bazıları tahmin edilen değişkenle bağlantılı bile olmayabilir. Bu durumda, gürültünün kendisi bir sinyal olarak yorumlanabilir.

Fazla uydurmayı kontrol etmenin iyi bir yolu, verinin bir kısmı üzerinde eğitim almak ve üzerinde temel gerçeğe sahip olduğumuz başka bir kısım hakkında tahminde bulunmaktır. Bu nedenle, üzerinde eğitim aldığımız verilerin sistemin gerçekliğini ve gelecekteki durumlarını temsil etmesi koşuluyla, yeni verilerde beklenen hata kabaca bu veri kümesinde ölçülen hatadır.

Bu nedenle, doğru bir veri bölünmesiyle birlikte uygun bir eğitim ve tahmin hattı tasarlarsak, yalnızca aşırı uyum sorununu ele almakla kalmaz, aynı zamanda bu mimariyi yeni veriler üzerinde tahmin yapmak için yeniden kullanabiliriz.

Son adım, yeni verilerdeki hatanın beklendiği gibi aynı olup olmadığını kontrol etmek olacaktır. Her zaman bir kayma vardır (gerçek hata her zaman beklenenin altındadır) ve kabul edilebilir bir kaymanın ne olduğu belirlenmelidir - ancak bu makalenin konusu değildir.

Tahmin için bir REST API

Eğitim ve tahmini açıkça ayırmanın işe yaradığı yer burasıdır. Özellik mühendisliği yöntemlerimizi ve model parametrelerimizi kaydettiysek, bu öğelerle basit bir REST API oluşturabiliriz.

resim alt metni

Buradaki anahtar, API açılışında modeli ve parametreleri yüklemektir. Başlatıldıktan ve bellekte saklandıktan sonra, her API çağrısı, özellik mühendisliği hesaplamasını ve ML algoritmasının "tahmin" yöntemini tetikler. Her ikisi de genellikle gerçek zamanlı bir yanıt sağlamak için yeterince hızlıdır.

API, tahmin edilecek benzersiz bir örneği veya birkaç farklı örneği (toplu tahminler) kabul edecek şekilde tasarlanabilir.

JSON giriş ve JSON çıkış (soru giriş, cevaplama) ile bu prensibi uygulayan minimum Python/Flask kodu:

 app = Flask(__name__) @app.route('/api/makecalc/', methods=['POST']) def makecalc(): """ Function run at each API call No need to re-load the model """ # reads the received json jsonfile = request.get_json() res = dict() for key in jsonfile.keys(): # calculates and predicts res[key] = model.predict(doTheCalculation(key)) # returns a json file return jsonify(res) if __name__ == '__main__': # Model is loaded when the API is launched model = pickle.load(open('modelfile', 'rb')) app.run(debug=True)

API'nin yeni verilerden tahmin yapmak için kullanılabileceğini unutmayın, ancak modeli eğitmek için kullanılmasını önermiyorum. Kullanılabilir, ancak bu, model eğitim kodunu karmaşıklaştırır ve bellek kaynakları açısından daha talepkar olabilir.

Uygulama Örneği - Bisiklet Paylaşımı

Örnek olarak bir Kaggle veri setini, bisiklet paylaşımını ele alalım. Bisikletin bakımını, lojistiğini ve işin diğer yönlerini daha iyi yönetmek için her gün kiralık bisiklet sayısını tahmin etmek isteyen bir bisiklet paylaşım şirketi olduğumuzu varsayalım.

resim alt metni

Kiralamalar esas olarak hava koşullarına bağlıdır, bu nedenle hava tahmini ile bu şirket, kiralamaların ne zaman zirveye çıkacağını daha iyi bir fikir edinebilir ve bu günlerde bakım yapmaktan kaçınmaya çalışabilir.

İlk olarak, bir modeli eğitiyoruz ve onu Jupyter not defterinde görülebilecek bir turşu nesnesi olarak kaydediyoruz.

Model eğitimi ve performansı burada ele alınmamıştır, bu sadece tüm süreci anlamak için bir örnektir.

Ardından her API çağrısında yapılacak olan veri dönüşümünü yazıyoruz:

 import numpy as np import pandas as pd from datetime import date def doTheCalculation(data): data['dayofyear']=(data['dteday']- data['dteday'].apply(lambda x: date(x.year,1,1)) .astype('datetime64[ns]')).apply(lambda x: x.days) X = np.array(data[['instant','season','yr','holiday','weekday','workingday', 'weathersit','temp','atemp','hum','windspeed','dayofyear']]) return X

Bu sadece bir değişkenin (yılın günü) hem ayı hem de kesin günü içerecek şekilde hesaplanmasıdır. Ayrıca, bir dizi sütun ve bunların sıralanması gereken sıraları da vardır.

O halde Flask ile REST API yazmamız gerekiyor:

 from flask import Flask, request, redirect, url_for, flash, jsonify from features_calculation import doTheCalculation import json, pickle import pandas as pd import numpy as np app = Flask(__name__) @app.route('/api/makecalc/', methods=['POST']) def makecalc(): """ Function run at each API call """ jsonfile = request.get_json() data = pd.read_json(json.dumps(jsonfile),orient='index',convert_dates=['dteday']) print(data) res = dict() ypred = model.predict(doTheCalculation(data)) for i in range(len(ypred)): res[i] = ypred[i] return jsonify(res) if __name__ == '__main__': modelfile = 'modelfile.pickle' model = pickle.load(open(modelfile, 'rb')) print("loaded OK") app.run(debug=True)

Bu programı çalıştırın, varsayılan olarak 5000 numaralı bağlantı noktasında API'ye hizmet edecektir.

Bir isteği yerel olarak test edersek, yine de Python ile:

 import requests, json url = '[http://127.0.0.1:5000/api/makecalc/](http://127.0.0.1:5000/api/makecalc/)' text = json.dumps({"0":{"instant":1,"dteday":"2011-01-01T00:00:00.000Z","season":1,"yr":0,"mnth":1,"holiday":0,"weekday":6,"workingday":0,"weathersit":2,"temp":0.344167,"atemp":0.363625,"hum":0.805833,"windspeed":0.160446}, "1":{"instant":2,"dteday":"2011-01-02T00:00:00.000Z","season":1,"yr":0,"mnth":1,"holiday":0,"weekday":3,"workingday":0,"weathersit":2,"temp":0.363478,"atemp":0.353739,"hum":0.696087,"windspeed":0.248539}, "2":{"instant":3,"dteday":"2011-01-03T00:00:00.000Z","season":1,"yr":0,"mnth":1,"holiday":0,"weekday":1,"workingday":1,"weathersit":1,"temp":0.196364,"atemp":0.189405,"hum":0.437273,"windspeed":0.248309}})

İstek, modele beslenen tüm bilgileri içerir. Bu nedenle, modelimiz belirtilen tarihler için bir bisiklet kiralama tahmini ile yanıt verecektir (burada üç tane var).

 headers = {'content-type': 'application/json', 'Accept-Charset': 'UTF-8'} r = requests.post(url, data=text, headers=headers) print(r,r.text) <Response [200]> { "0": 1063, "1": 1028, "2": 1399 }

Bu kadar! Bu hizmet, herhangi bir şirketin uygulamasında, bakım planlaması için veya kullanıcıların bisiklet trafiğinden, talepten ve kiralık bisikletlerin bulunabilirliğinden haberdar olmaları için kolayca kullanılabilir.

Hepsini bir araya koy

Pek çok makine öğrenimi sisteminin ve özellikle PoC'lerin en büyük kusuru, eğitim ve tahminin karıştırılmasıdır.

Dikkatlice ayrılırlarsa, bir MVP için Python/Flask ile oldukça düşük bir geliştirme maliyeti ve çabasıyla, özellikle de birçok PoC için başlangıçta Scikit-learn, Tensorflow ile geliştirilmişse, gerçek zamanlı tahminler oldukça kolay bir şekilde gerçekleştirilebilir. veya başka bir Python makine öğrenimi kitaplığı.

Ancak bu, tüm uygulamalar, özellikle özellik mühendisliğinin yoğun olduğu uygulamalar veya her aramada en son verilere sahip olması gereken en yakın eşleşmeyi alan uygulamalar için uygun olmayabilir.

Her halükarda, onlar hakkındaki soruları cevaplamak için filmleri tekrar tekrar izlemeniz gerekiyor mu? Aynı kural makine öğrenimi için de geçerlidir!