[PYTHON] Prédire l'avenir des tendances démographiques dans la ville de Numazu par analyse de régression chronologique à l'aide de Prophet

Chose que tu veux faire

・ Prédisez la population future de Numazu City en vous basant sur les données démographiques des dernières années avec la bibliothèque de prédictions chronologiques de Python "Facebook Prophet" ・ Évaluer les résultats de l'analyse ⇒ Réglage ⇒ Réanalyser

environnement

** Windows10 64bit** ** Anaconda3** Environnement virtuel: python (3.7.3) Bibliothèques: fbprophet (0.6), pandas (1.1.2), matplotlib (3.0.3)

Des données d'utilisation

Liste de la population et des ménages de la ville de Numazu

-Utiliser la population mensuelle agrégée des fichiers annuels sur le site ci-dessus comme fichier d'entrée ** [dataset.csv] **. ・ À l'origine, il existe un rapport démographique dans les données ouvertes de Numazu City. Catalogue de données ouvertes Fuji no Kuni (Numazu City) Ce sont des statistiques annuelles, mais comme nous avons supposé mensuellement la granularité des données pour l'analyse des séries chronologiques, Cette fois, nous utiliserons les informations du registre de base des résidents sur le site Web officiel de la ville, qui contient des données mensuelles. -A titre de compensation, le formatage du PDF au tableur est nécessaire. C'était gênant. ・ Il est composé de deux rangées d'année, de mois et de personnel domestique. Puisqu'il s'agit d'un essai, il n'y a pas de variables externes. ・ 2013 / 04-2020 / 08 seront les données d'apprentissage.

dataset.csv

Année mois Personnel domestique (total)
2013-04 205,790
2013-05 205,739
2013-06 205,572
・ ・ ・ ・ ・ ・
2020-07 193,896
2020-08 193,756

Analyse prédictive

Importer la bibliothèque

import pandas as pd
import matplotlib.pyplot as plt
from fbprophet import Prophet

Capture de données

Jinkoudata = pd.read_csv("dataset.csv")
Jinkoudata.columns = ['ds','y']

-Importer les données de population dans la base de données [données Jinkou]. -Changez les noms des colonnes [année / mois] et [personnel domestique (total)] en [ds] [y] respectivement (selon la convention de dénomination du prophète).

Génération de modèle

model = Prophet(weekly_seasonality=False,daily_seasonality=False)

・ Puisque l'analyse est effectuée sur une base mensuelle cette fois, les paramètres qui ne tiennent pas compte du cycle hebdomadaire et du cycle quotidien sont spécifiés. -En outre, les paramètres suivants peuvent être spécifiés arbitrairement lors de la création d'une instance. Valeurs des paramètres entre []. La valeur spécifiée à titre d'exemple est la valeur par défaut.

●growth='linear' [logistic/linear] Spécifiez le modèle d'analyse comme linéaire ou logistique.

●changepoints=None [DATE(YYYY-MM-DD)] Désignation arbitraire des points de changement des tendances (fluctuations de tendance à long terme). Dans prophet, les points de changement sont automatiquement extraits et reflétés dans la prédiction, mais au lieu d'utiliser la détection automatique des points de changement si nécessaire, Il est utilisé avec l'intention de spécifier manuellement l'emplacement des points de changement potentiels à l'aide de ce paramètre.

** ● n_changepoints ** = 25 [constante arbitraire] Spécifiez le nombre de candidats de point de changement à détecter. Plus la valeur est élevée, plus il est facile de détecter de nombreux points de changement. Si cela est trop grand, les points de changement peuvent être détectés de manière excessive et la précision de la prévision peut chuter.

