You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ML-For-Beginners/translations/fr/3-Web-App/1-Web-App/README.md

17 KiB

Construire une application Web pour utiliser un modèle ML

Dans cette leçon, vous allez entraîner un modèle ML sur un ensemble de données qui sort de l'ordinaire : les observations d'OVNIs au cours du siècle dernier, provenant de la base de données de NUFORC.

Vous apprendrez :

  • Comment "pickle" un modèle entraîné
  • Comment utiliser ce modèle dans une application Flask

Nous continuerons à utiliser des notebooks pour nettoyer les données et entraîner notre modèle, mais vous pouvez pousser le processus un peu plus loin en explorant l'utilisation d'un modèle "dans la nature", pour ainsi dire : dans une application web.

Pour ce faire, vous devez construire une application web en utilisant Flask.

Quiz avant le cours

Construction d'une application

Il existe plusieurs façons de construire des applications web pour consommer des modèles d'apprentissage automatique. Votre architecture web peut influencer la façon dont votre modèle est entraîné. Imaginez que vous travaillez dans une entreprise où le groupe de science des données a entraîné un modèle qu'il souhaite que vous utilisiez dans une application.

Considérations

Il y a beaucoup de questions à poser :

  • Est-ce une application web ou une application mobile ? Si vous construisez une application mobile ou si vous devez utiliser le modèle dans un contexte IoT, vous pourriez utiliser TensorFlow Lite et utiliser le modèle dans une application Android ou iOS.
  • Où résidera le modèle ? Dans le cloud ou localement ?
  • Support hors ligne. L'application doit-elle fonctionner hors ligne ?
  • Quelle technologie a été utilisée pour entraîner le modèle ? La technologie choisie peut influencer les outils que vous devez utiliser.
    • Utilisation de TensorFlow. Si vous entraînez un modèle en utilisant TensorFlow, par exemple, cet écosystème offre la possibilité de convertir un modèle TensorFlow pour une utilisation dans une application web en utilisant TensorFlow.js.
    • Utilisation de PyTorch. Si vous construisez un modèle en utilisant une bibliothèque telle que PyTorch, vous avez la possibilité de l'exporter au format ONNX (Open Neural Network Exchange) pour une utilisation dans des applications web JavaScript qui peuvent utiliser Onnx Runtime. Cette option sera explorée dans une leçon future pour un modèle entraîné avec Scikit-learn.
    • Utilisation de Lobe.ai ou Azure Custom Vision. Si vous utilisez un système ML SaaS (Software as a Service) tel que Lobe.ai ou Azure Custom Vision pour entraîner un modèle, ce type de logiciel propose des moyens d'exporter le modèle pour de nombreuses plateformes, y compris la construction d'une API sur mesure à interroger dans le cloud par votre application en ligne.

Vous avez également l'opportunité de construire une application web Flask entière qui serait capable d'entraîner le modèle elle-même dans un navigateur web. Cela peut également être fait en utilisant TensorFlow.js dans un contexte JavaScript.

Pour nos besoins, étant donné que nous avons travaillé avec des notebooks basés sur Python, explorons les étapes que vous devez suivre pour exporter un modèle entraîné depuis un tel notebook vers un format lisible par une application web construite en Python.

Outil

Pour cette tâche, vous avez besoin de deux outils : Flask et Pickle, tous deux fonctionnant sur Python.

Qu'est-ce que Flask ? Défini comme un "micro-framework" par ses créateurs, Flask fournit les fonctionnalités de base des frameworks web utilisant Python et un moteur de template pour construire des pages web. Jetez un œil à ce module Learn pour pratiquer la construction avec Flask.

Qu'est-ce que Pickle ? Pickle 🥒 est un module Python qui sérialise et désérialise une structure d'objet Python. Lorsque vous "pickle" un modèle, vous sérialisez ou aplatissez sa structure pour une utilisation sur le web. Faites attention : pickle n'est pas intrinsèquement sécurisé, donc soyez prudent si vous êtes invité à "un-pickle" un fichier. Un fichier picklé a le suffixe .pkl.

Exercice - nettoyez vos données

Dans cette leçon, vous utiliserez des données provenant de 80 000 observations d'OVNIs, collectées par NUFORC (Le Centre national de rapport sur les OVNIs). Ces données contiennent des descriptions intéressantes d'observations d'OVNIs, par exemple :

  • Longue description d'exemple. "Un homme émerge d'un faisceau de lumière qui brille sur un champ herbeux la nuit et il court vers le parking de Texas Instruments".
  • Courte description d'exemple. "les lumières nous ont poursuivis".

Le tableau ufos.csv comprend des colonnes sur le city, state et country où l'observation a eu lieu, l'shape de l'objet et son latitude et longitude.

