[PYTHON] Les prévisions épidémiques du nouveau virus corona ont été publiées sur le Web à une vitesse explosive

Cet article se présente également sous la forme de Article publié sur le blog officiel du Yotsuya Lab.

Si vous le souhaitez, veuillez également consulter le Blog de Yotani Lab.

Auparavant, il y avait un article publié par M. Yamashin. C'est un article très intéressant qui estime les paramètres pour dessiner le modèle SEIR à partir de la transition actuelle du nombre de personnes infectées et prédit le nombre de cas dans le futur.

Estimer le nombre de personnes infectées par le nouveau virus corona à l'aide d'un modèle mathématique

Contexte

En lisant cet article, je me suis dit "Oh, c'est incroyable. J'aimerais que tout le monde puisse le voir quand il voudra" et j'ai sérieusement pensé à le publier sur le WEB. Le script de prédiction est écrit en Python. J'ai dû configurer Python sur mon PC pour voir les images. Aussi, je dois mettre dans une bibliothèque et préparer un environnement pour la série Python3 ... Oh, c'est ennuyeux! !! !! C'est un secret qui est devenu.

En conséquence, je l'ai fait. Cliquez ici pour les services ouverts au public. À partir de l'URL suivante. Prédiction d'une nouvelle infection par le virus corona COVID-19

Afin d'exécuter le script et d'obtenir les dernières données, il est nécessaire de télécharger le CSV source à partir de Kaggle à chaque fois. De plus, le moment de la mise à jour est différent, il est donc assez difficile de le voir une fois par jour. J'exécutais le script à chaque fois que je l'obtenais.

En fait, M. Yamashin, j'ai également remplacé chaque jour l'image de l'article du blog. Le saviez-vous ...?

Je voulais aussi voir les dernières données, mais il était difficile de créer l'environnement. (Les ingénieurs sont des morceaux ennuyeux. Ce sont des démons. Je ne pense qu'aux choses ennuyeuses. Tout d'abord, nous avons configuré un environnement Docker pour exécuter ce script. Qu'il s'agisse d'un PC domestique ou d'un PC d'entreprise ...

Pour voir, je me connectais en SSH à mon VPS à partir d'un train de navette et en appuyant sur les commandes. Mais comme prévu, je suis fatigué ou agacé ...

C'est pourquoi nous avons publié la prévision d'épidémie de virus Corona que tout le monde peut consulter sur le Web!

Cette fois, je voudrais parler de ce que j'ai pensé de la publication et de la manière de l'implémenter.

Sélection de technologie

De l'histoire de la technologie utilisée. Le but de ce temps est le suivant.

  1. Obtenez régulièrement les dernières données
  2. Je souhaite exécuter automatiquement un script de calcul
  3. Je veux un environnement qui puisse être visualisé à tout moment en affichant des graphiques ou en diffusant des images sur le Web.

Afin de répondre à ces exigences, nous avons décidé de les effacer un par un.

Le référentiel est ouvert au public ici.

https://github.com/428lab/new_coronavirus_infection

Puisque j'utilise Python, c'est django ou Flask ainsi que du côté serveur, non? Je t'y pensais! !! C'est une bonne décision! Je voulais aussi l'utiliser. Mais cette fois c'est différent! !!

Les scripts Python ne fonctionnent pas aussi bien que prévu. Non, je faisais mon travail principal. Le travail consiste à sortir la feuille json des données de vérification. Ensuite, pour construire ce système, quel est l'ordre de la distribution automatique et comment y parvenir?

Je vais vous expliquer étape par étape.

  1. Utilisez l'environnement Docker pour unifier l'environnement de développement
  2. Cliquez sur l'API de Kaggle pour obtenir le dernier Covid-19.CSV (Bash)
  3. Définissez le nom du pays et la population de chaque pays (Python)
  4. Produisez un fichier JSON formaté pour être facile à utiliser sur le Web (Python)
  5. Lisez le fichier JSON et affichez-le dans Chart.js. (Nuxt)
  6. Téléchargez dans le répertoire public du serveur (Bash)
  7. Économie de main-d'œuvre sur les coûts d'exploitation et l'automatisation du serveur (exécution de Cron avec VPS)

