J'ai créé une application d'apprentissage automatique avec Dash (+ Docker) part3 ~ Practice ~

introduction

J'ai créé une application d'apprentissage automatique simple en utilisant le framework d'application Web de Python Dash, j'ai donc écrit cet article comme un enregistrement d'apprentissage (le livrable est ici /)). Ce qui précède (partie 2) a introduit la mise en page et le rappel, qui sont les bases de la création d'applications Dash. Dans cet article, je voudrais présenter certaines des applications que j'ai réellement créées comme exemples d'application. Comme indiqué ci-dessous, implémentez une application qui affiche le résultat de l'analyse sélectionné par la case à cocher pour les données du tableau. スクリーンショット 2020-11-13 11.06.15.png Veuillez consulter ici (part1) pour l'environnement d'exploitation. De plus, dans cet article, Pandas est utilisé pour le traitement des données, mais je pense que vous pouvez le lire presque sans problème, même si vous ne connaissez pas les Pandas.

Préparation

Dans l'application que j'ai créée, j'ai ajouté une fonction pour télécharger des fichiers csv, etc., mais cette fois, je vais lire directement les données préparées. Pour la partie sample_data.csv, essayez d'utiliser vos données de table préférées d'une taille appropriée (il est préférable d'avoir deux ou plusieurs variables numériques pour implémenter un diagramme de paires). Cet article utilise les données de compétition Titanic de Kaggle (train.csv).

<Structure du répertoire>
Dash_App/
  ├ sample_data.csv
  ├ app.py
  ├ Dockerfile
  └ docker-compose.yml

Les parties autres que Layout et Callback doivent être les suivantes.

app.py


import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
import pandas as pd
import plotly.express as px
import plotly.figure_factory as ff

#Lire les données
data = pd.read_csv('src/sample_data.csv')

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
################################################################
Partie de mise en page
################################################################
################################################################
Partie de rappel
################################################################

if __name__ == '__main__':
    app.run_server(host='0.0.0.0', port=5050, debug=True)

Création de la partie Layout