Dans le notebook vierge inclus dans cette leçon :

  1. importez pandas, matplotlib, et numpy comme vous l'avez fait dans les leçons précédentes et importez le tableau ufos. Vous pouvez jeter un œil à un échantillon de données :

    import pandas as pd
    import numpy as np
    
    ufos = pd.read_csv('./data/ufos.csv')
    ufos.head()
    
  2. Convertissez les données ufos en un petit dataframe avec de nouveaux titres. Vérifiez les valeurs uniques dans le champ Country.

    ufos = pd.DataFrame({'Seconds': ufos['duration (seconds)'], 'Country': ufos['country'],'Latitude': ufos['latitude'],'Longitude': ufos['longitude']})
    
    ufos.Country.unique()
    
  3. Maintenant, vous pouvez réduire la quantité de données avec lesquelles nous devons travailler en supprimant toutes les valeurs nulles et en n'importing que les observations entre 1 et 60 secondes :

    ufos.dropna(inplace=True)
    
    ufos = ufos[(ufos['Seconds'] >= 1) & (ufos['Seconds'] <= 60)]
    
    ufos.info()
    
  4. Importez la bibliothèque LabelEncoder de Scikit-learn pour convertir les valeurs textuelles des pays en un nombre :

    LabelEncoder encode les données par ordre alphabétique

    from sklearn.preprocessing import LabelEncoder
    
    ufos['Country'] = LabelEncoder().fit_transform(ufos['Country'])
    
    ufos.head()
    

    Vos données devraient ressembler à ceci :

    	Seconds	Country	Latitude	Longitude
    2	20.0	3		53.200000	-2.916667
    3	20.0	4		28.978333	-96.645833
    14	30.0	4		35.823889	-80.253611
    23	60.0	4		45.582778	-122.352222
    24	3.0		3		51.783333	-0.783333
    

Exercice - construisez votre modèle

Maintenant, vous pouvez vous préparer à entraîner un modèle en divisant les données en groupes d'entraînement et de test.

  1. Sélectionnez les trois caractéristiques sur lesquelles vous souhaitez vous entraîner en tant que vecteur X, et le vecteur y sera le Country. You want to be able to input Seconds, Latitude and Longitude et obtenez un identifiant de pays à retourner.

    from sklearn.model_selection import train_test_split
    
    Selected_features = ['Seconds','Latitude','Longitude']
    
    X = ufos[Selected_features]
    y = ufos['Country']
    
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
    
  2. Entraînez votre modèle en utilisant la régression logistique :

    from sklearn.metrics import accuracy_score, classification_report
    from sklearn.linear_model import LogisticRegression
    model = LogisticRegression()
    model.fit(X_train, y_train)
    predictions = model.predict(X_test)
    
    print(classification_report(y_test, predictions))
    print('Predicted labels: ', predictions)
    print('Accuracy: ', accuracy_score(y_test, predictions))
    

La précision n'est pas mauvaise (environ 95%), sans surprise, car Country and Latitude/Longitude correlate.

The model you created isn't very revolutionary as you should be able to infer a Country from its Latitude and Longitude, mais c'est un bon exercice d'essayer d'entraîner à partir de données brutes que vous avez nettoyées, exportées, puis d'utiliser ce modèle dans une application web.

Exercice - 'pickle' votre modèle

Maintenant, il est temps de pickle votre modèle ! Vous pouvez le faire en quelques lignes de code. Une fois qu'il est picklé, chargez votre modèle picklé et testez-le contre un tableau de données échantillon contenant des valeurs pour les secondes, la latitude et la longitude,

import pickle
model_filename = 'ufo-model.pkl'
pickle.dump(model, open(model_filename,'wb'))

model = pickle.load(open('ufo-model.pkl','rb'))
print(model.predict([[50,44,-12]]))

Le modèle renvoie '3', qui est le code pays pour le Royaume-Uni. Incroyable ! 👽

Exercice - construisez une application Flask