En fait, compte tenu du coût de maintenance, les fonctions sont divisées par chaque facteur. Ce n'est pas très complimenté car il est fait, et bien que cela puisse être assez lourd dans certaines parties, nous sélectionnons activement la technologie à laquelle les personnes impliquées sont habituées afin de prioriser la divulgation.

Raisons de la sélection de chaque technologie

Je voudrais parler un peu des raisons du choix de la technologie. C'était un système conçu pour ne pas être lié par la configuration de plusieurs langues et environnements. Je pense que la bonté de faire demi-tour lors du développement d'un produit aussi petit peut également être utilisé comme matériau pour des projets.

Utilisation de Docker

J'ai utilisé Docker cette fois parce que je voulais unifier au maximum l'environnement de développement de chaque individu. L'article publié l'autre jour est Python, mais selon l'environnement de développement, il peut être exécuté avec des commandes Python, ou coexister avec Python 3. De plus, il est difficile de sélectionner et de créer une bibliothèque pour chaque projet comme Node.js, et il est également nécessaire de créer Pyenv.

Cependant, j'ai choisi Docker car il peut résoudre ces problèmes liés à l'environnement et créer une situation où mon environnement de développement personnel n'est pas pollué. D'ailleurs, j'utilise Docker-compose en supposant qu'il sera plus facile à maintenir et que le nombre de conteneurs augmentera.

Sortie dans un fichier JSON

Quant au code Python, M. Yamashin a déjà été mentionné dans l'article précédent, je vais donc omettre l'explication ici. Quand j'ai pensé à cette sortie de données, j'ai réfléchi à la manière de transmettre efficacement les données au WEB. Si vous exportez autant que vous le pouvez sur les données, le côté WEB peut laisser le choix d'utiliser ou non. Cette fois-ci, en ce qui concerne l'échelle des données, nous avons regroupé les valeurs réelles et prévues par pays, et en même temps, nous avons permis d'enregistrer quand même, en laissant l'heure au moment de la sortie. Étant donné que les valeurs numériques des données de sortie utilisent le tableau qui est inséré lorsque le graphique est généré, l'implémentation elle-même est très simple.

    def plot_bar(self, ax):
        width = 0.5
        #Initialisation de type dictionnaire
        self.graph["fact"] = dict()
        self.graph["fact"]["infected"] = dict()
        self.graph["fact"]["recovered"] = dict()
        self.graph["fact"]["deaths"] = dict()

        for day, infected, recovered, deaths in zip(self.timestamp, self.infected, self.recovered, self.deaths ):
            bottom = 0
            ax.bar(day, infected, width, bottom, color='red', label='Infectious')
            #Ajouté aux données de sortie du graphique
            self.graph["fact"]["infected"][day.strftime("%Y/%m/%d")] = infected
            bottom += infected
            ax.bar(day, recovered, width, bottom, color='blue', label='Recovered')
            #Ajouté aux données de sortie du graphique
            self.graph["fact"]["recovered"][day.strftime("%Y/%m/%d")] = recovered
            bottom += recovered
            ax.bar(day, deaths, width, bottom, color='black', label='Deaths')
            #Ajouté aux données de sortie du graphique
            self.graph["fact"]["deaths"][day.strftime("%Y/%m/%d")] = deaths
            bottom += deaths

        ax.set_ylabel('Confirmed infections',fontsize=20)
        handler, label = ax.get_legend_handles_labels()
        ax.legend(handler[0:3] , label[0:3], loc="upper left", borderaxespad=0. , fontsize=20)

        return 

    def plot_estimation(self, ax, estimatedParams):
        day = self.timestamp[0]
        day_list = []
        max = 0
        #Initialisation de type dictionnaire (personne infectée prédite)
        self.graph["estimation"] = dict()

        estimated_value_list = []
        for estimated_value in self.estimate4plot(estimatedParams.x[0])[:,2]:
            if max < estimated_value:
                max = estimated_value
                peak = (day, estimated_value)

            day_list.append(day)
            estimated_value_list.append(estimated_value)
            day += datetime.timedelta(days=1) 
            if estimated_value < 0:
                break
        ax.annotate(peak[0].strftime('%Y/%m/%d') + ' ' + str(int(peak[1])), xy = peak, size = 20, color = "black")
        ax.plot(day_list, estimated_value_list, color='red', label="Estimation infection", linewidth=3.0)

        #Jetez la prédiction des personnes infectées
        self.graph["estimation"]["infection"] = estimated_value_list

        day = self.timestamp[0]
        day_list = []
        estimated_value_list = []
        for estimated_value in self.estimate4plot(estimatedParams.x[0])[:,3]:
            day_list.append(day)
            estimated_value_list.append(estimated_value)
            day += datetime.timedelta(days=1) 
            if estimated_value < 0:
                break
        ax.plot(day_list, estimated_value_list, color='blue', label="Estimation recovered", linewidth=3.0)

        #Poussez la prédiction de récupération
        self.graph["estimation"]["recovered"] = estimated_value_list

        day = self.timestamp[0]
        day_list = []
        estimated_value_list = []
        for estimated_value in self.estimate4plot(estimatedParams.x[0])[:,4]:
            day_list.append(day)
            estimated_value_list.append(estimated_value)
            day += datetime.timedelta(days=1) 
            if estimated_value < 0:
                break
        ax.plot(day_list, estimated_value_list, color='black', label="Estimation deaths", linewidth=3.0)

        #Lancer une prédiction mortelle
        self.graph["estimation"]["deaths"] = estimated_value_list

        ax.set_ylim(0,)

        handler, label = ax.get_legend_handles_labels()
        ax.legend(handler[0:6] , label[0:6], loc="upper right", borderaxespad=0. , fontsize=20)

        return