Cette fois, j'essaierai d'utiliser des cases à cocher (dcc.RadioItems ()) et des boutons (html.Button ()). L'exemple de code se trouve sur le Site officiel, donc je pense que c'est une bonne idée de trouver ce que vous voulez utiliser et de copier l'exemple pour l'implémenter. .. Par exemple, si vous regardez l'exemple de code de dcc.RadioItems (), il ressemble à ce qui suit. スクリーンショット 2020-11-13 13.25.35.png Si vous regardez, vous pouvez voir que les options sont définies avec l'argument options, et label (texte affiché) et valeur sont spécifiés pour chaque option. De plus, comme «Montréal» est vérifié suite à la spécification de «MLT» dans l'argument suivant «valeur», la valeur initiale peut être définie dans l'argument «valeur» et la valeur sélectionnée par l'opération d'interface utilisateur est «valeur. Vous pouvez imaginer que le `sera écrasé (bien qu'il soit beaucoup plus rapide de le vérifier en le déplaçant que de le lire ...). Tout en imitant l'exemple de code, j'ai créé la partie Layout comme suit. La valeur initiale de «valeur» n'a pas été définie et l'option définie «valeur» a été définie sur «AAA», «BBB» et «CCC» pour une meilleure compréhension.

app.py


app.layout = html.Div(children=[

    html.H3('Step5:Analyse des variables numériques'),
    html.H5('Sélectionnez une méthode d'analyse et appuyez sur Exécuter'),
    #Partie case à cocher
    dcc.RadioItems(
        id='num_analysis_selection',
        options=[
            {'label': 'Liste des statistiques', 'value': 'AAA'},
            {'label': 'Parcelle de paires', 'value': 'BBB'},
            {'label': 'Matrice de corrélation', 'value': 'CCC'}
        ]
    ),
    #Partie bouton
    html.Button(id="num_analysis-button", n_clicks=0, children="Courir", style={'background': '#DDDDDD'}),
    #La partie qui affiche le résultat
    html.Div(id='num_result')
])

Si vous démarrez l'application dans cet état, elle s'affichera comme ci-dessous. Bien sûr, comme c'est le cas maintenant, rien ne se passe lorsque vous appuyez sur le bouton, je voudrais donc commencer à déplacer avec Callback à partir de la section suivante. スクリーンショット 2020-11-13 14.01.40.png

Partie de rappel

Contrôle de fonctionnement

Ensuite, j'écrirai la partie Callback. Avant d'utiliser les données, commençons par une simple vérification des opérations. Sous la partie Layout de app.py, écrivez Callback comme suit.

app.py


@app.callback(
    Output(component_id='num_result', component_property='children'),
    [Input(component_id='num_analysis_selection', component_property='value')]
)
def num_analysis(input):
    return input

Si vous exécutez l'application dans cet état, vous pouvez voir que la valeur de valeur de l'option cochée est affichée sous le bouton. [Ce qui précède (part2)] Ceci est un examen de (), mais le mouvement est le suivant: ① La valeur de valeur de dc.ReadItems () spécifiée dans Input est l'argument (input) de la fonctionnum_analysis () (2) La valeur de retour (input) de cette fonction est transmise à l'argument children dehtml.Div (id = 'num_result')spécifié dans Output. スクリーンショット 2020-11-13 14.13.56.png Après avoir confirmé le mouvement, j'aimerais utiliser les données réellement lues. Cette fois, un traitement différent est effectué en fonction du contenu sélectionné, de sorte que le branchement conditionnel est effectué avec l'instruction if en utilisant la valeur d'entrée.

Table à dessin

Tout d'abord, j'écrirai le traitement lorsque "Liste des statistiques" est sélectionné. Plus précisément, je voudrais dessiner un tableau des résultats de l'exécution de la méthode describe () dans Pandas. J'ai entendu comment dessiner un tableau avec Dash, mais ici j'utiliserai le plus simple html.Table. Si vous jetez un œil à l 'Exemple de code du didacticiel officiel, スクリーンショット 2020-11-13 15.33.06.png C'est un peu compliqué, mais il semble que je crée une fonction appelée generate_table (). Cette fois, je l'ai implémenté comme ci-dessous en utilisant la partie retour de cette fonction.

app.py


@app.callback(
    Output(component_id='num_result', component_property='children'),
    [Input(component_id='num_analysis_selection', component_property='value')]
)
def num_analysis(input):
    if input == 'AAA':
        describe = data.describe()
        return html.Table([
            html.Thead(
                html.Tr([html.Th(col) for col in describe.columns])
            ),
            html.Tbody([
                html.Tr([
                    html.Td(describe.iloc[i][col]) for col in describe.columns
                ]) for i in range(len(describe))
            ])
        ])

Si vous sélectionnez "Liste des statistiques", vous devriez être en mesure de dessiner le tableau comme indiqué ci-dessous. スクリーンショット 2020-11-13 15.59.30.png

Dessinez un diagramme tracé

Ensuite, nous implémenterons des graphiques de paires et un dessin de matrice de corrélation (carte thermique). La meilleure chose à propos de Dash est que vous pouvez utiliser les diagrammes interactifs et sympas de Plotly, donc je vais le rechercher sur le site officiel de Plotly. Puisque le flux de base est le même, nous ne regarderons que le diagramme de paires. スクリーンショット 2020-11-13 16.12.27.png La façon de dessiner un tracé de Plotly avec Dash est essentiellement de passer de fig.show () dans Plotly à dcc.Graph (figure = fig). Ensuite, nous allons également implémenter la partie carte thermique.

app.py


@app.callback(
    Output(component_id='num_result', component_property='children'),
    [Input(component_id='num_analysis_selection', component_property='value')]
)
def num_analysis(input):
    #Dessiner une liste de statistiques
    if input == 'AAA':
        describe = data.describe()
        return html.Table([
            html.Thead(
                html.Tr([html.Th(col) for col in describe.columns])
            ),
            html.Tbody([
                html.Tr([
                    html.Td(describe.iloc[i][col]) for col in describe.columns
                ]) for i in range(len(describe))
            ])
        ])
    #Dessiner un diagramme de paires
    elif input == 'BBB':
        fig = px.scatter_matrix(
            data, 
            dimensions=['Pclass', 'Age', 'Parch', 'Fare'], 
            color='Survived'
        )
        return dcc.Graph(figure=fig)

    #Dessin du coefficient de corrélation (carte thermique)
    elif input == 'CCC':
        corr = data[['Pclass', 'Age', 'Parch', 'Fare']].corr().round(4)
        fig = ff.create_annotated_heatmap(
            z=corr.values, 
            x=list(corr.columns),
            y=list(corr.index), 
            colorscale='Oranges',
            hoverinfo='none'
        )
        return dcc.Graph(figure=fig)

Vous devriez maintenant être en mesure de dessiner des graphiques de paires et des matrices de corrélation.

Utiliser l'état pour faire fonctionner le bouton

Une dernière étape. À ce stade, le dessin du diagramme commence au moment où vous le sélectionnez avec la case à cocher et le bouton d'exécution ci-dessous ne fonctionne pas. Nous modifierons cela pour que le résultat soit reflété en appuyant sur le bouton d'exécution après l'avoir sélectionné. Pour ce faire, nous utiliserons une fonctionnalité appelée State in Callback. Mettez en commentaire l'instruction if et ci-dessous une fois, et modifiez la partie Callback comme indiqué ci-dessous.

app.py


@app.callback(
    Output(component_id='num_result', component_property='children'),
    [Input(component_id='num_analysis-button', component_property='n_clicks')],
    [State(component_id='num_analysis_selection', component_property='value')]
)
def num_analysis(n_clicks, input):
    return 'n_clicks:{}, input:{}'.format(n_clicks, input)

J'ai spécifié un bouton pour Input et réécrit la case à cocher qui était à l'origine Input to State. En faisant cela, la partie spécifiée par State ne sera pas reflétée lorsqu'il y a une action, mais sera reflétée en même temps lorsqu'il y a une action dans la partie spécifiée par Input. Notez qu'il y a deux arguments passés à la fonction: dérivé du bouton (n_clicks) et dérivé de la case à cocher ( input). Au fait, n_clicks est le nombre de fois que le bouton a été enfoncé. Si vous essayez de démarrer l'application dans l'état ci-dessus, la valeur de n_clicks augmentera chaque fois que vous appuyez sur le bouton d'exécution, et vous pouvez voir que l'entrée contient'AAA'etc. スクリーンショット 2020-11-13 18.25.08.png Maintenant que vous comprenez comment fonctionne State, retournez le contenu de la fonction num_analysis (n_clicks, input) à l'instruction if et ci-dessous. Je n'utilise pas n_clicks cette fois, donc c'est tout. Enfin, je publierai à nouveau le code complété.

app.py


import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
import pandas as pd
import plotly.express as px
import plotly.figure_factory as ff

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

data = pd.read_csv('src/dash/titanic_train.csv')

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div(children=[

    html.H3('Step5:Analyse des variables numériques'),
    html.H5('Sélectionnez une méthode d'analyse et appuyez sur Exécuter'),
    #Partie case à cocher
    dcc.RadioItems(
        id='num_analysis_selection',
        options=[
            {'label': 'Liste des statistiques', 'value': 'AAA'},
            {'label': 'Parcelle de paires', 'value': 'BBB'},
            {'label': 'Matrice de corrélation', 'value': 'CCC'}
        ]
    ),
    #Partie bouton
    html.Button(id="num_analysis-button", n_clicks=0, children="Courir", style={'background': '#DDDDDD'}),
    #La partie qui affiche le résultat
    html.Div(id='num_result')
])
@app.callback(
    Output(component_id='num_result', component_property='children'),
    [Input(component_id='num_analysis-button', component_property='n_clicks')],
    [State(component_id='num_analysis_selection', component_property='value')]
)
def num_analysis(n_clicks, input):
    if input == 'AAA':
        describe = data.describe()
        return html.Table([
            html.Thead(
                html.Tr([html.Th(col) for col in describe.columns])
            ),
            html.Tbody([
                html.Tr([
                    html.Td(describe.iloc[i][col]) for col in describe.columns
                ]) for i in range(len(describe))
            ])
        ])
    #Dessiner un diagramme de paires
    elif input == 'BBB':
        fig = px.scatter_matrix(
            data, 
            dimensions=['Pclass', 'Age', 'Parch', 'Fare'], 
            color='Survived'
        )
        return dcc.Graph(figure=fig)
    
    #Dessin du coefficient de corrélation (carte thermique)
    elif input == 'CCC':
        corr = data[['Pclass', 'Age', 'Parch', 'Fare']].corr().round(4)
        fig = ff.create_annotated_heatmap(
            z=corr.values, 
            x=list(corr.columns),
            y=list(corr.index), 
            colorscale='Oranges',
            hoverinfo='none'
        )
        return dcc.Graph(figure=fig)
        

if __name__ == '__main__':
    app.run_server(host='0.0.0.0', port=5050, debug=True)

en conclusion

En version pratique, nous avons implémenté une application simple d'analyse de données de table. Lors de la création d'une application pour l'apprentissage automatique ou l'analyse de données, la plupart du travail est répété comme cette fois, "Traitement des données avec Pandas ou Scikit-learn → Passer des valeurs pour correspondre à Dash ou Plotly", donc diverses choses S'il vous plaît essayez. Dans le prochain article (dernier), j'aimerais vous montrer comment déployer votre application sur Heroku à l'aide de Docker. Cela fait longtemps, mais merci.

Recommended Posts

J'ai créé une application d'apprentissage automatique avec Dash (+ Docker) part3 ~ Practice ~
J'ai créé une application d'apprentissage automatique avec Dash (+ Docker) part2 ~ Façon basique d'écrire Dash ~
J'ai essayé de créer une application d'apprentissage automatique avec Dash (+ Docker) part1 ~ Construction de l'environnement et vérification du fonctionnement ~
[iOS] J'ai essayé de créer une application de traitement de type insta avec Swift
J'ai essayé de moderniser une application Java EE avec OpenShift.
J'ai essayé de créer un environnement de développement padrino avec Docker
J'ai essayé de créer une application Android avec MVC maintenant (Java)
J'ai essayé de créer une fonction de groupe (babillard) avec Rails
J'ai essayé de créer une simple application Android de reconnaissance faciale en utilisant OpenCV
J'ai essayé de faire une sauvegarde automatique avec plus agréable + PostgreSQL + SSL + docker
J'ai essayé de créer une API Web qui se connecte à DB avec Quarkus
J'ai essayé de créer une application de conversation en Java à l'aide de l'IA «A3RT»
J'ai essayé de faire une authentification de base avec Java
J'ai essayé de casser le bloc avec java (1)
J'ai essayé de créer un portefeuille avec AWS, Docker, CircleCI, Laravel [avec lien de référence]
J'ai essayé de faire un jeu simple avec Javafx ① "Trouvons le jeu du bonheur" (inachevé)
[Android] J'ai créé un écran de liste de matériaux avec ListView + Bottom Sheet
J'ai essayé de cloner une application Web pleine de bugs avec Spring Boot
J'ai essayé de créer une fonction de connexion avec Java
[Apprentissage automatique] J'ai essayé la détection d'objets avec Create ML [détection d'objets]
Rails6 J'ai essayé d'introduire Docker dans une application existante
J'ai essayé de faire un jeu simple avec Javafx ① "Trouvons le jeu du bonheur" (version inachevée ②)
J'ai essayé de créer une fonction de message de l'extension Rails Tutorial (Partie 1): Créer un modèle
Introduction à l'apprentissage automatique avec Spark "Estimation de prix" # 3 Apprenons avec les données d'entraînement et créons un [moteur d'estimation de prix]
J'ai essayé BIND avec Docker
[Azure] J'ai essayé de créer une application Java gratuitement ~ Se connecter avec FTP ~ [Débutant]
J'ai essayé de faire une demande en 3 mois d'inexpérimenté
J'ai essayé de créer un environnement de développement java8 avec Chocolatey
[Rails] J'ai essayé de créer une mini application avec FullCalendar
Je veux faire une liste avec kotlin et java!
Je veux créer une fonction avec kotlin et java!
Apprendre Ruby avec AtCoder 13 Comment créer un tableau à deux dimensions
J'ai essayé d'implémenter une application web pleine de bugs avec Kotlin
J'ai créé un client RESAS-API en Java
J'ai essayé OCR de traiter un fichier PDF avec Java part2
J'ai essayé de faire une fonction de réponse de l'extension Rails Tutorial (Partie 3): Correction d'un malentendu des spécifications
J'ai essayé de convertir l'exemple d'application en microservice selon l'idée du livre "Microservice Architecture".
J'ai essayé de développer une application web à partir d'un mois et demi d'histoire d'apprentissage de la programmation
Facile à créer LINE BOT avec Java Servlet Partie 2: J'ai essayé des messages image et des modèles
J'ai essayé de créer une fonction de message pour l'extension Rails Tutorial (Partie 2): Créer un écran à afficher
J'ai essayé d'interagir avec Java
J'ai essayé de résumer l'apprentissage Java (1)
Créons une application Web de gestion de livres avec Spring Boot part1
Je veux créer un bouton avec un saut de ligne avec link_to [Note]
J'ai essayé d'exécuter une application d'échange de cartes de crédit avec Corda 1
Créons une application Web de gestion de livres avec Spring Boot part3
J'ai essayé de créer un environnement de serveur UML Plant avec Docker
Faisons une application multiplateforme avec JRuby (génération de fichier jar)
[Unity] J'ai essayé de créer un plug-in natif UniNWPathMonitor en utilisant NWPathMonitor
Créons une application Web de gestion de livres avec Spring Boot part2
Créer un compilateur C à utiliser avec Rust x CLion avec Docker
J'ai essayé de créer une application simple en utilisant Dockder + Rails Scaffold
[Java] J'ai essayé de faire un labyrinthe par la méthode de creusage ♪
[Rails] Implémentation de la fonction de catégorie multicouche en utilisant l'ascendance "J'ai essayé de créer une fenêtre avec Bootstrap 3"
Après avoir appris Progate, j'ai essayé de créer une application SNS en utilisant Rails dans l'environnement local