Maintenant, vous pouvez construire une application Flask pour appeler votre modèle et renvoyer des résultats similaires, mais d'une manière plus visuellement agréable.

  1. Commencez par créer un dossier appelé web-app à côté du fichier notebook.ipynb où se trouve votre fichier ufo-model.pkl.

  2. Dans ce dossier, créez trois autres dossiers : static, avec un dossier css à l'intérieur, et templates. Vous devriez maintenant avoir les fichiers et répertoires suivants :

    web-app/
      static/
        css/
      templates/
    notebook.ipynb
    ufo-model.pkl
    

    Consultez le dossier de solution pour une vue de l'application terminée

  3. Le premier fichier à créer dans le dossier web-app est le fichier requirements.txt. Comme package.json dans une application JavaScript, ce fichier répertorie les dépendances requises par l'application. Dans requirements.txt, ajoutez les lignes :

    scikit-learn
    pandas
    numpy
    flask
    
  4. Maintenant, exécutez ce fichier en naviguant vers web-app :

    cd web-app
    
  5. Dans votre terminal, tapez pip install, pour installer les bibliothèques répertoriées dans requirements.txt :

    pip install -r requirements.txt
    
  6. Maintenant, vous êtes prêt à créer trois autres fichiers pour terminer l'application :

    1. Créez app.py à la racine.
    2. Créez index.html dans le répertoire templates.
    3. Créez styles.css dans le répertoire static/css.
  7. Développez le fichier styles.css avec quelques styles :

    body {
    	width: 100%;
    	height: 100%;
    	font-family: 'Helvetica';
    	background: black;
    	color: #fff;
    	text-align: center;
    	letter-spacing: 1.4px;
    	font-size: 30px;
    }
    
    input {
    	min-width: 150px;
    }
    
    .grid {
    	width: 300px;
    	border: 1px solid #2d2d2d;
    	display: grid;
    	justify-content: center;
    	margin: 20px auto;
    }
    
    .box {
    	color: #fff;
    	background: #2d2d2d;
    	padding: 12px;
    	display: inline-block;
    }
    
  8. Ensuite, développez le fichier index.html :

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8">
        <title>🛸 UFO Appearance Prediction! 👽</title>
        <link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
      </head>
    
      <body>
        <div class="grid">
    
          <div class="box">
    
            <p>According to the number of seconds, latitude and longitude, which country is likely to have reported seeing a UFO?</p>
    
            <form action="{{ url_for('predict')}}" method="post">
              <input type="number" name="seconds" placeholder="Seconds" required="required" min="0" max="60" />
              <input type="text" name="latitude" placeholder="Latitude" required="required" />
              <input type="text" name="longitude" placeholder="Longitude" required="required" />
              <button type="submit" class="btn">Predict country where the UFO is seen</button>
            </form>
    
            <p>{{ prediction_text }}</p>
    
          </div>
    
        </div>
    
      </body>
    </html>
    

    Jetez un œil au templating dans ce fichier. Remarquez la syntaxe 'mustache' autour des variables qui seront fournies par l'application, comme le texte de prédiction : {{}}. There's also a form that posts a prediction to the /predict route.

    Finally, you're ready to build the python file that drives the consumption of the model and the display of predictions:

  9. In app.py ajoutez :

    import numpy as np
    from flask import Flask, request, render_template
    import pickle
    
    app = Flask(__name__)
    
    model = pickle.load(open("./ufo-model.pkl", "rb"))
    
    
    @app.route("/")
    def home():
        return render_template("index.html")
    
    
    @app.route("/predict", methods=["POST"])
    def predict():
    
        int_features = [int(x) for x in request.form.values()]
        final_features = [np.array(int_features)]
        prediction = model.predict(final_features)
    
        output = prediction[0]
    
        countries = ["Australia", "Canada", "Germany", "UK", "US"]
    
        return render_template(
            "index.html", prediction_text="Likely country: {}".format(countries[output])
        )
    
    
    if __name__ == "__main__":
        app.run(debug=True)
    

    💡 Astuce : lorsque vous ajoutez debug=True while running the web app using Flask, any changes you make to your application will be reflected immediately without the need to restart the server. Beware! Don't enable this mode in a production app.

If you run python app.py or python3 app.py - your web server starts up, locally, and you can fill out a short form to get an answer to your burning question about where UFOs have been sighted!

Before doing that, take a look at the parts of app.py:

  1. First, dependencies are loaded and the app starts.
  2. Then, the model is imported.
  3. Then, index.html is rendered on the home route.

On the /predict route, several things happen when the form is posted:

  1. The form variables are gathered and converted to a numpy array. They are then sent to the model and a prediction is returned.
  2. The Countries that we want displayed are re-rendered as readable text from their predicted country code, and that value is sent back to index.html to be rendered in the template.

Using a model this way, with Flask and a pickled model, is relatively straightforward. The hardest thing is to understand what shape the data is that must be sent to the model to get a prediction. That all depends on how the model was trained. This one has three data points to be input in order to get a prediction.

In a professional setting, you can see how good communication is necessary between the folks who train the model and those who consume it in a web or mobile app. In our case, it's only one person, you!


🚀 Challenge

Instead of working in a notebook and importing the model to the Flask app, you could train the model right within the Flask app! Try converting your Python code in the notebook, perhaps after your data is cleaned, to train the model from within the app on a route called train. Quels sont les avantages et les inconvénients de cette méthode ?

Quiz après le cours

Révision & Auto-apprentissage

Il existe de nombreuses façons de construire une application web pour consommer des modèles ML. Faites une liste des façons dont vous pourriez utiliser JavaScript ou Python pour construire une application web exploitant l'apprentissage automatique. Considérez l'architecture : le modèle doit-il rester dans l'application ou vivre dans le cloud ? Si c'est le cas, comment y accéderiez-vous ? Dessinez un modèle architectural pour une solution web ML appliquée.

Devoir

Essayez un modèle différent

Avertissement :
Ce document a été traduit à l'aide de services de traduction automatique basés sur l'IA. Bien que nous nous efforçons d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue native doit être considéré comme la source autorisée. Pour des informations critiques, une traduction humaine professionnelle est recommandée. Nous ne sommes pas responsables des malentendus ou des interprétations erronées résultant de l'utilisation de cette traduction.