Après cela, sortez simplement le type de dictionnaire plongé tel quel. Le JSON de sortie est implémenté pour être des données en premier, comme indiqué ci-dessous. Il reconnaît cela comme un objet Javascript.

{
    "fact": {
        "infected": {
            "2020/01/22": 2,
            "2020/01/23": 1,
            "2020/01/24": 1,
        },
        "recovered": {
            "2020/01/22": 0,
            "2020/01/23": 0,
            "2020/01/24": 0,
        },
        "deaths": {
            "2020/01/22": 0,
            "2020/01/23": 0,
            "2020/01/24": 0,
        }
    },
    "estimation": {
        "infection": [
            1.0,
            1.001343690430807,
            1.057149907444775,
            1.1604873710493135,
            1.3082809855652382,
            1.500433415450257,
            1.7392685227686018,
            2.0292066531306356,
        ],
        "recovered": [
            0.0,
            0.02712800489579143,
            0.05505548053170182,
            0.0851617724612349,
            0.1186923604385037,
            0.15685109117056692,
            0.20087311338956979,
            0.2520859691391483,
        ],
        "deaths": [
            0.0,
            0.0021553841476101903,
            0.004374288136297892,
            0.0067663042324873765,
            0.009430388748244232,
            0.012462190151582021,
            0.015959843930437784,
            0.02002882643985976,
        ]
    }
}

De plus, la destination de sortie est enregistrée dans le dossier de sauvegarde avec la date et l'heure, et les données principales sont sorties dans le dossier Assets de Nuxt. Le côté Nuxt vise un moyen de faire en sorte que vous n'ayez pas à être au courant de cette sortie.

Sélection de la langue sur la face avant WEB