** ● year_seasonality ** = 'auto' [true / false / auto / arbitrary constant] Précisez la périodicité (année). Le degré de considération peut être ajusté en spécifiant un nombre arbitraire (10 est la valeur spécifiée si elle n'est pas spécifiée).

** ● week_seasonality ** = 'auto' [true / false / auto / arbitrary constant] Précisez la périodicité (semaine). Le degré de considération peut être ajusté en spécifiant un nombre arbitraire (10 est la valeur spécifiée si elle n'est pas spécifiée).

** ● daily_seasonality ** = 'auto' [true / false / auto / arbitrary constant] Précisez la périodicité (jour). Le degré de considération peut être ajusté en spécifiant un nombre arbitraire (10 est la valeur spécifiée si elle n'est pas spécifiée).

●holidays=None [DataFrame] Spécifiez le bloc de données de date de l'événement. Incorporer les jours fériés et les dates avec les événements dans l'analyse et les refléter dans les prévisions.

** ● changepoint_prior_scale ** = 0,05 [constante arbitraire] Spécifiez la dispersion de la distribution de Laplace. Plus cette valeur est élevée, plus il est facile de détecter le point de changement. Cependant, cela peut le rendre trop flexible. Identique à n_changepoints.

** ● changepoint_range ** = 0.8 [constante arbitraire] Spécifiez le rapport des données pour la détection des points de changement. La valeur spécifiée étant de 0,8, les points de changement sont extraits du début des données d'entraînement à 80%. Par exemple, s'il y a un grand mouvement dans la tendance à la fin des données, réglez-le sur "1.0". Le point de changement sera détecté en utilisant toute la gamme de données, y compris la fluctuation de la dernière étape.

Il semble y avoir diverses autres choses, mais je vais l'omettre parce que ce qui précède est la seule chose qui peut être considérée avec la quantité de connaissances jusqu'à présent.

Apprentissage

model.fit(Jinkoudata)

fit() ・ Apprenez en spécifiant les données d'entraînement avec ajustement.

Génération de trames de données

future = model.make_future_dataframe(periods=16,freq='M')

make_future_dataframe() -Créer une future ligne de série chronologique en l'ajoutant à la trame de données adaptée comme données d'apprentissage au modèle créé. ・ Ici, en plus de la base de données ajustée (Jinkoudata: 2013 / 04-2020 / 08), Nous avons créé des bases de données pour les 16 prochains mois (2020 / 09-2021 / 12). ・ En conséquence, [futures] seront des données avec une période de 2013/04 à 2021/12.

future

ds
0 2013-04-01
1 2013-05-01
2 2013-06-01
・ ・ ・ ・ ・ ・
103 2021-10-31
104 2021-11-30

Prévoir

predict = model.predict(future)

-Spécifiez la trame de données de série temporelle créée précédemment comme argument et prédire. -La série temporelle à prévoir va de 2013/04 à 2021/12, qui est la série chronologique stockée à l'avenir.

** Résultat de la prédiction [prédire] **

ds yhat yhat_lower yhat_upper
0 2013-04-01 205798.225901 205762.014035 205838.079234
1 2013-05-01 205717.024368 205679.523657 205759.642408
2 2013-06-01 205600.30351 205560.587079 205640.792342
3 2013-07-01 205530.899822 205488.087052 205570.056443
4 2013-08-01 205335.468464 205296.411528 205378.093757

Il y a d'autres informations qui sont prédites et stockées dans la trame de données, Comme il est difficile de saisir la valeur numérique, nous allons ici vérifier les éléments liés à la valeur prédite. ・ Yhat: valeur prédite ・ Yhat_lower: limite inférieure prévue ・ Yhat_upper: limite supérieure prévue «Valeur prévue», «Valeur limite inférieure prévue» et «Valeur limite supérieure prévue» sont stockées dans les colonnes ci-dessus. La "valeur prédite" est le résultat de prédiction le plus probable, et la "limite inférieure prédite" et la "limite supérieure prédite" sont les limites inférieure et supérieure en tant que plage de fluctuation de la valeur prédite.

une analyse

model.plot(predict)

-Dessiner la prédiction avec [plot]. -Les points noirs sont les données d'entraînement, les lignes bleues sont les valeurs prédites (yhat) et les bandes bleues sont la largeur de fluctuation prévue (yhat_lower: yhat_upper).

model.plot(predict).png ** [Ce que vous pouvez lire ici] ** ■ Du fait des prévisions, la tendance à la baisse en 2021 au même rythme qu'avant (environ 1000 personnes ou moins / an) ■ Briser le niveau des 193 000 d'ici la fin de 2021 ■ La précision de la prédiction est élevée car la valeur prédite et le résultat réel ne sont pas séparés (les données sont plutôt simples). ■ Il est possible de faire des prédictions avec une plage de fluctuation relativement petite des valeurs prévues jusqu'à environ six mois à l'avance. (Les données d'apprentissage ont augmenté rapidement de 2021/03 à 2020/08)

model.plot_components(predict)

-Le dessin pour chaque facteur tel que la fluctuation de tendance et la fluctuation saisonnière est fait avec [plot_components]. ・ Le terme [tendance] est la tendance (fluctuation de tendance à long terme). Je dessine quel genre de fluctuation il s'agit d'une transition annuelle. ・ Le terme [annuel] change selon les saisons. Il décrit les fluctuations au cours de l'année. ・ Les tendances ne montrent pas beaucoup d'augmentation ou de diminution sur une courte période de temps et observent une augmentation ou une diminution annuelle de l'échelle qui répète les fluctuations saisonnières.

model.plot_components(predict).png ** [Ce que vous pouvez lire ici] ** ■ Il est en train de diminuer pour prendre une belle forme de ligne depuis 8 ans. Après l'année d'apprentissage (2013), il n'y a aucun signe de rebond sur une base annuelle ■ En tant que fluctuation au cours de l'année, elle continue essentiellement de diminuer, mais elle commencera à augmenter légèrement en octobre et novembre. (Étant donné que les fluctuations saisonnières sont analysées et exprimées par des formes d'onde, lors de l'utilisation de données mensuelles comme celle-ci Notez qu'il est prévu que la forme d'onde devienne plus grande à mesure que l'intervalle de date des données est plus grand. (Bien qu'il n'y ait pratiquement pas d'augmentation des données réelles, le taux de diminution a considérablement diminué en octobre et en novembre par rapport aux autres. Puisqu'il a montré une légère augmentation ces dernières années, il semble qu'il y ait eu un endroit où il s'est tourné pour augmenter en tant que prédiction.) ■ Légèrement, la tendance à la baisse est progressive (Bien que la baisse soit forte en mars de chaque année, le taux de diminution lui-même est également en baisse. Par exemple, la baisse de mars elle-même est due à des événements d'emploi / d'avancement, On peut supposer que la réduction du taux de diminution est due à la baisse de la natalité, Pour obtenir les détails, les dynamiques sociales comme les entrées et les sorties, comme le nombre de naissances et de décès Des données ouvertes telles que la dynamique naturelle sont nécessaires)

Évaluation

Il est nécessaire d'évaluer la précision de prédiction du modèle créé. Cette fois, nous évaluerons en utilisant la vérification des intersections.

Vérification croisée

from fbprophet.diagnostics import cross_validation
df_cv = cross_validation(model, initial='1095 days', period='182 days', horizon = '365 days')

cross_validation() ・ Initial: quand commencer les prévisions ・ Période: période pour déplacer les données ・ Horizontal: période prévue Dans le cas de l'exemple de déclaration ci-dessus, à partir du 1095e jour (initial), 1 à 1094 jours de données pour la période de données d'entraînement (3 fois l'horizon sauf indication contraire), Prédire la période d'évaluation du 1095e jour à 365 jours (horizon). Après avoir analysé la prévision, décalez le point de départ de la période de prévision de 182 jours (période), Nous prévoyons 365 jours à partir du 1277e jour comme prochaine période d'évaluation. Ceci est répété jusqu'à la fin des données et le résultat de la prédiction est stocké. Ce résultat de prédiction sera utilisé comme résultat d'évaluation en le remplaçant par une échelle qui peut être facilement confirmée par la méthode décrite plus loin.

** Résultat de la vérification croisée [df_cv] **

ds yhat yhat_lower yhat_upper y cutoff
0 2016-09-01 199454.428910 199389.987532 199514.165966 199386 2016-08-05
1 2016-10-01 199437.182903 199145.883231 199744.554272 199236 2016-08-05
2 2016-11-01 199274.971653 198645.490967 199906.989114 199110 2016-08-05
3 2016-12-01 199073.586270 198066.379455 200065.689963 199006 2016-08-05
4 2017-01-01 198809.990576 197391.138491 200210.975003 198837 2016-08-05

Calcul de l'échelle d'évaluation

from fbprophet.diagnostics import performance_metrics
df_p = performance_metrics(df_cv)

performance_metrics() Pour le résultat de la vérification d'intersection [df_cv], calculez l'échelle d'évaluation et enregistrez le résultat.

** Résultat du calcul de l'échelle d'évaluation [df_p] **

horizon mse rmse mae mape mdape coverage
0 57 days 16078.849437 126.802403 109.436237 0.000554 0.000432 0.1250
1 58 days 20194.085707 142.105896 129.175240 0.000655 0.000627 0.1250
2 59 days 18026.561842 134.263032 113.963954 0.000578 0.000545 0.2500
3 60 days 20932.092431 144.679274 129.291089 0.000657 0.000687 0.2500
4 87 days 33783.385041 183.802571 161.495031 0.000819 0.000824 0.3750

L'échelle d'évaluation est un calcul des résultats pour chaque indice d'évaluation, et les types sont les suivants.

** ● MSE [erreur quadratique moyenne] ** La valeur moyenne du carré de la valeur absolue, qui est la différence entre la valeur réelle et la valeur prédite.

** ● RMSE [erreur quadratique moyenne] ** La racine carrée de la valeur moyenne du carré de la différence entre la valeur réelle et la valeur prédite.

** ● MAE [erreur absolue moyenne] ** La moyenne des valeurs absolues de la différence entre la valeur réelle et la valeur prédite.

** ● MAPE [erreur en pourcentage absolu moyen] ** Moyenne du rapport de la différence entre la valeur réelle et la valeur prédite à la valeur réelle.

MSE, RMSE et MAE sont calculés différemment, mais les écarts de prédiction sont exprimés en moyenne sur la base de mesures réelles (population cette fois). MAPE exprime l'écart de prédiction sur une base de pourcentage (%). Étant donné que les nombres traités cette fois-ci sont importants, je voudrais confirmer les résultats de l'évaluation avec MAPE (Average Absolute Percentage Error), qui est intuitivement facile à comprendre.

Visualisation de l'échelle d'évaluation par MAPE (erreur en pourcentage absolu moyen)

from fbprophet.plot import plot_cross_validation_metric
fig = plot_cross_validation_metric(df_cv, metric='mape')

plot_cross_validation_metric() Vous pouvez visualiser l'échelle d'évaluation calculée dans la section précédente. Avec l'horizon (période d'évaluation) spécifié dans la vérification d'intersection comme axe X, La valeur MAPE pour le nombre d'évaluations exécutées est dessinée sous forme de point, La moyenne est affichée sous forme de ligne bleue.

plot_cross_validation_metric.png ** [Ce que vous pouvez lire ici] ** ■ La précision de la prévision globale n'est pas faible ⇒ Même si vous regardez la valeur d'écart maximum, mape est d'environ 0,4%. (= Puisqu'il s'agit d'une municipalité avec une échelle de 200000 habitants, un écart pouvant atteindre 800 personnes est estimé) Si vous suivez la moyenne, l'erreur évolue entre 0,05 et 0,15%, soit environ 100 à 300 personnes. Puisqu'il s'agit d'une prédiction, il n'y a pas d'index pour être correct, Selon les données de mesure réelles, il y a de nombreuses périodes où il y a des mouvements de 100 personnes sur une base mensuelle. Même s'il s'agit d'une erreur, c'est une différence qui peut être remplie en une période d'agrégation. Vous pouvez juger que ce n'est pas une grosse erreur. ■ La précision diminue à mesure que la période s'écoule depuis le début de la prédiction ⇒ Naturellement, la précision a tendance à diminuer (la distribution des mape augmente) au fil des mois.

réglage

Espace pour améliorer la précision du modèle

Le modèle créé n'étant pas toujours le meilleur, il peut être possible d'améliorer la précision en faisant des prédictions à l'aide du modèle réglé. Ici, j'écrirai également le processus de jugement "Y a-t-il de la place pour le réglage?"

Perspective de réglage

Au moment de décider de régler ou non, il est nécessaire de tenir compte de la nature des données utilisées pour la formation. Cette fois, nous examinerons les perspectives suivantes.

** ● Saisonnalité légale / saisonnalité de conduite ** Les fluctuations des données réelles sont soit additives (la plage et l'ampleur des fluctuations sont constantes quelle que soit la taille de la variable objective) ou multiplicateur (plus la variable objective est grande, plus la plage des fluctuations est grande). Ou

** ● Nombre de points de changement extraits ** Le nombre de points de changement dans les données réelles est-il approprié?

** ● Plage d'extraction des points de changement ** La plage d'extraction du point de changement des données réelles est-elle appropriée?

Jugement du réglage de ce modèle

** ● Saisonnalité légale / saisonnalité de conduite ** La variable objective cette fois-ci est les données démographiques. La «mort» et la «naissance», considérées comme l'un des facteurs d'augmentation et de diminution de la population, seraient les personnes âgées et les jeunes. Parce que l'on pense que l'ampleur des fluctuations changera en fonction de la population. ** Nous jugeons que ces données ont un léger aspect multiplicateur **. (Bien que le nombre total diminue d'année en année à partir du graphique du résultat de la prédiction, il en est accompagné. Vous pouvez voir que la diminution annuelle est faible, quoique légèrement). (À part cela, «emménager» et «déménager» sont également affectés par la population, Dans ces cas, le nombre et l'échelle des entreprises / écoles bénéficiaires de l'entrée et de la sortie sont également fortement affectés. Il était difficile de conclure avec uniquement des données démographiques) La modélisation Prophet peut être effectuée avec le paramètre [seasonality_mode] ou "additive seasonality" Vous pouvez spécifier "saisonnalité légale", mais si omis, le modèle sera créé avec "saisonnalité additive" par défaut. Il est possible d'essayer de créer un modèle avec une «saisonnalité légale» comme réglage. ⇒ Cible de réglage </ font>

** ● Nombre de points de changement extraits ** Prophet extrait automatiquement les points de changement des données d'entraînement et les utilise pour la prédiction. Le nombre de points de changement à extraire est également de 25 par défaut. Le nombre de points de changement extraits peut être spécifié au moment de la création du modèle avec le paramètre [n_changepoints]. Si ce nombre est trop petit, "le changement se produira à ce moment" La précision de la prédiction est réduite en raison du manque de reconnaissance des points de changement dans la série chronologique. Même si ce nombre est trop grand, de légères fluctuations seront reconnues comme des points de changement, et On suppose que la flexibilité de la prédiction sera altérée et la précision diminuée. En d'autres termes, si vous spécifiez un nombre, vous voulez que le modèle s'entraîne Il est nécessaire de contrôler les points de changement importants, Les événements ont tendance à ne pas être clairs avec des données mensuelles comme celle-ci. ** Il est difficile de juger "combien sont appropriés" **, donc je pense qu'il y a peu de place pour le réglage. ⇒ Non soumis au réglage </ font>

** ● Plage d'extraction des points de changement ** Dans Prophet, comme plage d'extraction des points de changement Extrayez 80% du point de départ des données d'entraînement comme période cible. Par exemple, s'il y a une forte hausse de la tendance à la fin des données d'entraînement, Le modèle par défaut ne peut pas faire de prédictions qui tiennent compte de ce changement. Dans le paramètre [changepoint_range] lors de la création d'un modèle Ajustez la plage d'extraction en spécifiant «1.0». Dans ce cas, ces ** grandes fluctuations récentes Comme on ne le voit pas en particulier **, il ne semble pas y avoir de place pour un réglage du point de vue de la plage d'extraction des points de changement. ⇒ Non soumis au réglage </ font>

Tuning: Modélisation avec la saisonnalité de conduite

Comme jugé dans la section ci-dessus, nous allons créer un modèle avec "saisonnalité légale" comme réglage.

#Génération de modèle (saisonnalité légale)
#Ajout de paramètres de temps de génération[seasonality_mode = "multiplicative"]
model_multi = Prophet(weekly_seasonality=False,daily_seasonality=False,seasonality_mode = "multiplicative")
#Apprentissage
model_multi.fit(Jinkoudata)
#Prévoir
predict_multi = model_multi.predict(future)
#Dessin des résultats de prédiction
fig = model_multi.plot(predict_multi)

Le dessin du résultat de la prédiction du modèle de conduite est le suivant. model.plot(predict_multi).png model.plot_components(predict_multi).png La tendance ressemble au modèle juridique. Nous effectuerons également une validation croisée pour cela.

#Vérification croisée
df_cv_multi = cross_validation(model_multi, initial='1095 days', period='182 days', horizon = '365 days')
#Calcul de l'échelle d'évaluation
df_p_multi = performance_metrics(df_cv_multi)
#Visualisation de l'échelle d'évaluation par MAPE (erreur en pourcentage absolu moyen)
fig_multi = plot_cross_validation_metric(df_cv_multi, metric='mape')

L'échelle d'évaluation MAPE était la suivante. plot_cross_validation_metric(df_cv_multi.png Légèrement, vraiment très peu, mais moins diversifié que le modèle additif, C'est devenu un modèle avec peu d'écart par rapport à la prédiction.

Dessinez les données de mesure réelles et les deux types de résultats de prédiction dans le même tableau et comparez-les.

#Réglage de la taille de la table
plt.figure(figsize=(12,6))
#Réglage du cap de l'axe
plt.xlabel('Year month')
plt.ylabel('Jinkou')
#Spécifier la plage de dessin
plt.xlim(82, 105)
plt.ylim(190000, 196000)
#Changer l'affichage de la balance
plt.xticks([82,88,94,100,105], ["2020-01","2020-07","2021-01","2021-07","2021-12"])
#Dessin de chaque valeur numérique
plt.plot(Jinkoudata.y,label = 'Jinkoudata')
plt.plot(predict.yhat,label = 'Predict_add')
plt.plot(predict_multi.yhat,label = 'Predict_multi')
plt.legend()

Le résultat du dessin était comme ci-dessous. plt.legend_data_add_multi.png Données de mesure réelles utilisées par [Jinkoudata] pour l'apprentissage, [Predict_add] est le résultat de la prédiction dans le modèle de saisonnalité additive, [Predict_multi] est le résultat de la prédiction dans le modèle de saisonnalité de conduite. …… Il y a une question de savoir si c'est bien, mais les lignes de [Predict_add] et [Predict_multi] se chevauchent, et les résultats sont presque les mêmes. À l'origine, la nature multiplicatrice des données mesurées elle-même était faible, de sorte qu'elle peut ne pas apparaître comme une différence significative dans les résultats de prédiction.

Résumé

La modélisation et la prévision elles-mêmes ont été plus faciles que prévu. Cependant, l'utilisation nécessite encore une compréhension et une connaissance de la nature et de la corrélation des données. La période de prévision à laquelle on peut faire confiance en tant que modèle pour les prévisions futures n'était pas plus longue que ce à quoi je m'attendais, c'est donc une opération pour lire les tendances à partir des données pour chaque période unitaire et régler à chaque fois (bien qu'il semble que cela ne se limite pas à cet exemple). Je pensais que ce serait une condition préalable.

J'ai essayé de prédire l'avenir de la population en tant que pratique, mais comme la diminution était claire à partir des données originales, je pense que cela ne valait pas la peine pour l'instant. Le choix d'un thème est toujours important. Si vous souhaitez creuser plus profondément, vous pouvez utiliser des variables externes pour améliorer la précision, mais vous pouvez essayer l'analyse de corrélation séparément. La ville de Numazu est ma ville préférée, alors j'ai pensé qu'il serait bon de faire des prédictions après avoir étudié d'autres domaines.