Comme je l'ai mentionné précédemment, j'utilise Nuxt.js, un framework JavaScript, pour créer ce site Web. Il y a plusieurs raisons de le choisir, mais si Vue.js est laissé tel quel, je dois souvent le faire aussi, donc cette fois j'ai passé un peu. Et je suis arrivé à Nuxt.js.

En livrant statiquement avec Nuxt, le coût de dessin côté utilisateur et la charge au moment du rendu côté serveur sont réduits. Parce que j'ai peur de la facturation! !! !!

Il n'y a pas de description des éléments techniques ici, mais je n'ai pas pu passer beaucoup de temps sur la conception et la mise en page, j'ai donc utilisé Bootstrap pour le simplifier. De plus, nous privilégions l'utilisation d'images uniquement pour les articles partagés sur Facebook et Twitter, en visant un mécanisme aussi simple que possible à partager.

(En fait, la zone OGP est également assez bien mise en œuvre.)

Les lignes de pliage et les graphiques à barres ne sont modifiés que dans les nuances de couleur, mais les résultats et les prévisions accumulés sont rendus aussi faciles que possible à juger. Étant donné que la date sur l'axe X devient très fine, j'ai décidé de sortir les dates de pointe et maximum séparément. Il semble toujours plat, donc c'est un point d'amélioration.

Exécuter sur VPS ou serveur avec Bash

Fondamentalement, toutes les opérations sur les fichiers sont scriptées dans Bash. Il n'y a aucune raison pour que ce soit si difficile, mais avec Bash, il est facile de l'exécuter dans Cron, et vous pouvez frapper des commandes comme la génération de fil. En bref, l'opération de libération est terminée avec juste cela. Cette fois, l'échelle est petite, et essentiellement ce que nous faisons est un traitement par lots, nous utilisons donc cette procédure de l'acquisition à l'exécution du fichier ZIP.

Il vaut la peine de se rappeler que Cron frappe juste une exécution automatique et que toute l'exécution réelle est dans le script Shell.

Au fait, le serveur VPS est emprunté à Mixhost cette fois.

https://mixhost.jp/

Actuellement, Mixhost dispose d'un système pour prendre en charge la distribution de contenu lié au virus corona. En empruntant ce service, nous empruntons également des VPS gratuitement pour publication. J'ai réalisé que la mémoire à 6 cœurs était très bénie avec un environnement de 8 Go et un SSD de 500 Go. Être gros! !! !!

https://mixhost.jp/news/432

Résumé

Avec cela, j'ai pu le présenter au public deux jours après avoir commencé à le faire sérieusement. Après cela, j'ai répété des modifications détaillées, mais cette fois j'ai créé un site sans être particulier sur le design, donnant la priorité à la publication. Si vous souhaitez élaborer sur la conception ou toucher le code côté Python, veuillez accéder au référentiel suivant.

https://github.com/428lab/new_coronavirus_infection

Recommended Posts

Les prévisions épidémiques du nouveau virus corona ont été publiées sur le Web à une vitesse explosive
Tracez la propagation du nouveau virus corona
Estimer le pic d'infectivité du nouveau virus corona
Folding @ Home sur Linux Mint pour contribuer à l'analyse du nouveau virus corona
Résumez le titre de Hottentori dans Hateb et regardez le présent du Web
Au moment de la mise à jour de python avec ubuntu
Simulation GUI du nouveau virus corona (modèle SEIR)
Jusqu'à la sortie de l'application Web avec Sakura VPS
Tweetez le triple pronostic de la course de bateaux sur Twitter
Tâches au démarrage d'un nouveau projet python
J'ai analysé les tweets sur le nouveau virus corona publiés sur Twitter
Créez un serveur Web API à une vitesse explosive en utilisant HUG
Résumé de l'exploration d'image effectuée à la vitesse d'une seconde
Quantifier le degré d'autolimitation nécessaire pour contenir le nouveau virus corona